From 0d2db04abada2f2e6de8dc164775b5bc71c125c3 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Sun, 12 Nov 2017 20:33:29 -0500 Subject: [PATCH 01/31] Rename IInterface to IServerInterface --- TGCommandLine/ConsoleCommand.cs | 4 ++-- TGCommandLine/InstanceRootCommand.cs | 2 +- TGCommandLine/Program.cs | 6 +++--- TGCommandLine/RootCommands.cs | 2 +- TGControlPanel/ControlPanel/ControlPanel.cs | 8 ++++---- TGControlPanel/InstanceSelector.cs | 8 ++++---- TGControlPanel/Login.cs | 2 +- TGControlPanel/ServerOpForm.cs | 6 +++--- TGControlPanel/TestMergeManager.cs | 8 ++++---- TGInstallerWrapper/Main.cs | 2 +- TGServerService/ServerInstance/Compiler.cs | 2 +- TGServerService/ServerInstance/DreamDaemon.cs | 2 +- TGServiceInterface/Interface.cs | 12 ++++++------ .../Commands/Repository/RepositoryCommandTest.cs | 10 +++++----- TGServiceTests/ControlPanel/TestInstanceSelector.cs | 2 +- 15 files changed, 38 insertions(+), 38 deletions(-) diff --git a/TGCommandLine/ConsoleCommand.cs b/TGCommandLine/ConsoleCommand.cs index 7f9489d1c1..5e5274775a 100644 --- a/TGCommandLine/ConsoleCommand.cs +++ b/TGCommandLine/ConsoleCommand.cs @@ -5,8 +5,8 @@ namespace TGCommandLine abstract class ConsoleCommand : Command { /// - /// The currently in use by the + /// The currently in use by the /// - public static IInterface Interface; + public static IServerInterface Interface; } } diff --git a/TGCommandLine/InstanceRootCommand.cs b/TGCommandLine/InstanceRootCommand.cs index 85fd78610b..f430785e26 100644 --- a/TGCommandLine/InstanceRootCommand.cs +++ b/TGCommandLine/InstanceRootCommand.cs @@ -5,7 +5,7 @@ namespace TGCommandLine { abstract class InstanceRootCommand : RootCommand { - public static IInterface currentInterface; + public static IServerInterface currentInterface; public override ExitCode DoRun(IList parameters) { if (currentInterface.InstanceName == null) diff --git a/TGCommandLine/Program.cs b/TGCommandLine/Program.cs index fb0e245d09..ef15f54ed5 100644 --- a/TGCommandLine/Program.cs +++ b/TGCommandLine/Program.cs @@ -10,7 +10,7 @@ namespace TGCommandLine class Program { static bool interactive = false, saidSrvVersion = false; - static IInterface currentInterface; + static IServerInterface currentInterface; static Command.ExitCode RunCommandLine(IList argsAsList) { //first lookup the connection string @@ -100,7 +100,7 @@ namespace TGCommandLine }; } - static void ReplaceInterface(IInterface I) + static void ReplaceInterface(IServerInterface I) { currentInterface = I; ConsoleCommand.Interface = I; @@ -157,7 +157,7 @@ namespace TGCommandLine /// /// The name of the to test /// If , does not output on success - /// if a was achieved with , otherwise + /// if a was achieved with , otherwise static bool CheckInstanceConnectivity(string instanceName, bool silentSuccess) { var res = currentInterface.ConnectToInstance(instanceName); diff --git a/TGCommandLine/RootCommands.cs b/TGCommandLine/RootCommands.cs index 6394224cd7..552e7b1bf7 100644 --- a/TGCommandLine/RootCommands.cs +++ b/TGCommandLine/RootCommands.cs @@ -7,7 +7,7 @@ namespace TGCommandLine { class CLICommand : RootCommand { - public CLICommand(IInterface I) + public CLICommand(IServerInterface I) { var tmp = new List { new UpdateCommand(), new TestmergeCommand(), new RepoCommand(), new BYONDCommand(), new DMCommand(), new DDCommand(), new ConfigCommand(), new IRCCommand(), new DiscordCommand(), new AutoUpdateCommand(), new SetAutoUpdateCommand() }; if (I.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator)) diff --git a/TGControlPanel/ControlPanel/ControlPanel.cs b/TGControlPanel/ControlPanel/ControlPanel.cs index 5e88c8f0c1..f662e50cae 100644 --- a/TGControlPanel/ControlPanel/ControlPanel.cs +++ b/TGControlPanel/ControlPanel/ControlPanel.cs @@ -18,15 +18,15 @@ namespace TGControlPanel public static IDictionary InstancesInUse { get; private set; } = new Dictionary(); /// - /// The instance for this + /// The instance for this /// - readonly IInterface Interface; + readonly IServerInterface Interface; /// /// Constructs a /// - /// The for the - public ControlPanel(IInterface I) + /// The for the + public ControlPanel(IServerInterface I) { InitializeComponent(); FormClosed += ControlPanel_FormClosed; diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 3be9cde5ad..21e8a32624 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -13,9 +13,9 @@ namespace TGControlPanel sealed partial class InstanceSelector : CountedForm { /// - /// The we build instance connections from + /// The we build instance connections from /// - readonly IInterface masterInterface; + readonly IServerInterface masterInterface; /// /// List of from /// @@ -28,8 +28,8 @@ namespace TGControlPanel /// /// Construct an /// - /// An connected a the - public InstanceSelector(IInterface I) + /// An connected a the + public InstanceSelector(IServerInterface I) { InitializeComponent(); InstanceListBox.MouseDoubleClick += InstanceListBox_MouseDoubleClick; diff --git a/TGControlPanel/Login.cs b/TGControlPanel/Login.cs index 364746a652..9a45e19e5a 100644 --- a/TGControlPanel/Login.cs +++ b/TGControlPanel/Login.cs @@ -58,7 +58,7 @@ namespace TGControlPanel VerifyAndConnect(new Interface()); } - void VerifyAndConnect(IInterface I) + void VerifyAndConnect(IServerInterface I) { try { diff --git a/TGControlPanel/ServerOpForm.cs b/TGControlPanel/ServerOpForm.cs index 06099fd819..2a886e742d 100644 --- a/TGControlPanel/ServerOpForm.cs +++ b/TGControlPanel/ServerOpForm.cs @@ -5,7 +5,7 @@ using System.Windows.Forms; namespace TGControlPanel { /// - /// Used to provide an ATP function for calls into an + /// Used to provide an ATP function for calls into an /// #if !DEBUG abstract class ServerOpForm : Form @@ -14,9 +14,9 @@ namespace TGControlPanel #endif { /// - /// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor + /// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor /// - /// The operation to wrap + /// The operation to wrap /// A wrapping protected Task WrapServerOp(Action action) { diff --git a/TGControlPanel/TestMergeManager.cs b/TGControlPanel/TestMergeManager.cs index d04e598c73..d766e3dfe0 100644 --- a/TGControlPanel/TestMergeManager.cs +++ b/TGControlPanel/TestMergeManager.cs @@ -17,9 +17,9 @@ namespace TGControlPanel const string MergedPullsError = "Error retrieving currently merged pull requests: {0}"; /// - /// The connected to an to handle the pull requests for + /// The connected to an to handle the pull requests for /// - readonly IInterface currentInterface; + readonly IServerInterface currentInterface; /// /// The to use to read PR lists @@ -38,9 +38,9 @@ namespace TGControlPanel /// /// Construct a /// - /// The to use for managing the + /// The to use for managing the /// The to use for getting pull request information - public TestMergeManager(IInterface interfaceToUse, GitHubClient clientToUse) + public TestMergeManager(IServerInterface interfaceToUse, GitHubClient clientToUse) { InitializeComponent(); DialogResult = DialogResult.Cancel; diff --git a/TGInstallerWrapper/Main.cs b/TGInstallerWrapper/Main.cs index c796238fd3..81eed484af 100644 --- a/TGInstallerWrapper/Main.cs +++ b/TGInstallerWrapper/Main.cs @@ -20,7 +20,7 @@ namespace TGInstallerWrapper bool cancelled = false; bool pathIsDefault = true; - IInterface Interface; + IServerInterface Interface; /// /// Construct an installer form diff --git a/TGServerService/ServerInstance/Compiler.cs b/TGServerService/ServerInstance/Compiler.cs index cff03130b5..6ccda81072 100644 --- a/TGServerService/ServerInstance/Compiler.cs +++ b/TGServerService/ServerInstance/Compiler.cs @@ -119,7 +119,7 @@ namespace TGServerService //what is says on the tin CompilerStatus IsInitialized() { - if (File.Exists(RelativePath(Path.Combine(GameDirLive, BridgeDLLName))) || File.Exists(RelativePath(Path.Combine(GameDirLive, Assembly.GetAssembly(typeof(IInterface)).GetName().Name + ".dll")))) //its a good tell, jim + if (File.Exists(RelativePath(Path.Combine(GameDirLive, BridgeDLLName))) || File.Exists(RelativePath(Path.Combine(GameDirLive, Assembly.GetAssembly(typeof(IServerInterface)).GetName().Name + ".dll")))) //its a good tell, jim return CompilerStatus.Initialized; return CompilerStatus.Uninitialized; } diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGServerService/ServerInstance/DreamDaemon.cs index 113797efe9..0321025126 100644 --- a/TGServerService/ServerInstance/DreamDaemon.cs +++ b/TGServerService/ServerInstance/DreamDaemon.cs @@ -530,7 +530,7 @@ namespace TGServerService return; //Copy the interface dll to the static dir - var InterfacePath = Assembly.GetAssembly(typeof(IInterface)).Location; + var InterfacePath = Assembly.GetAssembly(typeof(IServerInterface)).Location; //bridge is installed next to the interface var BridgePath = Path.Combine(Path.GetDirectoryName(InterfacePath), BridgeDLLName); #if DEBUG diff --git a/TGServiceInterface/Interface.cs b/TGServiceInterface/Interface.cs index 15823014d8..15795c4746 100644 --- a/TGServiceInterface/Interface.cs +++ b/TGServiceInterface/Interface.cs @@ -14,7 +14,7 @@ namespace TGServiceInterface /// /// Main for communicating the /// - public interface IInterface : IDisposable + public interface IServerInterface : IDisposable { /// /// The name of the current instance in use. Defaults to @@ -32,7 +32,7 @@ namespace TGServiceInterface ushort HTTPSPort { get; } /// - /// Checks if the is setup for a remote connection + /// Checks if the is setup for a remote connection /// bool IsRemoteConnection { get; } @@ -45,14 +45,14 @@ namespace TGServiceInterface ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false); /// - /// Returns if the interface being used to connect to a service does not have the same release version as the service + /// Returns if the interface being used to connect to a service does not have the same release version as the service /// /// An error message to display to the user should this function return - /// if the interface being used to connect to a service does not have the same release version as the service + /// if the interface being used to connect to a service does not have the same release version as the service bool VersionMismatch(out string errorMessage); /// - /// Returns the requested component for the instance . This does not guarantee a successful connection. + /// Returns the requested component for the instance . This does not guarantee a successful connection. /// /// The component to retrieve /// The correct component @@ -79,7 +79,7 @@ namespace TGServiceInterface } /// - sealed public class Interface : IInterface + sealed public class Interface : IServerInterface { /// /// List of s that can be used with diff --git a/TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs b/TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs index 48e3355c1a..0c80b404da 100644 --- a/TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs +++ b/TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs @@ -8,13 +8,13 @@ namespace TGCommandLine.Commands.Repository.Tests public abstract class RepositoryCommandTest : OutputProcOverriderTest { /// - /// Creates a mock that returns a specific when that component is requested + /// Creates a mock that returns a specific when that component is requested /// - /// The the resulting should return - /// A mock - protected IInterface MockInterfaceToRepo(ITGRepository repo) + /// The the resulting should return + /// A mock + protected IServerInterface MockInterfaceToRepo(ITGRepository repo) { - var mock = new Mock(); + var mock = new Mock(); mock.Setup(foo => foo.GetComponent()).Returns(repo); return mock.Object; } diff --git a/TGServiceTests/ControlPanel/TestInstanceSelector.cs b/TGServiceTests/ControlPanel/TestInstanceSelector.cs index 626fbe3195..e5f9da9cd3 100644 --- a/TGServiceTests/ControlPanel/TestInstanceSelector.cs +++ b/TGServiceTests/ControlPanel/TestInstanceSelector.cs @@ -20,7 +20,7 @@ namespace TGControlPanel.Tests { var mockLanding = new Mock(); mockLanding.Setup(x => x.ListInstances()).Returns(new List()); - var mockInter = new Mock(); + var mockInter = new Mock(); mockInter.Setup(x => x.GetComponent()).Returns(mockLanding.Object); new InstanceSelector(mockInter.Object).Dispose(); From cc364a75d6800bbed09c60db9f95805c7a280c8b Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Sun, 12 Nov 2017 20:42:04 -0500 Subject: [PATCH 02/31] Renames Interface to ServerInterface --- TGCommandLine/Program.cs | 17 +- TGControlPanel/InstanceSelector.cs | 2 +- TGControlPanel/Login.cs | 4 +- TGControlPanel/Program.cs | 2 +- TGDreamDaemonBridge/DreamDaemonBridge.cs | 2 +- TGInstallerWrapper/Main.cs | 2 +- TGServerService/Service.cs | 12 +- .../{Interface.cs => ServerInterface.cs} | 1000 ++++++++--------- TGServiceInterface/TGServiceInterface.csproj | 160 +-- .../TestHelpers.cs | 0 .../TestInterface.cs | 12 +- TGServiceTests/TGServiceTests.csproj | 230 ++-- 12 files changed, 721 insertions(+), 722 deletions(-) rename TGServiceInterface/{Interface.cs => ServerInterface.cs} (92%) rename TGServiceTests/{Interface => ServiceInterface}/TestHelpers.cs (100%) rename TGServiceTests/{Interface => ServiceInterface}/TestInterface.cs (89%) diff --git a/TGCommandLine/Program.cs b/TGCommandLine/Program.cs index ef15f54ed5..c1e7c18465 100644 --- a/TGCommandLine/Program.cs +++ b/TGCommandLine/Program.cs @@ -6,7 +6,6 @@ using TGServiceInterface.Components; namespace TGCommandLine { - class Program { static bool interactive = false, saidSrvVersion = false; @@ -53,7 +52,7 @@ namespace TGCommandLine } argsAsList.RemoveAt(I); argsAsList.RemoveAt(I); - ReplaceInterface(new Interface(address, port, username, password)); + ReplaceInterface(new ServerInterface(address, port, username, password)); break; } } @@ -176,7 +175,7 @@ namespace TGCommandLine static int Main(string[] args) { - ReplaceInterface(new Interface()); + ReplaceInterface(new ServerInterface()); Command.OutputProcVar.Value = Console.WriteLine; if (args.Length != 0) { @@ -194,13 +193,13 @@ namespace TGCommandLine { argsAsList.RemoveAt(I); --I; - Interface.SetBadCertificateHandler(_ => false); + ServerInterface.SetBadCertificateHandler(_ => false); } } return (int)RunCommandLine(argsAsList); } //interactive mode - Interface.SetBadCertificateHandler(BadCertificateInteractive); + ServerInterface.SetBadCertificateHandler(BadCertificateInteractive); Console.WriteLine("Type 'instance' to connect to a server instance"); Console.WriteLine("Type 'remote' to connect to a remote service"); while (true) @@ -231,17 +230,17 @@ namespace TGCommandLine var username = Console.ReadLine(); Console.Write("Enter password: "); var password = ReadLineSecure(); - ReplaceInterface(new Interface(address, port, username, password)); + ReplaceInterface(new ServerInterface(address, port, username, password)); var res = currentInterface.ConnectionStatus(out string error); if (!res.HasFlag(ConnectivityLevel.Connected)) { Console.WriteLine("Unable to connect: " + error); - ReplaceInterface(new Interface()); + ReplaceInterface(new ServerInterface()); } else if (!res.HasFlag(ConnectivityLevel.Authenticated)) { Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode..."); - ReplaceInterface(new Interface()); + ReplaceInterface(new ServerInterface()); } else { @@ -256,7 +255,7 @@ namespace TGCommandLine break; case "disconnect": SentVMMWarning = false; - ReplaceInterface(new Interface()); + ReplaceInterface(new ServerInterface()); Console.WriteLine("Switch to local mode"); break; case "quit": diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 21e8a32624..ba46fc11f6 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -100,7 +100,7 @@ namespace TGControlPanel activeCP.BringToFront(); return; } - var InstanceAccessor = new Interface(masterInterface as Interface); + var InstanceAccessor = new ServerInterface(masterInterface as ServerInterface); try { ConnectivityLevel res = ConnectivityLevel.None; diff --git a/TGControlPanel/Login.cs b/TGControlPanel/Login.cs index 9a45e19e5a..882592d1cc 100644 --- a/TGControlPanel/Login.cs +++ b/TGControlPanel/Login.cs @@ -31,7 +31,7 @@ namespace TGControlPanel { IPTextBox.Text = IPTextBox.Text.Trim(); UsernameTextBox.Text = UsernameTextBox.Text.Trim(); - using (var I = new Interface(IPTextBox.Text, (ushort)PortSelector.Value, UsernameTextBox.Text, PasswordTextBox.Text)) + using (var I = new ServerInterface(IPTextBox.Text, (ushort)PortSelector.Value, UsernameTextBox.Text, PasswordTextBox.Text)) { var Config = Properties.Settings.Default; Config.RemoteIP = IPTextBox.Text; @@ -55,7 +55,7 @@ namespace TGControlPanel private void LocalLoginButton_Click(object sender, EventArgs e) { Properties.Settings.Default.RemoteDefault = false; - VerifyAndConnect(new Interface()); + VerifyAndConnect(new ServerInterface()); } void VerifyAndConnect(IServerInterface I) diff --git a/TGControlPanel/Program.cs b/TGControlPanel/Program.cs index b484dbc88f..4865d338df 100644 --- a/TGControlPanel/Program.cs +++ b/TGControlPanel/Program.cs @@ -20,7 +20,7 @@ namespace TGControlPanel } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Interface.SetBadCertificateHandler(BadCertificateHandler); + ServerInterface.SetBadCertificateHandler(BadCertificateHandler); var login = new Login(); login.Show(); Application.Run(); diff --git a/TGDreamDaemonBridge/DreamDaemonBridge.cs b/TGDreamDaemonBridge/DreamDaemonBridge.cs index 003e9b6b9b..07835d4232 100644 --- a/TGDreamDaemonBridge/DreamDaemonBridge.cs +++ b/TGDreamDaemonBridge/DreamDaemonBridge.cs @@ -27,7 +27,7 @@ namespace TGDreamDaemonBridge parsedArgs.AddRange(args); var instance = parsedArgs[0]; parsedArgs.RemoveAt(0); - using (var I = new Interface()) + using (var I = new ServerInterface()) if(I.ConnectToInstance(instance, true).HasFlag(ConnectivityLevel.Connected)) I.GetComponent().InteropMessage(String.Join(" ", parsedArgs)); } diff --git a/TGInstallerWrapper/Main.cs b/TGInstallerWrapper/Main.cs index 81eed484af..df1b275a83 100644 --- a/TGInstallerWrapper/Main.cs +++ b/TGInstallerWrapper/Main.cs @@ -69,7 +69,7 @@ namespace TGInstallerWrapper } void CheckForExistingVersion() { - Interface = new Interface(); + Interface = new ServerInterface(); var verifiedConnection = Interface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator); try { diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index 0486e7c5de..75f0f23cac 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -234,8 +234,8 @@ namespace TGServerService /// void SetupService() { - serviceHost = CreateHost(this, Interface.MasterInterfaceName); - foreach (var I in Interface.ValidServiceInterfaces) + serviceHost = CreateHost(this, ServerInterface.MasterInterfaceName); + foreach (var I in ServerInterface.ValidServiceInterfaces) AddEndpoint(serviceHost, I); serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us } @@ -348,10 +348,10 @@ namespace TGServerService return null; } - var host = CreateHost(instance, String.Format("{0}/{1}", Interface.InstanceInterfaceName, instanceName)); + var host = CreateHost(instance, String.Format("{0}/{1}", ServerInterface.InstanceInterfaceName, instanceName)); hosts.Add(instanceName, host); - foreach (var J in Interface.ValidInstanceInterfaces) + foreach (var J in ServerInterface.ValidInstanceInterfaces) AddEndpoint(host, J); host.Authorization.ServiceAuthorizationManager = instance; @@ -366,11 +366,11 @@ namespace TGServerService void AddEndpoint(ServiceHost host, Type typetype) { var bindingName = typetype.Name; - host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = Interface.TransferLimitLocal }, bindingName); + host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = ServerInterface.TransferLimitLocal }, bindingName); var httpsBinding = new WSHttpBinding() { SendTimeout = new TimeSpan(0, 0, 40), - MaxReceivedMessageSize = Interface.TransferLimitRemote + MaxReceivedMessageSize = ServerInterface.TransferLimitRemote }; var requireAuth = typetype.Name != typeof(ITGConnectivity).Name; httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; diff --git a/TGServiceInterface/Interface.cs b/TGServiceInterface/ServerInterface.cs similarity index 92% rename from TGServiceInterface/Interface.cs rename to TGServiceInterface/ServerInterface.cs index 15795c4746..62608e7cf9 100644 --- a/TGServiceInterface/Interface.cs +++ b/TGServiceInterface/ServerInterface.cs @@ -1,500 +1,500 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Net; -using System.Net.Security; -using System.Reflection; -using System.Security.Principal; -using System.ServiceModel; -using TGServiceInterface.Components; - -namespace TGServiceInterface -{ - /// - /// Main for communicating the - /// - public interface IServerInterface : IDisposable - { - /// - /// The name of the current instance in use. Defaults to - /// - string InstanceName { get; } - - /// - /// If this is set, we will try and connect to an HTTPS server running at this address - /// - string HTTPSURL { get; } - - /// - /// The port used to connect to the - /// - ushort HTTPSPort { get; } - - /// - /// Checks if the is setup for a remote connection - /// - bool IsRemoteConnection { get; } - - /// - /// Targets as the instance to use with . Closes all connections to any previous instance - /// - /// The name of the instance to connect to - /// If set to , skips the connectivity and authentication checks, sets , and returns - /// The apporopriate - ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false); - - /// - /// Returns if the interface being used to connect to a service does not have the same release version as the service - /// - /// An error message to display to the user should this function return - /// if the interface being used to connect to a service does not have the same release version as the service - bool VersionMismatch(out string errorMessage); - - /// - /// Returns the requested component for the instance . This does not guarantee a successful connection. - /// - /// The component to retrieve - /// The correct component - T GetComponent(); - - /// - /// Returns a root service component - /// - /// The component for the service - 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 - /// - /// on successful connection, error message on failure - ConnectivityLevel ConnectionStatus(); - - /// - /// 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 - /// - /// String of the error that prevented an elevated connectivity level - /// The apporopriate - ConnectivityLevel ConnectionStatus(out string error); - } - - /// - sealed public class Interface : IServerInterface - { - /// - /// List of s that can be used with - /// - 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 - /// - public const long TransferLimitLocal = Int32.MaxValue; //2GB can't go higher - - /// - /// The maximum message size to and from a remote server - /// - public const long TransferLimitRemote = 10485760; //10 MB - - /// - /// Base name of communication URLs - /// - public const string MasterInterfaceName = "TGStationServerService"; - /// - /// Base name of instance URLs - /// - public const string InstanceInterfaceName = MasterInterfaceName + "/Instance"; - - /// - public string InstanceName { get; private set; } - - /// - /// If this is set, we will try and connect to an HTTPS server running at this address - /// - readonly string _HTTPSURL; - - /// - public string HTTPSURL { get { return _HTTPSURL; } } - - /// - /// The port used to connect to the - /// - readonly ushort _HTTPSPort; - - /// - public ushort HTTPSPort { get { return _HTTPSPort; } } - - /// - /// Username for remote operations - /// - readonly string HTTPSUsername; - - /// - /// Password for remote operations - /// - readonly string HTTPSPassword; - - /// - /// Associated list of open s keyed by type name. A in this list may close or fault at any time. Must be locked before being accessed - /// - IDictionary ChannelFactoryCache = new Dictionary(); - - /// - /// Returns a of s that can be used with the service - /// - /// A of s that can be used with the service - static IList CollectComponents() - { - 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 == ConnectivityComponent.Namespace - && t.GetCustomAttribute(typeof(ServiceContractAttribute)) != null - && (t == ConnectivityComponent || !ValidServiceInterfaces.Contains(t)) - select t; - return query.ToList(); - } - - /// - /// Sets the function called when a remote login fails due to the server having an invalid SSL cert - /// - /// The to be called when a remote login is attempted while the server posesses a bad certificate. Passed a of error information about the and should return if it the connection should be made anyway - public static void SetBadCertificateHandler(Func handler) - { - ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) => - { - string ErrorMessage; - switch (error) - { - case SslPolicyErrors.None: - return true; - case SslPolicyErrors.RemoteCertificateChainErrors: - ErrorMessage = "There are certificate chain errors."; - break; - case SslPolicyErrors.RemoteCertificateNameMismatch: - ErrorMessage = "The certificate name does not match."; - break; - case SslPolicyErrors.RemoteCertificateNotAvailable: - ErrorMessage = "The certificate doesn't exist in the trust store."; - break; - default: - ErrorMessage = "An unknown error occurred."; - break; - } - ErrorMessage = String.Format("The server's certificate failed to verify! Error: {0} Cert: {1}", ErrorMessage, cert.ToString()); - return handler(ErrorMessage); - }; - } - - /// - /// Construct an for a local connection - /// - public Interface() { } - - /// - /// Construct an for a remote connection - /// - /// The address of the remote server - /// The port the remote server runs on - /// Windows account username for the remote server - /// Windows account password for the remote server - public Interface(string address, ushort port, string username, string password) - { - _HTTPSURL = address; - _HTTPSPort = port; - HTTPSUsername = username; - HTTPSPassword = password; - } - - /// - /// Constructs an that connects to the same as some - /// - /// Another to copy settings from - public Interface(Interface other) : this(other.HTTPSURL, other.HTTPSPort, other.HTTPSUsername, other.HTTPSPassword) { } - - /// - public ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false) - { - if (instanceName == null) - instanceName = InstanceName; - if (!skipChecks && !ConnectionStatus().HasFlag(ConnectivityLevel.Connected)) - return ConnectivityLevel.None; - var prevInstance = InstanceName; - if (prevInstance != instanceName) - CloseAllChannels(false); - InstanceName = instanceName; - if (skipChecks) - return ConnectivityLevel.Connected; - try - { - GetComponent().VerifyConnection(); - } - catch - { - InstanceName = prevInstance; - return ConnectivityLevel.None; - } - try - { - GetComponent().ServerDirectory(); - } - catch - { - return ConnectivityLevel.Connected; - } - try - { - GetComponent().GetCurrentAuthorizedGroup(); - return ConnectivityLevel.Administrator; - } - catch - { - return ConnectivityLevel.Authenticated; - } - } - - /// - public bool IsRemoteConnection { get { return HTTPSURL != null; } } - - /// - /// Closes all s stored in and clears it - /// - /// If set to , doesn't clear the channels that are used by - void CloseAllChannels(bool includingRoot) - { - string[] RootThings = { typeof(ITGSService).Name, 'S' + typeof(ITGConnectivity).Name }; - lock (ChannelFactoryCache) - { - var toRemove = new List(); - foreach (var I in ChannelFactoryCache) - { - if (RootThings.Contains(I.Key)) - continue; - var cf = I.Value; - try - { - cf.Closed += ChannelFactory_Closed; - cf.Close(); - } - catch - { - cf.Abort(); - } - toRemove.Add(I.Key); - } - foreach (var I in toRemove) - ChannelFactoryCache.Remove(I); - } - } - - /// - public bool VersionMismatch(out string errorMessage) - { - 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 - { - errorMessage = String.Format("Version mismatch between interface version ({0}) and service version ({1}). Some functionality may crash this program.", ours, theirs); - return true; - } - errorMessage = null; - return false; - } - - /// - /// Disposes a closed - /// - /// The channel factory that was closed - /// The event arguments - static void ChannelFactory_Closed(object sender, EventArgs e) - { - (sender as IDisposable).Dispose(); - } - - /// - public T GetComponent() - { - var ToT = typeof(T); - if (!ValidInstanceInterfaces.Contains(ToT)) - throw new Exception("Invalid type!"); - return GetComponentImpl(true); - } - - /// - /// 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 - /// - /// The component to retrieve - /// If should be used to connect - /// The correct component - T GetComponentImpl(bool useInstanceName) - { - if (useInstanceName & InstanceName == null) - throw new Exception("Instance not selected!"); - var actualToT = typeof(T); - var tot = actualToT.Name; - if (actualToT == typeof(ITGConnectivity) && !useInstanceName) - tot = 'S' + tot; - ChannelFactory cf; - - lock (ChannelFactoryCache) - { - if (ChannelFactoryCache.ContainsKey(tot)) - try - { - cf = ((ChannelFactory)ChannelFactoryCache[tot]); - if (cf.State != CommunicationState.Opened) - throw new Exception(); - return cf.CreateChannel(); - } - catch - { - ChannelFactoryCache[tot].Abort(); - ChannelFactoryCache.Remove(tot); - } - cf = CreateChannel(useInstanceName ? InstanceName : null); - ChannelFactoryCache[tot] = cf; - } - return cf.CreateChannel(); - } - - /// - public T GetServiceComponent() - { - var ToT = typeof(T); - if (!ValidServiceInterfaces.Contains(ToT)) - throw new Exception("Invalid type!"); - return GetComponentImpl(false); - } - - /// - /// Directly creates a for without caching. This should be eventually closed by the caller - /// - /// The component of the channel to be created - /// The correct - /// Thrown if isn't a valid component - ChannelFactory CreateChannel(string instanceName) - { - var accessPath = instanceName == null ? MasterInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName); - - var InterfaceName = typeof(T).Name; - if (!IsRemoteConnection) - { - var res2 = new ChannelFactory( - new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = TransferLimitLocal }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", accessPath, InterfaceName))); //10 megs - res2.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; - return res2; - } - - //okay we're going over - var binding = new WSHttpBinding() - { - SendTimeout = new TimeSpan(0, 0, 40), - MaxReceivedMessageSize = TransferLimitRemote - }; - var requireAuth = InterfaceName != typeof(ITGConnectivity).Name; - binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; - binding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check - binding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None; - var address = new EndpointAddress(String.Format("https://{0}:{1}/{2}/{3}", HTTPSURL, HTTPSPort, accessPath, InterfaceName)); - var res = new ChannelFactory(binding, address); - if (requireAuth) - { - res.Credentials.UserName.UserName = HTTPSUsername; - res.Credentials.UserName.Password = HTTPSPassword; - res.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; - } - return res; - } - - /// - public ConnectivityLevel ConnectionStatus() - { - return ConnectionStatus(out string unused); - } - - /// - public ConnectivityLevel ConnectionStatus(out string error) - { - try - { - GetComponentImpl(false).VerifyConnection(); - } - catch (CommunicationException e) - { - error = e.ToString(); - return ConnectivityLevel.None; - } - try - { - GetServiceComponent().Version(); - } - catch(Exception e) - { - error = e.ToString(); - return ConnectivityLevel.Connected; - } - try - { - GetServiceComponent().Version(); - error = null; - return ConnectivityLevel.Administrator; - } - catch(Exception e) - { - error = e.ToString(); - return ConnectivityLevel.Authenticated; - } - } - - #region IDisposable Support - /// - /// To detect redundant calls - /// - private bool disposedValue = false; - - /// - /// Implements the pattern. Calls - /// - /// if was called manually, if it was from the finalizer - void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - CloseAllChannels(true); - } - - // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. - // TODO: set large fields to null. - - disposedValue = true; - } - } - - // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. - // ~Interface() { - // // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - // Dispose(false); - // } - - /// - /// Implements the pattern - /// - public void Dispose() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(true); - // TODO: uncomment the following line if the finalizer is overridden above. - // GC.SuppressFinalize(this); - } - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Principal; +using System.ServiceModel; +using TGServiceInterface.Components; + +namespace TGServiceInterface +{ + /// + /// Main for communicating the + /// + public interface IServerInterface : IDisposable + { + /// + /// The name of the current instance in use. Defaults to + /// + string InstanceName { get; } + + /// + /// If this is set, we will try and connect to an HTTPS server running at this address + /// + string HTTPSURL { get; } + + /// + /// The port used to connect to the + /// + ushort HTTPSPort { get; } + + /// + /// Checks if the is setup for a remote connection + /// + bool IsRemoteConnection { get; } + + /// + /// Targets as the instance to use with . Closes all connections to any previous instance + /// + /// The name of the instance to connect to + /// If set to , skips the connectivity and authentication checks, sets , and returns + /// The apporopriate + ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false); + + /// + /// Returns if the interface being used to connect to a service does not have the same release version as the service + /// + /// An error message to display to the user should this function return + /// if the interface being used to connect to a service does not have the same release version as the service + bool VersionMismatch(out string errorMessage); + + /// + /// Returns the requested component for the instance . This does not guarantee a successful connection. + /// + /// The component to retrieve + /// The correct component + T GetComponent(); + + /// + /// Returns a root service component + /// + /// The component for the service + 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 + /// + /// on successful connection, error message on failure + ConnectivityLevel ConnectionStatus(); + + /// + /// 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 + /// + /// String of the error that prevented an elevated connectivity level + /// The apporopriate + ConnectivityLevel ConnectionStatus(out string error); + } + + /// + sealed public class ServerInterface : IServerInterface + { + /// + /// List of s that can be used with + /// + 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 + /// + public const long TransferLimitLocal = Int32.MaxValue; //2GB can't go higher + + /// + /// The maximum message size to and from a remote server + /// + public const long TransferLimitRemote = 10485760; //10 MB + + /// + /// Base name of communication URLs + /// + public const string MasterInterfaceName = "TGStationServerService"; + /// + /// Base name of instance URLs + /// + public const string InstanceInterfaceName = MasterInterfaceName + "/Instance"; + + /// + public string InstanceName { get; private set; } + + /// + /// If this is set, we will try and connect to an HTTPS server running at this address + /// + readonly string _HTTPSURL; + + /// + public string HTTPSURL { get { return _HTTPSURL; } } + + /// + /// The port used to connect to the + /// + readonly ushort _HTTPSPort; + + /// + public ushort HTTPSPort { get { return _HTTPSPort; } } + + /// + /// Username for remote operations + /// + readonly string HTTPSUsername; + + /// + /// Password for remote operations + /// + readonly string HTTPSPassword; + + /// + /// Associated list of open s keyed by type name. A in this list may close or fault at any time. Must be locked before being accessed + /// + IDictionary ChannelFactoryCache = new Dictionary(); + + /// + /// Returns a of s that can be used with the service + /// + /// A of s that can be used with the service + static IList CollectComponents() + { + 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 == ConnectivityComponent.Namespace + && t.GetCustomAttribute(typeof(ServiceContractAttribute)) != null + && (t == ConnectivityComponent || !ValidServiceInterfaces.Contains(t)) + select t; + return query.ToList(); + } + + /// + /// Sets the function called when a remote login fails due to the server having an invalid SSL cert + /// + /// The to be called when a remote login is attempted while the server posesses a bad certificate. Passed a of error information about the and should return if it the connection should be made anyway + public static void SetBadCertificateHandler(Func handler) + { + ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) => + { + string ErrorMessage; + switch (error) + { + case SslPolicyErrors.None: + return true; + case SslPolicyErrors.RemoteCertificateChainErrors: + ErrorMessage = "There are certificate chain errors."; + break; + case SslPolicyErrors.RemoteCertificateNameMismatch: + ErrorMessage = "The certificate name does not match."; + break; + case SslPolicyErrors.RemoteCertificateNotAvailable: + ErrorMessage = "The certificate doesn't exist in the trust store."; + break; + default: + ErrorMessage = "An unknown error occurred."; + break; + } + ErrorMessage = String.Format("The server's certificate failed to verify! Error: {0} Cert: {1}", ErrorMessage, cert.ToString()); + return handler(ErrorMessage); + }; + } + + /// + /// Construct an for a local connection + /// + public ServerInterface() { } + + /// + /// Construct an for a remote connection + /// + /// The address of the remote server + /// The port the remote server runs on + /// Windows account username for the remote server + /// Windows account password for the remote server + public ServerInterface(string address, ushort port, string username, string password) + { + _HTTPSURL = address; + _HTTPSPort = port; + HTTPSUsername = username; + HTTPSPassword = password; + } + + /// + /// Constructs an that connects to the same as some + /// + /// Another to copy settings from + public ServerInterface(ServerInterface other) : this(other.HTTPSURL, other.HTTPSPort, other.HTTPSUsername, other.HTTPSPassword) { } + + /// + public ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false) + { + if (instanceName == null) + instanceName = InstanceName; + if (!skipChecks && !ConnectionStatus().HasFlag(ConnectivityLevel.Connected)) + return ConnectivityLevel.None; + var prevInstance = InstanceName; + if (prevInstance != instanceName) + CloseAllChannels(false); + InstanceName = instanceName; + if (skipChecks) + return ConnectivityLevel.Connected; + try + { + GetComponent().VerifyConnection(); + } + catch + { + InstanceName = prevInstance; + return ConnectivityLevel.None; + } + try + { + GetComponent().ServerDirectory(); + } + catch + { + return ConnectivityLevel.Connected; + } + try + { + GetComponent().GetCurrentAuthorizedGroup(); + return ConnectivityLevel.Administrator; + } + catch + { + return ConnectivityLevel.Authenticated; + } + } + + /// + public bool IsRemoteConnection { get { return HTTPSURL != null; } } + + /// + /// Closes all s stored in and clears it + /// + /// If set to , doesn't clear the channels that are used by + void CloseAllChannels(bool includingRoot) + { + string[] RootThings = { typeof(ITGSService).Name, 'S' + typeof(ITGConnectivity).Name }; + lock (ChannelFactoryCache) + { + var toRemove = new List(); + foreach (var I in ChannelFactoryCache) + { + if (RootThings.Contains(I.Key)) + continue; + var cf = I.Value; + try + { + cf.Closed += ChannelFactory_Closed; + cf.Close(); + } + catch + { + cf.Abort(); + } + toRemove.Add(I.Key); + } + foreach (var I in toRemove) + ChannelFactoryCache.Remove(I); + } + } + + /// + public bool VersionMismatch(out string errorMessage) + { + 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 + { + errorMessage = String.Format("Version mismatch between interface version ({0}) and service version ({1}). Some functionality may crash this program.", ours, theirs); + return true; + } + errorMessage = null; + return false; + } + + /// + /// Disposes a closed + /// + /// The channel factory that was closed + /// The event arguments + static void ChannelFactory_Closed(object sender, EventArgs e) + { + (sender as IDisposable).Dispose(); + } + + /// + public T GetComponent() + { + var ToT = typeof(T); + if (!ValidInstanceInterfaces.Contains(ToT)) + throw new Exception("Invalid type!"); + return GetComponentImpl(true); + } + + /// + /// 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 + /// + /// The component to retrieve + /// If should be used to connect + /// The correct component + T GetComponentImpl(bool useInstanceName) + { + if (useInstanceName & InstanceName == null) + throw new Exception("Instance not selected!"); + var actualToT = typeof(T); + var tot = actualToT.Name; + if (actualToT == typeof(ITGConnectivity) && !useInstanceName) + tot = 'S' + tot; + ChannelFactory cf; + + lock (ChannelFactoryCache) + { + if (ChannelFactoryCache.ContainsKey(tot)) + try + { + cf = ((ChannelFactory)ChannelFactoryCache[tot]); + if (cf.State != CommunicationState.Opened) + throw new Exception(); + return cf.CreateChannel(); + } + catch + { + ChannelFactoryCache[tot].Abort(); + ChannelFactoryCache.Remove(tot); + } + cf = CreateChannel(useInstanceName ? InstanceName : null); + ChannelFactoryCache[tot] = cf; + } + return cf.CreateChannel(); + } + + /// + public T GetServiceComponent() + { + var ToT = typeof(T); + if (!ValidServiceInterfaces.Contains(ToT)) + throw new Exception("Invalid type!"); + return GetComponentImpl(false); + } + + /// + /// Directly creates a for without caching. This should be eventually closed by the caller + /// + /// The component of the channel to be created + /// The correct + /// Thrown if isn't a valid component + ChannelFactory CreateChannel(string instanceName) + { + var accessPath = instanceName == null ? MasterInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName); + + var InterfaceName = typeof(T).Name; + if (!IsRemoteConnection) + { + var res2 = new ChannelFactory( + new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = TransferLimitLocal }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", accessPath, InterfaceName))); //10 megs + res2.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; + return res2; + } + + //okay we're going over + var binding = new WSHttpBinding() + { + SendTimeout = new TimeSpan(0, 0, 40), + MaxReceivedMessageSize = TransferLimitRemote + }; + var requireAuth = InterfaceName != typeof(ITGConnectivity).Name; + binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; + binding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check + binding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None; + var address = new EndpointAddress(String.Format("https://{0}:{1}/{2}/{3}", HTTPSURL, HTTPSPort, accessPath, InterfaceName)); + var res = new ChannelFactory(binding, address); + if (requireAuth) + { + res.Credentials.UserName.UserName = HTTPSUsername; + res.Credentials.UserName.Password = HTTPSPassword; + res.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; + } + return res; + } + + /// + public ConnectivityLevel ConnectionStatus() + { + return ConnectionStatus(out string unused); + } + + /// + public ConnectivityLevel ConnectionStatus(out string error) + { + try + { + GetComponentImpl(false).VerifyConnection(); + } + catch (CommunicationException e) + { + error = e.ToString(); + return ConnectivityLevel.None; + } + try + { + GetServiceComponent().Version(); + } + catch(Exception e) + { + error = e.ToString(); + return ConnectivityLevel.Connected; + } + try + { + GetServiceComponent().Version(); + error = null; + return ConnectivityLevel.Administrator; + } + catch(Exception e) + { + error = e.ToString(); + return ConnectivityLevel.Authenticated; + } + } + + #region IDisposable Support + /// + /// To detect redundant calls + /// + private bool disposedValue = false; + + /// + /// Implements the pattern. Calls + /// + /// if was called manually, if it was from the finalizer + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + CloseAllChannels(true); + } + + // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. + // TODO: set large fields to null. + + disposedValue = true; + } + } + + // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. + // ~Interface() { + // // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + // Dispose(false); + // } + + /// + /// Implements the pattern + /// + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + // TODO: uncomment the following line if the finalizer is overridden above. + // GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/TGServiceInterface/TGServiceInterface.csproj b/TGServiceInterface/TGServiceInterface.csproj index 1c5769d1ba..c5a0a379a6 100644 --- a/TGServiceInterface/TGServiceInterface.csproj +++ b/TGServiceInterface/TGServiceInterface.csproj @@ -1,81 +1,81 @@ - - - - - Debug - AnyCPU - {AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB} - Library - Properties - TGServiceInterface - TGServiceInterface - v4.5.2 - 512 - - - tgs.ico - - - true - bin\Debug\ - DEBUG;TRACE - full - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - bin\Release\ - TRACE - bin\x86\Release\TGServiceInterface.xml - true - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + AnyCPU + {AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB} + Library + Properties + TGServiceInterface + TGServiceInterface + v4.5.2 + 512 + + + tgs.ico + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\ + TRACE + bin\x86\Release\TGServiceInterface.xml + true + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TGServiceTests/Interface/TestHelpers.cs b/TGServiceTests/ServiceInterface/TestHelpers.cs similarity index 100% rename from TGServiceTests/Interface/TestHelpers.cs rename to TGServiceTests/ServiceInterface/TestHelpers.cs diff --git a/TGServiceTests/Interface/TestInterface.cs b/TGServiceTests/ServiceInterface/TestInterface.cs similarity index 89% rename from TGServiceTests/Interface/TestInterface.cs rename to TGServiceTests/ServiceInterface/TestInterface.cs index ebb8ec3751..f8fa81420a 100644 --- a/TGServiceTests/Interface/TestInterface.cs +++ b/TGServiceTests/ServiceInterface/TestInterface.cs @@ -27,7 +27,7 @@ namespace TGServiceInterface.Tests Assert.IsFalse(String.IsNullOrWhiteSpace(message)); return true; }; - Interface.SetBadCertificateHandler(func); + ServerInterface.SetBadCertificateHandler(func); } /// @@ -37,7 +37,7 @@ namespace TGServiceInterface.Tests public void TestBadCertificateHandler() { var ran = false; - Interface.SetBadCertificateHandler(_ => + ServerInterface.SetBadCertificateHandler(_ => { ran = true; return true; @@ -50,9 +50,9 @@ namespace TGServiceInterface.Tests /// Creates a remote configured pointing at an invalid address /// /// The created - Interface CreateFakeRemoteInterface() + ServerInterface CreateFakeRemoteInterface() { - return new Interface("some.fake.url.420", 34752, "user", "password"); + return new ServerInterface("some.fake.url.420", 34752, "user", "password"); } /// @@ -61,7 +61,7 @@ namespace TGServiceInterface.Tests [TestMethod] public void TestLocalInstantiation() { - Assert.IsFalse(new Interface().IsRemoteConnection); + Assert.IsFalse(new ServerInterface().IsRemoteConnection); } /// @@ -77,7 +77,7 @@ namespace TGServiceInterface.Tests public void TestCopyRemoteInterface() { var first = CreateFakeRemoteInterface(); - var second = new Interface(first); + var second = new ServerInterface(first); Assert.AreEqual(first.HTTPSURL, second.HTTPSURL); Assert.AreEqual(first.HTTPSPort, second.HTTPSPort); Assert.IsTrue(second.IsRemoteConnection); diff --git a/TGServiceTests/TGServiceTests.csproj b/TGServiceTests/TGServiceTests.csproj index 870d624bb6..f61981f9ee 100644 --- a/TGServiceTests/TGServiceTests.csproj +++ b/TGServiceTests/TGServiceTests.csproj @@ -1,116 +1,116 @@ - - - - - Debug - AnyCPU - {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971} - Library - Properties - TGServiceTests - TGServiceTests - v4.6.1 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 15.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - false - - - - ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll - - - ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - ..\packages\Moq.4.7.145\lib\net45\Moq.dll - - - - - - - - - - - - - - - - - - Component - - - - - - - - - - - - - - {89191f69-b18e-4b59-b72e-e12f9b6811a0} - TGCommandLine - - - {394e7643-6b8c-416f-ab18-95ac12648cdc} - TGControlPanel - - - {8956d4c3-bfb9-448e-bf5f-ee7e6f9996f9} - TGInstallerWrapper - - - {f32eda25-0855-411c-af5e-f0d042917e2d} - TGServerService - - - {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - + + + + + Debug + AnyCPU + {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971} + Library + Properties + TGServiceTests + TGServiceTests + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll + + + ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + ..\packages\Moq.4.7.145\lib\net45\Moq.dll + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + {89191f69-b18e-4b59-b72e-e12f9b6811a0} + TGCommandLine + + + {394e7643-6b8c-416f-ab18-95ac12648cdc} + TGControlPanel + + + {8956d4c3-bfb9-448e-bf5f-ee7e6f9996f9} + TGInstallerWrapper + + + {f32eda25-0855-411c-af5e-f0d042917e2d} + TGServerService + + + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} + TGServiceInterface + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file From 6e54f622deea11b2eb882cd7f4584c04eb994dec Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Sun, 12 Nov 2017 21:24:39 -0500 Subject: [PATCH 03/31] Sanely namespaces the project --- .github/CONTRIBUTING.md | 4 +- AssemblyInfo.global.cs | 2 +- README.md | 4 +- .../AdminCommands.cs | 6 +- {TGCommandLine => TGS.CommandLine}/App.config | 0 .../BYONDCommands.cs | 6 +- .../ChatCommands.cs | 6 +- .../ConfigCommands.cs | 6 +- .../ConsoleCommand.cs | 4 +- .../DDCommands.cs | 630 ++++---- .../DMCommands.cs | 6 +- .../InstanceRootCommand.cs | 4 +- {TGCommandLine => TGS.CommandLine}/Program.cs | 570 +++---- .../Properties/AssemblyInfo.cs | 34 +- .../RepoCommands.cs | 6 +- .../RootCommands.cs | 6 +- .../ServiceCommands.cs | 10 +- .../TGS.CommandLine.csproj | 8 +- {TGCommandLine => TGS.CommandLine}/tgs.ico | Bin .../App.config | 12 +- .../ControlPanel/ByondPage.cs | 6 +- .../ControlPanel/ChatPage.cs | 6 +- .../ControlPanel/ControlPanel.Designer.cs | 2 +- .../ControlPanel/ControlPanel.cs | 6 +- .../ControlPanel/ControlPanel.resx | 0 .../ControlPanel/RepoPage.cs | 6 +- .../ControlPanel/ServerPage.cs | 6 +- .../ControlPanel/StaticPage.cs | 6 +- .../CountedForm.cs | 2 +- .../GithubLoginPrompt.Designer.cs | 2 +- .../GithubLoginPrompt.cs | 6 +- .../GithubLoginPrompt.resx | 0 .../InstanceSelector.Designer.cs | 2 +- .../InstanceSelector.cs | 6 +- .../InstanceSelector.resx | 0 .../Login.Designer.cs | 2 +- {TGControlPanel => TGS.ControlPanel}/Login.cs | 4 +- .../Login.resx | 0 .../Program.cs | 6 +- .../Properties/AssemblyInfo.cs | 32 +- .../Properties/Settings.Designer.cs | 2 +- .../Properties/Settings.settings | 2 +- .../ServerOpForm.cs | 8 +- .../TGS.ControlPanel.csproj | 8 +- .../TestMergeManager.Designer.cs | 2 +- .../TestMergeManager.cs | 6 +- .../TestMergeManager.resx | 0 .../packages.config | 0 {TGControlPanel => TGS.ControlPanel}/tgs.ico | Bin .../App.config | 0 .../FodyWeavers.xml | 0 .../Main.Designer.cs | 2 +- .../Main.cs | 22 +- .../Main.resx | 0 .../Program.cs | 2 +- .../Properties/AssemblyInfo.cs | 0 .../Properties/Resources.Designer.cs | 8 +- .../Properties/Resources.resx | 6 +- .../TGS.Installer.UI.csproj | 6 +- .../app.manifest | 0 .../packages.config | 0 .../tgs.ico | Bin .../Product.wxs | 304 ++-- .../TGS.Installer.wixproj | 180 +-- .../DreamDaemonBridge.cs | 6 +- .../FodyWeavers.xml | 0 .../Properties/AssemblyInfo.cs | 0 .../TGS.Interface.Bridge.csproj | 6 +- .../packages.config | 0 .../ChatSetupInfo.cs | 688 ++++---- .../Command.cs | 2 +- .../Components/Administration.cs | 2 +- .../Components/Byond.cs | 2 +- .../Components/Chat.cs | 2 +- .../Components/Compiler.cs | 2 +- .../Components/Config.cs | 2 +- .../Components/Connectivity.cs | 2 +- .../Components/DreamDaemon.cs | 2 +- .../Components/Instance.cs | 2 +- .../Components/InstanceManager.cs | 2 +- .../Components/Interop.cs | 2 +- .../Components/Landing.cs | 2 +- .../Components/Repository.cs | 2 +- .../Components/Service.cs | 2 +- .../Enumerations.cs | 2 +- .../Helpers.cs | 2 +- .../InstanceMetadata.cs | 2 +- .../Properties/AssemblyInfo.cs | 32 +- .../PullRequestInfo.cs | 2 +- .../RootCommand.cs | 2 +- .../ServerInterface.cs | 4 +- .../TGS.Interface.csproj | 160 +- .../TGS.Interface.nuspec | 2 +- {TGServerService => TGS.Interface}/tgs.ico | Bin .../App.config | 8 +- .../ChatCommands/ByondCommand.cs | 4 +- .../ChatCommands/ChatCommand.cs | 4 +- .../ChatCommands/CommandInfo.cs | 2 +- .../ChatCommands/KekCommand.cs | 2 +- .../ChatCommands/PullRequestsCommand.cs | 2 +- .../ChatCommands/RevisionCommand.cs | 2 +- .../ChatCommands/RootChatCommand.cs | 4 +- .../ChatCommands/ServerChatCommand.cs | 2 +- .../ChatCommands/VersionCommand.cs | 2 +- .../ChatProviders/ChatProvider.cs | 4 +- .../ChatProviders/DiscordChatProvider.cs | 4 +- .../ChatProviders/IRCChatProvider.cs | 4 +- .../DeprecatedInstanceConfig.cs | 2 +- .../EventID.cs | 74 +- .../InstanceConfig.cs | 4 +- .../MessageType.cs | 2 +- .../ProcessExtension.cs | 2 +- .../Program.cs | 2 +- .../ProjectInstaller.cs | 2 +- .../Properties/AssemblyInfo.cs | 32 +- .../Properties/Settings.Designer.cs | 2 +- .../Properties/Settings.settings | 2 +- .../RepoConfig.cs | 4 +- .../RootAuthorizationManager.cs | 4 +- .../ServerInstance/Administration.cs | 6 +- .../ServerInstance/Byond.cs | 6 +- .../ServerInstance/Chat.cs | 10 +- .../ServerInstance/Compiler.cs | 6 +- .../ServerInstance/Config.cs | 4 +- .../ServerInstance/DreamDaemon.cs | 8 +- .../ServerInstance/Interop.cs | 8 +- .../ServerInstance/PreactionHandler.cs | 2 +- .../ServerInstance/Repository.cs | 8 +- .../ServerInstance/ServerInstance.cs | 4 +- .../Service.cs | 1386 ++++++++--------- .../TGS.Server.Service.csproj | 8 +- .../packages.config | 0 .../tgs.ico | Bin .../Repository/RepositoryCommandTest.cs | 6 +- .../TestRepoSetPushTestmergeCommitsCommand.cs | 6 +- .../Repository/TestRepoStatusCommand.cs | 6 +- .../ControlPanel/TestInstanceSelector.cs | 6 +- .../OutputProcOverriderTest.cs | 2 +- .../Properties/AssemblyInfo.cs | 0 .../Service/ServiceAccessor.cs | 2 +- .../Service/TestInstanceConfig.cs | 2 +- .../Service/TestServerInstance.cs | 2 +- .../Service/TestService.cs | 2 +- .../ServiceInterface/TestHelpers.cs | 2 +- .../ServiceInterface/TestInterface.cs | 4 +- .../TGS.Tests.csproj | 230 +-- .../TempDirectoryRequiredTest.cs | 0 {TGServiceTests => TGS.Tests}/packages.config | 0 TGStationServer3.sln | 16 +- Tools/CoverageExclusions.runsettings | 2 +- Tools/PostCIBuild.ps1 | 14 +- Tools/SignBasics.ps1 | 10 +- Tools/SignMSI.ps1 | 2 +- appveyor.yml | 4 +- 154 files changed, 2434 insertions(+), 2434 deletions(-) rename {TGCommandLine => TGS.CommandLine}/AdminCommands.cs (96%) rename {TGCommandLine => TGS.CommandLine}/App.config (100%) rename {TGCommandLine => TGS.CommandLine}/BYONDCommands.cs (97%) rename {TGCommandLine => TGS.CommandLine}/ChatCommands.cs (99%) rename {TGCommandLine => TGS.CommandLine}/ConfigCommands.cs (97%) rename {TGCommandLine => TGS.CommandLine}/ConsoleCommand.cs (80%) rename {TGCommandLine => TGS.CommandLine}/DDCommands.cs (94%) rename {TGCommandLine => TGS.CommandLine}/DMCommands.cs (98%) rename {TGCommandLine => TGS.CommandLine}/InstanceRootCommand.cs (94%) rename {TGCommandLine => TGS.CommandLine}/Program.cs (95%) rename {TGCommandLine => TGS.CommandLine}/Properties/AssemblyInfo.cs (97%) rename {TGCommandLine => TGS.CommandLine}/RepoCommands.cs (99%) rename {TGCommandLine => TGS.CommandLine}/RootCommands.cs (98%) rename {TGCommandLine => TGS.CommandLine}/ServiceCommands.cs (97%) rename TGCommandLine/TGCommandLine.csproj => TGS.CommandLine/TGS.CommandLine.csproj (92%) rename {TGCommandLine => TGS.CommandLine}/tgs.ico (100%) rename {TGControlPanel => TGS.ControlPanel}/App.config (82%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/ByondPage.cs (96%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/ChatPage.cs (98%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/ControlPanel.Designer.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/ControlPanel.cs (97%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/ControlPanel.resx (100%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/RepoPage.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/ServerPage.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/ControlPanel/StaticPage.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/CountedForm.cs (97%) rename {TGControlPanel => TGS.ControlPanel}/GithubLoginPrompt.Designer.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/GithubLoginPrompt.cs (96%) rename {TGControlPanel => TGS.ControlPanel}/GithubLoginPrompt.resx (100%) rename {TGControlPanel => TGS.ControlPanel}/InstanceSelector.Designer.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/InstanceSelector.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/InstanceSelector.resx (100%) rename {TGControlPanel => TGS.ControlPanel}/Login.Designer.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/Login.cs (98%) rename {TGControlPanel => TGS.ControlPanel}/Login.resx (100%) rename {TGControlPanel => TGS.ControlPanel}/Program.cs (98%) rename {TGControlPanel => TGS.ControlPanel}/Properties/AssemblyInfo.cs (97%) rename {TGControlPanel => TGS.ControlPanel}/Properties/Settings.Designer.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/Properties/Settings.settings (95%) rename {TGControlPanel => TGS.ControlPanel}/ServerOpForm.cs (63%) rename TGControlPanel/TGControlPanel.csproj => TGS.ControlPanel/TGS.ControlPanel.csproj (95%) rename {TGControlPanel => TGS.ControlPanel}/TestMergeManager.Designer.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/TestMergeManager.cs (99%) rename {TGControlPanel => TGS.ControlPanel}/TestMergeManager.resx (100%) rename {TGControlPanel => TGS.ControlPanel}/packages.config (100%) rename {TGControlPanel => TGS.ControlPanel}/tgs.ico (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/App.config (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/FodyWeavers.xml (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/Main.Designer.cs (99%) rename {TGInstallerWrapper => TGS.Installer.UI}/Main.cs (90%) rename {TGInstallerWrapper => TGS.Installer.UI}/Main.resx (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/Program.cs (91%) rename {TGInstallerWrapper => TGS.Installer.UI}/Properties/AssemblyInfo.cs (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/Properties/Resources.Designer.cs (91%) rename {TGInstallerWrapper => TGS.Installer.UI}/Properties/Resources.resx (93%) rename TGInstallerWrapper/TGInstallerWrapper.csproj => TGS.Installer.UI/TGS.Installer.UI.csproj (96%) rename {TGInstallerWrapper => TGS.Installer.UI}/app.manifest (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/packages.config (100%) rename {TGInstallerWrapper => TGS.Installer.UI}/tgs.ico (100%) rename {TGServiceInstaller => TGS.Installer}/Product.wxs (71%) rename TGServiceInstaller/TGServiceInstaller.wixproj => TGS.Installer/TGS.Installer.wixproj (85%) rename {TGDreamDaemonBridge => TGS.Interface.Bridge}/DreamDaemonBridge.cs (92%) rename {TGDreamDaemonBridge => TGS.Interface.Bridge}/FodyWeavers.xml (100%) rename {TGDreamDaemonBridge => TGS.Interface.Bridge}/Properties/AssemblyInfo.cs (100%) rename TGDreamDaemonBridge/TGDreamDaemonBridge.csproj => TGS.Interface.Bridge/TGS.Interface.Bridge.csproj (95%) rename {TGDreamDaemonBridge => TGS.Interface.Bridge}/packages.config (100%) rename {TGServiceInterface => TGS.Interface}/ChatSetupInfo.cs (96%) rename {TGServiceInterface => TGS.Interface}/Command.cs (99%) rename {TGServiceInterface => TGS.Interface}/Components/Administration.cs (97%) rename {TGServiceInterface => TGS.Interface}/Components/Byond.cs (97%) rename {TGServiceInterface => TGS.Interface}/Components/Chat.cs (97%) rename {TGServiceInterface => TGS.Interface}/Components/Compiler.cs (98%) rename {TGServiceInterface => TGS.Interface}/Components/Config.cs (98%) rename {TGServiceInterface => TGS.Interface}/Components/Connectivity.cs (91%) rename {TGServiceInterface => TGS.Interface}/Components/DreamDaemon.cs (99%) rename {TGServiceInterface => TGS.Interface}/Components/Instance.cs (93%) rename {TGServiceInterface => TGS.Interface}/Components/InstanceManager.cs (98%) rename {TGServiceInterface => TGS.Interface}/Components/Interop.cs (93%) rename {TGServiceInterface => TGS.Interface}/Components/Landing.cs (94%) rename {TGServiceInterface => TGS.Interface}/Components/Repository.cs (99%) rename {TGServiceInterface => TGS.Interface}/Components/Service.cs (97%) rename {TGServiceInterface => TGS.Interface}/Enumerations.cs (99%) rename {TGServiceInterface => TGS.Interface}/Helpers.cs (98%) rename {TGServiceInterface => TGS.Interface}/InstanceMetadata.cs (96%) rename {TGServiceInterface => TGS.Interface}/Properties/AssemblyInfo.cs (98%) rename {TGServiceInterface => TGS.Interface}/PullRequestInfo.cs (97%) rename {TGServiceInterface => TGS.Interface}/RootCommand.cs (99%) rename {TGServiceInterface => TGS.Interface}/ServerInterface.cs (99%) rename TGServiceInterface/TGServiceInterface.csproj => TGS.Interface/TGS.Interface.csproj (92%) rename TGServiceInterface/TGServiceInterface.nuspec => TGS.Interface/TGS.Interface.nuspec (96%) rename {TGServerService => TGS.Interface}/tgs.ico (100%) rename {TGServerService => TGS.Server.Service}/App.config (60%) rename {TGServerService => TGS.Server.Service}/ChatCommands/ByondCommand.cs (93%) rename {TGServerService => TGS.Server.Service}/ChatCommands/ChatCommand.cs (95%) rename {TGServerService => TGS.Server.Service}/ChatCommands/CommandInfo.cs (94%) rename {TGServerService => TGS.Server.Service}/ChatCommands/KekCommand.cs (91%) rename {TGServerService => TGS.Server.Service}/ChatCommands/PullRequestsCommand.cs (95%) rename {TGServerService => TGS.Server.Service}/ChatCommands/RevisionCommand.cs (94%) rename {TGServerService => TGS.Server.Service}/ChatCommands/RootChatCommand.cs (91%) rename {TGServerService => TGS.Server.Service}/ChatCommands/ServerChatCommand.cs (97%) rename {TGServerService => TGS.Server.Service}/ChatCommands/VersionCommand.cs (93%) rename {TGServerService => TGS.Server.Service}/ChatProviders/ChatProvider.cs (97%) rename {TGServerService => TGS.Server.Service}/ChatProviders/DiscordChatProvider.cs (99%) rename {TGServerService => TGS.Server.Service}/ChatProviders/IRCChatProvider.cs (99%) rename {TGServerService => TGS.Server.Service}/DeprecatedInstanceConfig.cs (99%) rename {TGServerService => TGS.Server.Service}/EventID.cs (68%) rename {TGServerService => TGS.Server.Service}/InstanceConfig.cs (99%) rename {TGServerService => TGS.Server.Service}/MessageType.cs (94%) rename {TGServerService => TGS.Server.Service}/ProcessExtension.cs (98%) rename {TGServerService => TGS.Server.Service}/Program.cs (99%) rename {TGServerService => TGS.Server.Service}/ProjectInstaller.cs (96%) rename {TGServerService => TGS.Server.Service}/Properties/AssemblyInfo.cs (97%) rename {TGServerService => TGS.Server.Service}/Properties/Settings.Designer.cs (98%) rename {TGServerService => TGS.Server.Service}/Properties/Settings.settings (91%) rename {TGServerService => TGS.Server.Service}/RepoConfig.cs (97%) rename {TGServerService => TGS.Server.Service}/RootAuthorizationManager.cs (95%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Administration.cs (98%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Byond.cs (99%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Chat.cs (97%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Compiler.cs (99%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Config.cs (99%) rename {TGServerService => TGS.Server.Service}/ServerInstance/DreamDaemon.cs (99%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Interop.cs (98%) rename {TGServerService => TGS.Server.Service}/ServerInstance/PreactionHandler.cs (99%) rename {TGServerService => TGS.Server.Service}/ServerInstance/Repository.cs (99%) rename {TGServerService => TGS.Server.Service}/ServerInstance/ServerInstance.cs (98%) rename {TGServerService => TGS.Server.Service}/Service.cs (96%) rename TGServerService/TGServerService.csproj => TGS.Server.Service/TGS.Server.Service.csproj (97%) rename {TGServerService => TGS.Server.Service}/packages.config (100%) rename {TGServiceInterface => TGS.Server.Service}/tgs.ico (100%) rename {TGServiceTests => TGS.Tests}/CommandLine/Commands/Repository/RepositoryCommandTest.cs (86%) rename {TGServiceTests => TGS.Tests}/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs (93%) rename {TGServiceTests => TGS.Tests}/CommandLine/Commands/Repository/TestRepoStatusCommand.cs (92%) rename {TGServiceTests => TGS.Tests}/ControlPanel/TestInstanceSelector.cs (88%) rename {TGServiceTests => TGS.Tests}/OutputProcOverriderTest.cs (95%) rename {TGServiceTests => TGS.Tests}/Properties/AssemblyInfo.cs (100%) rename {TGServiceTests => TGS.Tests}/Service/ServiceAccessor.cs (93%) rename {TGServiceTests => TGS.Tests}/Service/TestInstanceConfig.cs (97%) rename {TGServiceTests => TGS.Tests}/Service/TestServerInstance.cs (97%) rename {TGServiceTests => TGS.Tests}/Service/TestService.cs (98%) rename {TGServiceTests => TGS.Tests}/ServiceInterface/TestHelpers.cs (98%) rename {TGServiceTests => TGS.Tests}/ServiceInterface/TestInterface.cs (97%) rename TGServiceTests/TGServiceTests.csproj => TGS.Tests/TGS.Tests.csproj (91%) rename {TGServiceTests => TGS.Tests}/TempDirectoryRequiredTest.cs (100%) rename {TGServiceTests => TGS.Tests}/packages.config (100%) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9dc136a1df..b839e64b22 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -28,11 +28,11 @@ Visual Studio comes with the nuget package manager. To install the dependencies, ##### (Optional) Installing WiX Toolset and Visual Studio Extension -The [WiX Toolset](http://wixtoolset.org/) is used for creating the installer .msi (Not the .exe, which is a standard C# program wrapper to the .msi). Building and modifying this is not required for debugging and development of the service but necessary if you want to debug tweaks to the installer configuration. You can download the Wix Toolset and Visual studio extension [here](http://wixtoolset.org/releases/). This will allow you to build `TGServiceInstaller.wixproj` just like all the other projects. +The [WiX Toolset](http://wixtoolset.org/) is used for creating the installer .msi (Not the .exe, which is a standard C# program wrapper to the .msi). Building and modifying this is not required for debugging and development of the service but necessary if you want to debug tweaks to the installer configuration. You can download the Wix Toolset and Visual studio extension [here](http://wixtoolset.org/releases/). This will allow you to build `TGS.Installer.wixproj` just like all the other projects. #### Debugging -So you've built the project and everything's good, right? Now you have to debug it. Debugging the command line and control panel are easy enough, just launch them like any other process. Debugging the TGServerService itself though requires a bit of finagling due to how Windows services work. +So you've built the project and everything's good, right? Now you have to debug it. Debugging the command line and control panel are easy enough, just launch them like any other process. Debugging the TGS.Server.Service itself though requires a bit of finagling due to how Windows services work. 1. Uninstall any release versions of TG Station Server 3 you may have on your machine 1. Open an administrative Windows cmd prompt diff --git a/AssemblyInfo.global.cs b/AssemblyInfo.global.cs index 2e9b5ff98f..56e3f1eec0 100644 --- a/AssemblyInfo.global.cs +++ b/AssemblyInfo.global.cs @@ -7,4 +7,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyFileVersion("3.2.0.5")] [assembly: AssemblyInformationalVersion("3.2.0.5")] -[assembly: InternalsVisibleTo("TGServiceTests")] +[assembly: InternalsVisibleTo("TGS.Tests")] diff --git a/README.md b/README.md index 21bdb7331a..e99ccffc5f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build status](https://ci.appveyor.com/api/projects/status/7t1h7bvuha0p9j5f?svg=true)](https://ci.appveyor.com/project/Cyberboss/tgstation-server-tools) [![Build Status](https://travis-ci.org/tgstation/tgstation-server.svg?branch=master)](https://travis-ci.org/tgstation/tgstation-server) [![codecov](https://codecov.io/gh/tgstation/tgstation-server/branch/master/graph/badge.svg)](https://codecov.io/gh/tgstation/tgstation-server) -[![GitHub license](https://img.shields.io/github/license/tgstation/tgstation-server.svg)](https://github.com/tgstation/tgstation-server/blob/master/LICENSE) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/tgstation/tgstation-server.svg)](http://isitmaintained.com/project/tgstation/tgstation-server "Average time to resolve an issue") [![NuGet version](https://badge.fury.io/nu/TGServiceInterface.svg)](https://badge.fury.io/nu/TGServiceInterface) +[![GitHub license](https://img.shields.io/github/license/tgstation/tgstation-server.svg)](https://github.com/tgstation/tgstation-server/blob/master/LICENSE) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/tgstation/tgstation-server.svg)](http://isitmaintained.com/project/tgstation/tgstation-server "Average time to resolve an issue") [![NuGet version](https://badge.fury.io/nu/TTGServiceInterface.svg)](https://badge.fury.io/nu/TGServiceInterface) [![forthebadge](http://forthebadge.com/images/badges/made-with-c-sharp.svg)](http://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) @@ -191,7 +191,7 @@ You can clear all active test merges using `Reset to Origin Branch` in the `Repo ### Viewing Server Logs * Logs are stored in the Windows event viewer under `Windows Logs` -> `Application`. You'll need to filter this list for `TG Station Server` -* Every event type is keyed with an ID. A complete listing of these IDs and their purpose can be found [here](https://github.com/tgstation/tgstation-server/blob/master/TGServerService/EventID.cs). +* Every event type is keyed with an ID. A complete listing of these IDs and their purpose can be found [here](https://github.com/tgstation/tgstation-server/blob/master/TGS.Server.Service/EventID.cs). * You can also import the custom view `View TGS3 Logs.xml` in this folder to have them automatically filtered ### Enabling upstream changelog generation diff --git a/TGCommandLine/AdminCommands.cs b/TGS.CommandLine/AdminCommands.cs similarity index 96% rename from TGCommandLine/AdminCommands.cs rename to TGS.CommandLine/AdminCommands.cs index aedddd15b1..953c002b07 100644 --- a/TGCommandLine/AdminCommands.cs +++ b/TGS.CommandLine/AdminCommands.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class AdminCommand : InstanceRootCommand { diff --git a/TGCommandLine/App.config b/TGS.CommandLine/App.config similarity index 100% rename from TGCommandLine/App.config rename to TGS.CommandLine/App.config diff --git a/TGCommandLine/BYONDCommands.cs b/TGS.CommandLine/BYONDCommands.cs similarity index 97% rename from TGCommandLine/BYONDCommands.cs rename to TGS.CommandLine/BYONDCommands.cs index 2666104e44..869c1ccfd3 100644 --- a/TGCommandLine/BYONDCommands.cs +++ b/TGS.CommandLine/BYONDCommands.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Threading; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class BYONDCommand : InstanceRootCommand { diff --git a/TGCommandLine/ChatCommands.cs b/TGS.CommandLine/ChatCommands.cs similarity index 99% rename from TGCommandLine/ChatCommands.cs rename to TGS.CommandLine/ChatCommands.cs index 651520457d..bf5fd5d3aa 100644 --- a/TGCommandLine/ChatCommands.cs +++ b/TGS.CommandLine/ChatCommands.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class IRCCommand : InstanceRootCommand { diff --git a/TGCommandLine/ConfigCommands.cs b/TGS.CommandLine/ConfigCommands.cs similarity index 97% rename from TGCommandLine/ConfigCommands.cs rename to TGS.CommandLine/ConfigCommands.cs index 0aae903ed4..ab4191a5d6 100644 --- a/TGCommandLine/ConfigCommands.cs +++ b/TGS.CommandLine/ConfigCommands.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.IO; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class ConfigCommand : InstanceRootCommand { diff --git a/TGCommandLine/ConsoleCommand.cs b/TGS.CommandLine/ConsoleCommand.cs similarity index 80% rename from TGCommandLine/ConsoleCommand.cs rename to TGS.CommandLine/ConsoleCommand.cs index 5e5274775a..1aa0e3f773 100644 --- a/TGCommandLine/ConsoleCommand.cs +++ b/TGS.CommandLine/ConsoleCommand.cs @@ -1,6 +1,6 @@ -using TGServiceInterface; +using TGS.Interface; -namespace TGCommandLine +namespace TGS.CommandLine { abstract class ConsoleCommand : Command { diff --git a/TGCommandLine/DDCommands.cs b/TGS.CommandLine/DDCommands.cs similarity index 94% rename from TGCommandLine/DDCommands.cs rename to TGS.CommandLine/DDCommands.cs index ef518c8911..9681589cf8 100644 --- a/TGCommandLine/DDCommands.cs +++ b/TGS.CommandLine/DDCommands.cs @@ -1,315 +1,315 @@ -using System; -using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; - -namespace TGCommandLine -{ - class DDCommand : InstanceRootCommand - { - public DDCommand() - { - Keyword = "dd"; - Children = new Command[] { new DDStartCommand(), new DDStopCommand(), new DDRestartCommand(), new DDStatusCommand(), new DDAutostartCommand(), new DDPortCommand(), new DDSecurityCommand(), new DDWorldAnnounceCommand(), new DDWebclientCommand() }; - } - public override string GetHelpText() - { - return "Manage DreamDaemon"; - } - } - - class DDWorldAnnounceCommand : ConsoleCommand - { - public DDWorldAnnounceCommand() - { - Keyword = "announce"; - RequiredParameters = 1; - } - - public override string GetHelpText() - { - return "Sends a message all players on the server"; - } - - public override string GetArgumentString() - { - return ""; - } - - protected override ExitCode Run(IList parameters) - { - var res = Interface.GetComponent().WorldAnnounce(String.Join(" ", parameters)); - OutputProc(res ?? "Success!"); - return res == null ? ExitCode.Normal : ExitCode.ServerError; - } - } - - class DDStartCommand : ConsoleCommand - { - public DDStartCommand() - { - Keyword = "start"; - } - - public override string GetHelpText() - { - return "Starts the server and watchdog"; - } - - protected override ExitCode Run(IList parameters) - { - var res = Interface.GetComponent().Start(); - OutputProc(res ?? "Success!"); - return res == null ? ExitCode.Normal : ExitCode.ServerError; - } - } - - class DDStopCommand : ConsoleCommand - { - public DDStopCommand() - { - Keyword = "stop"; - } - public override string GetArgumentString() - { - return "[--graceful]"; - } - - public override string GetHelpText() - { - return "Stops the server and watchdog optionally waiting for the current round to end"; - } - - protected override ExitCode Run(IList parameters) - { - var DD = Interface.GetComponent(); - if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful") - { - if (DD.DaemonStatus() != DreamDaemonStatus.Online) - { - OutputProc("Error: The game is not currently running!"); - return ExitCode.ServerError; - } - DD.RequestStop(); - return ExitCode.Normal; - } - var res = DD.Stop(); - OutputProc(res ?? "Success!"); - return res == null ? ExitCode.Normal : ExitCode.ServerError; - } - } - class DDRestartCommand : ConsoleCommand - { - public DDRestartCommand() - { - Keyword = "restart"; - } - - public override string GetArgumentString() - { - return "[--graceful]"; - } - protected override ExitCode Run(IList parameters) - { - var DD = Interface.GetComponent(); - if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful") - { - if (DD.DaemonStatus() != DreamDaemonStatus.Online) - { - OutputProc("Error: The game is not currently running!"); - return ExitCode.ServerError; - } - DD.RequestRestart(); - return ExitCode.Normal; - } - var res = DD.Restart(); - OutputProc(res ?? "Success!"); - return res == null ? ExitCode.Normal : ExitCode.ServerError; - } - - public override string GetHelpText() - { - return "Restarts the server and watchdog optionally waiting for the current round to end"; - } - } - class DDStatusCommand : ConsoleCommand - { - public DDStatusCommand() - { - Keyword = "status"; - } - - public override string GetHelpText() - { - return "Gets the current status of the watchdog and server"; - } - - protected override ExitCode Run(IList parameters) - { - var DD = Interface.GetComponent(); - OutputProc(DD.StatusString(true)); - if (DD.ShutdownInProgress()) - OutputProc("The server will shutdown once the current round completes."); - var pc = DD.PlayerCount(); - if (pc != -1) - OutputProc(pc + " connected clients"); - return ExitCode.Normal; - } - } - - class DDAutostartCommand : ConsoleCommand - { - public DDAutostartCommand() - { - Keyword = "autostart"; - RequiredParameters = 1; - } - - protected override ExitCode Run(IList parameters) - { - var DD = Interface.GetComponent(); - switch (parameters[0].ToLower()) - { - case "on": - DD.SetAutostart(true); - break; - case "off": - DD.SetAutostart(false); - break; - case "check": - OutputProc("Autostart is: " + (DD.Autostart() ? "On" : "Off")); - break; - default: - OutputProc("Invalid parameter: " + parameters[0]); - return ExitCode.BadCommand; - } - return ExitCode.Normal; - } - - public override string GetArgumentString() - { - return ""; - } - public override string GetHelpText() - { - return "Change or check autostarting of the game server with the service"; - } - } - class DDWebclientCommand : ConsoleCommand - { - public DDWebclientCommand() - { - Keyword = "webclient"; - RequiredParameters = 1; - } - - protected override ExitCode Run(IList parameters) - { - var DD = Interface.GetComponent(); - switch (parameters[0].ToLower()) - { - case "on": - DD.SetWebclient(true); - break; - case "off": - DD.SetWebclient(false); - break; - case "check": - OutputProc("Webclient is: " + (DD.Webclient() ? "Enabled" : "Disabled")); - break; - default: - OutputProc("Invalid parameter: " + parameters[0]); - return ExitCode.BadCommand; - } - return ExitCode.Normal; - } - - public override string GetArgumentString() - { - return ""; - } - public override string GetHelpText() - { - return "Change or check if the BYOND webclient is enabled for the game server"; - } - } - - class DDPortCommand : ConsoleCommand - { - public DDPortCommand() - { - Keyword = "set-port"; - RequiredParameters = 1; - } - - protected override ExitCode Run(IList parameters) - { - ushort port; - try - { - port = Convert.ToUInt16(parameters[0]); - } - catch - { - OutputProc("Invalid port number!"); - return ExitCode.BadCommand; - } - - Interface.GetComponent().SetPort(port); - return ExitCode.Normal; - } - - public override string GetArgumentString() - { - return ""; - } - - public override string GetHelpText() - { - return "Sets the port DreamDaemon will open the server on. Requires a server restart to apply and queues a graceful one up"; - } - } - - class DDSecurityCommand : ConsoleCommand - { - public DDSecurityCommand() - { - Keyword = "set-security"; - RequiredParameters = 1; - } - - protected override ExitCode Run(IList parameters) - { - DreamDaemonSecurity sec; - switch (parameters[0].ToLower()) - { - case "safe": - sec = DreamDaemonSecurity.Safe; - break; - case "ultra": - case "ultrasafe": - sec = DreamDaemonSecurity.Ultrasafe; - break; - case "trust": - case "trusted": - sec = DreamDaemonSecurity.Trusted; - break; - default: - OutputProc("Invalid security word!"); - return ExitCode.BadCommand; - } - Interface.GetComponent().SetSecurityLevel(sec); - return ExitCode.Normal; - } - - public override string GetArgumentString() - { - return ""; - } - - public override string GetHelpText() - { - return "Sets the visibility option for the DreamDaemon world"; - } - } -} +using System; +using System.Collections.Generic; +using TGS.Interface; +using TGS.Interface.Components; + +namespace TGS.CommandLine +{ + class DDCommand : InstanceRootCommand + { + public DDCommand() + { + Keyword = "dd"; + Children = new Command[] { new DDStartCommand(), new DDStopCommand(), new DDRestartCommand(), new DDStatusCommand(), new DDAutostartCommand(), new DDPortCommand(), new DDSecurityCommand(), new DDWorldAnnounceCommand(), new DDWebclientCommand() }; + } + public override string GetHelpText() + { + return "Manage DreamDaemon"; + } + } + + class DDWorldAnnounceCommand : ConsoleCommand + { + public DDWorldAnnounceCommand() + { + Keyword = "announce"; + RequiredParameters = 1; + } + + public override string GetHelpText() + { + return "Sends a message all players on the server"; + } + + public override string GetArgumentString() + { + return ""; + } + + protected override ExitCode Run(IList parameters) + { + var res = Interface.GetComponent().WorldAnnounce(String.Join(" ", parameters)); + OutputProc(res ?? "Success!"); + return res == null ? ExitCode.Normal : ExitCode.ServerError; + } + } + + class DDStartCommand : ConsoleCommand + { + public DDStartCommand() + { + Keyword = "start"; + } + + public override string GetHelpText() + { + return "Starts the server and watchdog"; + } + + protected override ExitCode Run(IList parameters) + { + var res = Interface.GetComponent().Start(); + OutputProc(res ?? "Success!"); + return res == null ? ExitCode.Normal : ExitCode.ServerError; + } + } + + class DDStopCommand : ConsoleCommand + { + public DDStopCommand() + { + Keyword = "stop"; + } + public override string GetArgumentString() + { + return "[--graceful]"; + } + + public override string GetHelpText() + { + return "Stops the server and watchdog optionally waiting for the current round to end"; + } + + protected override ExitCode Run(IList parameters) + { + var DD = Interface.GetComponent(); + if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful") + { + if (DD.DaemonStatus() != DreamDaemonStatus.Online) + { + OutputProc("Error: The game is not currently running!"); + return ExitCode.ServerError; + } + DD.RequestStop(); + return ExitCode.Normal; + } + var res = DD.Stop(); + OutputProc(res ?? "Success!"); + return res == null ? ExitCode.Normal : ExitCode.ServerError; + } + } + class DDRestartCommand : ConsoleCommand + { + public DDRestartCommand() + { + Keyword = "restart"; + } + + public override string GetArgumentString() + { + return "[--graceful]"; + } + protected override ExitCode Run(IList parameters) + { + var DD = Interface.GetComponent(); + if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful") + { + if (DD.DaemonStatus() != DreamDaemonStatus.Online) + { + OutputProc("Error: The game is not currently running!"); + return ExitCode.ServerError; + } + DD.RequestRestart(); + return ExitCode.Normal; + } + var res = DD.Restart(); + OutputProc(res ?? "Success!"); + return res == null ? ExitCode.Normal : ExitCode.ServerError; + } + + public override string GetHelpText() + { + return "Restarts the server and watchdog optionally waiting for the current round to end"; + } + } + class DDStatusCommand : ConsoleCommand + { + public DDStatusCommand() + { + Keyword = "status"; + } + + public override string GetHelpText() + { + return "Gets the current status of the watchdog and server"; + } + + protected override ExitCode Run(IList parameters) + { + var DD = Interface.GetComponent(); + OutputProc(DD.StatusString(true)); + if (DD.ShutdownInProgress()) + OutputProc("The server will shutdown once the current round completes."); + var pc = DD.PlayerCount(); + if (pc != -1) + OutputProc(pc + " connected clients"); + return ExitCode.Normal; + } + } + + class DDAutostartCommand : ConsoleCommand + { + public DDAutostartCommand() + { + Keyword = "autostart"; + RequiredParameters = 1; + } + + protected override ExitCode Run(IList parameters) + { + var DD = Interface.GetComponent(); + switch (parameters[0].ToLower()) + { + case "on": + DD.SetAutostart(true); + break; + case "off": + DD.SetAutostart(false); + break; + case "check": + OutputProc("Autostart is: " + (DD.Autostart() ? "On" : "Off")); + break; + default: + OutputProc("Invalid parameter: " + parameters[0]); + return ExitCode.BadCommand; + } + return ExitCode.Normal; + } + + public override string GetArgumentString() + { + return ""; + } + public override string GetHelpText() + { + return "Change or check autostarting of the game server with the service"; + } + } + class DDWebclientCommand : ConsoleCommand + { + public DDWebclientCommand() + { + Keyword = "webclient"; + RequiredParameters = 1; + } + + protected override ExitCode Run(IList parameters) + { + var DD = Interface.GetComponent(); + switch (parameters[0].ToLower()) + { + case "on": + DD.SetWebclient(true); + break; + case "off": + DD.SetWebclient(false); + break; + case "check": + OutputProc("Webclient is: " + (DD.Webclient() ? "Enabled" : "Disabled")); + break; + default: + OutputProc("Invalid parameter: " + parameters[0]); + return ExitCode.BadCommand; + } + return ExitCode.Normal; + } + + public override string GetArgumentString() + { + return ""; + } + public override string GetHelpText() + { + return "Change or check if the BYOND webclient is enabled for the game server"; + } + } + + class DDPortCommand : ConsoleCommand + { + public DDPortCommand() + { + Keyword = "set-port"; + RequiredParameters = 1; + } + + protected override ExitCode Run(IList parameters) + { + ushort port; + try + { + port = Convert.ToUInt16(parameters[0]); + } + catch + { + OutputProc("Invalid port number!"); + return ExitCode.BadCommand; + } + + Interface.GetComponent().SetPort(port); + return ExitCode.Normal; + } + + public override string GetArgumentString() + { + return ""; + } + + public override string GetHelpText() + { + return "Sets the port DreamDaemon will open the server on. Requires a server restart to apply and queues a graceful one up"; + } + } + + class DDSecurityCommand : ConsoleCommand + { + public DDSecurityCommand() + { + Keyword = "set-security"; + RequiredParameters = 1; + } + + protected override ExitCode Run(IList parameters) + { + DreamDaemonSecurity sec; + switch (parameters[0].ToLower()) + { + case "safe": + sec = DreamDaemonSecurity.Safe; + break; + case "ultra": + case "ultrasafe": + sec = DreamDaemonSecurity.Ultrasafe; + break; + case "trust": + case "trusted": + sec = DreamDaemonSecurity.Trusted; + break; + default: + OutputProc("Invalid security word!"); + return ExitCode.BadCommand; + } + Interface.GetComponent().SetSecurityLevel(sec); + return ExitCode.Normal; + } + + public override string GetArgumentString() + { + return ""; + } + + public override string GetHelpText() + { + return "Sets the visibility option for the DreamDaemon world"; + } + } +} diff --git a/TGCommandLine/DMCommands.cs b/TGS.CommandLine/DMCommands.cs similarity index 98% rename from TGCommandLine/DMCommands.cs rename to TGS.CommandLine/DMCommands.cs index cbc1ef6ae2..380f2307e7 100644 --- a/TGCommandLine/DMCommands.cs +++ b/TGS.CommandLine/DMCommands.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Threading; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class DMCommand : InstanceRootCommand { diff --git a/TGCommandLine/InstanceRootCommand.cs b/TGS.CommandLine/InstanceRootCommand.cs similarity index 94% rename from TGCommandLine/InstanceRootCommand.cs rename to TGS.CommandLine/InstanceRootCommand.cs index f430785e26..107fe20689 100644 --- a/TGCommandLine/InstanceRootCommand.cs +++ b/TGS.CommandLine/InstanceRootCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using TGServiceInterface; +using TGS.Interface; -namespace TGCommandLine +namespace TGS.CommandLine { abstract class InstanceRootCommand : RootCommand { diff --git a/TGCommandLine/Program.cs b/TGS.CommandLine/Program.cs similarity index 95% rename from TGCommandLine/Program.cs rename to TGS.CommandLine/Program.cs index c1e7c18465..a9157d9512 100644 --- a/TGCommandLine/Program.cs +++ b/TGS.CommandLine/Program.cs @@ -1,285 +1,285 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using TGServiceInterface; -using TGServiceInterface.Components; - -namespace TGCommandLine -{ - class Program - { - static bool interactive = false, saidSrvVersion = false; - static IServerInterface currentInterface; - static Command.ExitCode RunCommandLine(IList argsAsList) - { - //first lookup the connection string - bool badConnectionString = false; - for (var I = 0; I < argsAsList.Count - 1; ++I) { - var lowerarg = argsAsList[I].ToLower(); - if (lowerarg == "-c" || lowerarg == "--connect") - { - var connectionString = argsAsList[I + 1]; - var splits = connectionString.Split('@'); - var userpass = splits[0].Split(':'); - if (splits.Length != 2 || userpass.Length != 2) - { - badConnectionString = true; - break; - } - var addrport = splits[1].Split(':'); - if (addrport.Length != 2) - { - badConnectionString = true; - break; - } - var username = userpass[0]; - var password = userpass[1]; - var address = addrport[0]; - ushort port; - try - { - port = Convert.ToUInt16(addrport[1]); - } - catch - { - badConnectionString = true; - break; - } - if(String.IsNullOrWhiteSpace(username) || String.IsNullOrWhiteSpace(password) || String.IsNullOrWhiteSpace(address)) - { - badConnectionString = true; - break; - } - argsAsList.RemoveAt(I); - argsAsList.RemoveAt(I); - ReplaceInterface(new ServerInterface(address, port, username, password)); - break; - } - } - - if (badConnectionString) - { - Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port"); - return Command.ExitCode.BadCommand; - } - - var res = currentInterface.ConnectionStatus(out string error); - if (!res.HasFlag(ConnectivityLevel.Connected)) - { - Console.WriteLine("Unable to connect to service: " + error); - Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port"); - return Command.ExitCode.ConnectionError; - } - - if (!res.HasFlag(ConnectivityLevel.Authenticated)) - { - Console.WriteLine("Authentication error: Username/password/windows identity is not authorized!"); - return Command.ExitCode.ConnectionError; - } - - if (!SentVMMWarning && currentInterface.VersionMismatch(out error)) - { - SentVMMWarning = true; - Console.WriteLine(error); - } - else if (interactive && !saidSrvVersion) - { - Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent().Version()); - saidSrvVersion = true; - } - - try - { - return new CLICommand(currentInterface).DoRun(argsAsList); - } - catch (Exception e) - { - Console.WriteLine("Error: " + e.ToString()); - return Command.ExitCode.ConnectionError; - }; - } - - static void ReplaceInterface(IServerInterface I) - { - currentInterface = I; - ConsoleCommand.Interface = I; - InstanceRootCommand.currentInterface = I; - saidSrvVersion = false; - } - - public static string ReadLineSecure() - { - string result = ""; - while (true) - { - ConsoleKeyInfo i = Console.ReadKey(true); - if (i.Key == ConsoleKey.Enter) - { - break; - } - else if (i.Key == ConsoleKey.Backspace) - { - if (result.Length > 0) - { - result = result.Substring(0, result.Length - 1); - Console.Write("\b \b"); - } - } - else - { - result += i.KeyChar; - Console.Write("*"); - } - } - Console.WriteLine(); - return result; - } - static bool SentVMMWarning = false; - static string AcceptedBadCert; - static bool BadCertificateInteractive(string message) - { - if (AcceptedBadCert == message) - return true; - Console.WriteLine(message); - Console.Write("Do you wish to continue? NOT RECCOMENDED! (y/N): "); - var result = Console.ReadLine().Trim().ToLower(); - if (result == "y" || result == "yes") - { - AcceptedBadCert = message; - return true; - } - return false; - } - - /// - /// Tries to set 's to , outputting appropriate messages - /// - /// The name of the to test - /// If , does not output on success - /// if a was achieved with , otherwise - static bool CheckInstanceConnectivity(string instanceName, bool silentSuccess) - { - var res = currentInterface.ConnectToInstance(instanceName); - if (!res.HasFlag(ConnectivityLevel.Connected)) - Console.WriteLine("Unable to connect to instance! Does it exist?"); - else if (!res.HasFlag(ConnectivityLevel.Authenticated)) - Console.WriteLine("The current user is not authorized to use this instance!"); - else - { - if(!silentSuccess) - Console.WriteLine("Successfully conected to instance!"); - return true; - } - return false; - } - - static int Main(string[] args) - { - ReplaceInterface(new ServerInterface()); - Command.OutputProcVar.Value = Console.WriteLine; - if (args.Length != 0) - { - var argsAsList = new List(args); - for (var I = 0; I < argsAsList.Count - 1; ++I) - { - if (argsAsList[I].ToLower() == "--instance") - { - if (!CheckInstanceConnectivity(args[I + 1], true)) - return (int)Command.ExitCode.ConnectionError; - argsAsList.RemoveRange(I, 2); - break; - } - else if (argsAsList[I].ToLower() == "--disable-ssl-verification") //im just not even going to document this because i hate it so much - { - argsAsList.RemoveAt(I); - --I; - ServerInterface.SetBadCertificateHandler(_ => false); - } - } - return (int)RunCommandLine(argsAsList); - } - //interactive mode - ServerInterface.SetBadCertificateHandler(BadCertificateInteractive); - Console.WriteLine("Type 'instance' to connect to a server instance"); - Console.WriteLine("Type 'remote' to connect to a remote service"); - while (true) - { - Console.Write("Enter command: "); - var NextCommand = Console.ReadLine(); - switch (NextCommand.ToLower()) - { - case "instance": - Console.Write("Enter instance name: "); - CheckInstanceConnectivity(Console.ReadLine(), false); - break; - case "remote": - SentVMMWarning = false; - Console.Write("Enter server address: "); - var address = Console.ReadLine(); - Console.Write("Enter server port: "); - ushort port; - try{ - port = Convert.ToUInt16(Console.ReadLine()); - } - catch - { - Console.WriteLine("Error: Bad port!"); - break; - } - Console.Write("Enter username: "); - var username = Console.ReadLine(); - Console.Write("Enter password: "); - var password = ReadLineSecure(); - ReplaceInterface(new ServerInterface(address, port, username, password)); - var res = currentInterface.ConnectionStatus(out string error); - if (!res.HasFlag(ConnectivityLevel.Connected)) - { - Console.WriteLine("Unable to connect: " + error); - ReplaceInterface(new ServerInterface()); - } - else if (!res.HasFlag(ConnectivityLevel.Authenticated)) - { - Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode..."); - ReplaceInterface(new ServerInterface()); - } - else - { - Console.WriteLine("Connected remotely"); - if (currentInterface.VersionMismatch(out error)) - { - SentVMMWarning = true; - Console.WriteLine(error); - } - Console.WriteLine("Type 'disconnect' to return to local mode"); - } - break; - case "disconnect": - SentVMMWarning = false; - ReplaceInterface(new ServerInterface()); - Console.WriteLine("Switch to local mode"); - break; - case "quit": - case "exit": - return (int)Command.ExitCode.Normal; -#if DEBUG - case "debug-upgrade": - currentInterface.GetComponent().PrepareForUpdate(); - return (int)Command.ExitCode.Normal; -#endif - default: - //linq voodoo to get quoted strings - var formattedCommand = NextCommand.Split('"') - .Select((element, index) => index % 2 == 0 // If even index - ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) // Split the item - : new string[] { element }) // Keep the entire item - .SelectMany(element => element).ToList(); - - formattedCommand = formattedCommand.Select(x => x.Trim()).ToList(); - formattedCommand.Remove(""); - RunCommandLine(formattedCommand); - break; - } - } - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using TGS.Interface; +using TGS.Interface.Components; + +namespace TGS.CommandLine +{ + class Program + { + static bool interactive = false, saidSrvVersion = false; + static IServerInterface currentInterface; + static Command.ExitCode RunCommandLine(IList argsAsList) + { + //first lookup the connection string + bool badConnectionString = false; + for (var I = 0; I < argsAsList.Count - 1; ++I) { + var lowerarg = argsAsList[I].ToLower(); + if (lowerarg == "-c" || lowerarg == "--connect") + { + var connectionString = argsAsList[I + 1]; + var splits = connectionString.Split('@'); + var userpass = splits[0].Split(':'); + if (splits.Length != 2 || userpass.Length != 2) + { + badConnectionString = true; + break; + } + var addrport = splits[1].Split(':'); + if (addrport.Length != 2) + { + badConnectionString = true; + break; + } + var username = userpass[0]; + var password = userpass[1]; + var address = addrport[0]; + ushort port; + try + { + port = Convert.ToUInt16(addrport[1]); + } + catch + { + badConnectionString = true; + break; + } + if(String.IsNullOrWhiteSpace(username) || String.IsNullOrWhiteSpace(password) || String.IsNullOrWhiteSpace(address)) + { + badConnectionString = true; + break; + } + argsAsList.RemoveAt(I); + argsAsList.RemoveAt(I); + ReplaceInterface(new ServerInterface(address, port, username, password)); + break; + } + } + + if (badConnectionString) + { + Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port"); + return Command.ExitCode.BadCommand; + } + + var res = currentInterface.ConnectionStatus(out string error); + if (!res.HasFlag(ConnectivityLevel.Connected)) + { + Console.WriteLine("Unable to connect to service: " + error); + Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port"); + return Command.ExitCode.ConnectionError; + } + + if (!res.HasFlag(ConnectivityLevel.Authenticated)) + { + Console.WriteLine("Authentication error: Username/password/windows identity is not authorized!"); + return Command.ExitCode.ConnectionError; + } + + if (!SentVMMWarning && currentInterface.VersionMismatch(out error)) + { + SentVMMWarning = true; + Console.WriteLine(error); + } + else if (interactive && !saidSrvVersion) + { + Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent().Version()); + saidSrvVersion = true; + } + + try + { + return new CLICommand(currentInterface).DoRun(argsAsList); + } + catch (Exception e) + { + Console.WriteLine("Error: " + e.ToString()); + return Command.ExitCode.ConnectionError; + }; + } + + static void ReplaceInterface(IServerInterface I) + { + currentInterface = I; + ConsoleCommand.Interface = I; + InstanceRootCommand.currentInterface = I; + saidSrvVersion = false; + } + + public static string ReadLineSecure() + { + string result = ""; + while (true) + { + ConsoleKeyInfo i = Console.ReadKey(true); + if (i.Key == ConsoleKey.Enter) + { + break; + } + else if (i.Key == ConsoleKey.Backspace) + { + if (result.Length > 0) + { + result = result.Substring(0, result.Length - 1); + Console.Write("\b \b"); + } + } + else + { + result += i.KeyChar; + Console.Write("*"); + } + } + Console.WriteLine(); + return result; + } + static bool SentVMMWarning = false; + static string AcceptedBadCert; + static bool BadCertificateInteractive(string message) + { + if (AcceptedBadCert == message) + return true; + Console.WriteLine(message); + Console.Write("Do you wish to continue? NOT RECCOMENDED! (y/N): "); + var result = Console.ReadLine().Trim().ToLower(); + if (result == "y" || result == "yes") + { + AcceptedBadCert = message; + return true; + } + return false; + } + + /// + /// Tries to set 's to , outputting appropriate messages + /// + /// The name of the to test + /// If , does not output on success + /// if a was achieved with , otherwise + static bool CheckInstanceConnectivity(string instanceName, bool silentSuccess) + { + var res = currentInterface.ConnectToInstance(instanceName); + if (!res.HasFlag(ConnectivityLevel.Connected)) + Console.WriteLine("Unable to connect to instance! Does it exist?"); + else if (!res.HasFlag(ConnectivityLevel.Authenticated)) + Console.WriteLine("The current user is not authorized to use this instance!"); + else + { + if(!silentSuccess) + Console.WriteLine("Successfully conected to instance!"); + return true; + } + return false; + } + + static int Main(string[] args) + { + ReplaceInterface(new ServerInterface()); + Command.OutputProcVar.Value = Console.WriteLine; + if (args.Length != 0) + { + var argsAsList = new List(args); + for (var I = 0; I < argsAsList.Count - 1; ++I) + { + if (argsAsList[I].ToLower() == "--instance") + { + if (!CheckInstanceConnectivity(args[I + 1], true)) + return (int)Command.ExitCode.ConnectionError; + argsAsList.RemoveRange(I, 2); + break; + } + else if (argsAsList[I].ToLower() == "--disable-ssl-verification") //im just not even going to document this because i hate it so much + { + argsAsList.RemoveAt(I); + --I; + ServerInterface.SetBadCertificateHandler(_ => false); + } + } + return (int)RunCommandLine(argsAsList); + } + //interactive mode + ServerInterface.SetBadCertificateHandler(BadCertificateInteractive); + Console.WriteLine("Type 'instance' to connect to a server instance"); + Console.WriteLine("Type 'remote' to connect to a remote service"); + while (true) + { + Console.Write("Enter command: "); + var NextCommand = Console.ReadLine(); + switch (NextCommand.ToLower()) + { + case "instance": + Console.Write("Enter instance name: "); + CheckInstanceConnectivity(Console.ReadLine(), false); + break; + case "remote": + SentVMMWarning = false; + Console.Write("Enter server address: "); + var address = Console.ReadLine(); + Console.Write("Enter server port: "); + ushort port; + try{ + port = Convert.ToUInt16(Console.ReadLine()); + } + catch + { + Console.WriteLine("Error: Bad port!"); + break; + } + Console.Write("Enter username: "); + var username = Console.ReadLine(); + Console.Write("Enter password: "); + var password = ReadLineSecure(); + ReplaceInterface(new ServerInterface(address, port, username, password)); + var res = currentInterface.ConnectionStatus(out string error); + if (!res.HasFlag(ConnectivityLevel.Connected)) + { + Console.WriteLine("Unable to connect: " + error); + ReplaceInterface(new ServerInterface()); + } + else if (!res.HasFlag(ConnectivityLevel.Authenticated)) + { + Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode..."); + ReplaceInterface(new ServerInterface()); + } + else + { + Console.WriteLine("Connected remotely"); + if (currentInterface.VersionMismatch(out error)) + { + SentVMMWarning = true; + Console.WriteLine(error); + } + Console.WriteLine("Type 'disconnect' to return to local mode"); + } + break; + case "disconnect": + SentVMMWarning = false; + ReplaceInterface(new ServerInterface()); + Console.WriteLine("Switch to local mode"); + break; + case "quit": + case "exit": + return (int)Command.ExitCode.Normal; +#if DEBUG + case "debug-upgrade": + currentInterface.GetComponent().PrepareForUpdate(); + return (int)Command.ExitCode.Normal; +#endif + default: + //linq voodoo to get quoted strings + var formattedCommand = NextCommand.Split('"') + .Select((element, index) => index % 2 == 0 // If even index + ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) // Split the item + : new string[] { element }) // Keep the entire item + .SelectMany(element => element).ToList(); + + formattedCommand = formattedCommand.Select(x => x.Trim()).ToList(); + formattedCommand.Remove(""); + RunCommandLine(formattedCommand); + break; + } + } + } + } +} diff --git a/TGCommandLine/Properties/AssemblyInfo.cs b/TGS.CommandLine/Properties/AssemblyInfo.cs similarity index 97% rename from TGCommandLine/Properties/AssemblyInfo.cs rename to TGS.CommandLine/Properties/AssemblyInfo.cs index 7017cbba7f..ba9129eaba 100644 --- a/TGCommandLine/Properties/AssemblyInfo.cs +++ b/TGS.CommandLine/Properties/AssemblyInfo.cs @@ -1,17 +1,17 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TGStation Server Commandline")] -[assembly: AssemblyDescription("CLI for the TG Station Server Service")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9ad1f086-a83e-4d14-a844-58a9471106b6")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TGStation Server Commandline")] +[assembly: AssemblyDescription("CLI for the TG Station Server Service")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9ad1f086-a83e-4d14-a844-58a9471106b6")] diff --git a/TGCommandLine/RepoCommands.cs b/TGS.CommandLine/RepoCommands.cs similarity index 99% rename from TGCommandLine/RepoCommands.cs rename to TGS.CommandLine/RepoCommands.cs index 9e3fe3e658..a24a26d68f 100644 --- a/TGCommandLine/RepoCommands.cs +++ b/TGS.CommandLine/RepoCommands.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class RepoCommand : RootCommand { diff --git a/TGCommandLine/RootCommands.cs b/TGS.CommandLine/RootCommands.cs similarity index 98% rename from TGCommandLine/RootCommands.cs rename to TGS.CommandLine/RootCommands.cs index 552e7b1bf7..de6edae4ac 100644 --- a/TGCommandLine/RootCommands.cs +++ b/TGS.CommandLine/RootCommands.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { class CLICommand : RootCommand { diff --git a/TGCommandLine/ServiceCommands.cs b/TGS.CommandLine/ServiceCommands.cs similarity index 97% rename from TGCommandLine/ServiceCommands.cs rename to TGS.CommandLine/ServiceCommands.cs index a52cd40dec..833469d0c8 100644 --- a/TGCommandLine/ServiceCommands.cs +++ b/TGS.CommandLine/ServiceCommands.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine +namespace TGS.CommandLine { /// /// Used for managing the components @@ -316,7 +316,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceRemoteAccessPortCommand : ConsoleCommand { @@ -343,7 +343,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceSetRemoteAccessPortCommand : ConsoleCommand { diff --git a/TGCommandLine/TGCommandLine.csproj b/TGS.CommandLine/TGS.CommandLine.csproj similarity index 92% rename from TGCommandLine/TGCommandLine.csproj rename to TGS.CommandLine/TGS.CommandLine.csproj index b228dbaccc..a4086c5979 100644 --- a/TGCommandLine/TGCommandLine.csproj +++ b/TGS.CommandLine/TGS.CommandLine.csproj @@ -6,7 +6,7 @@ AnyCPU {89191F69-B18E-4B59-B72E-E12F9B6811A0} Exe - TGCommandLine + TGS.CommandLine TGCommandLine v4.5.2 512 @@ -31,7 +31,7 @@ bin\Release\ TRACE - bin\x86\Release\TGCommandLine.xml + bin\x86\Release\TGS.CommandLine.xml true true pdbonly @@ -63,9 +63,9 @@ - + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface + TGS.Interface diff --git a/TGCommandLine/tgs.ico b/TGS.CommandLine/tgs.ico similarity index 100% rename from TGCommandLine/tgs.ico rename to TGS.CommandLine/tgs.ico diff --git a/TGControlPanel/App.config b/TGS.ControlPanel/App.config similarity index 82% rename from TGControlPanel/App.config rename to TGS.ControlPanel/App.config index 16dd5b3a27..f753d0fbb0 100644 --- a/TGControlPanel/App.config +++ b/TGS.ControlPanel/App.config @@ -3,8 +3,8 @@ -
-
+
+
@@ -13,7 +13,7 @@ - + 0 @@ -50,12 +50,12 @@ - - + + 0 - + https://github.com/tgstation/tgstation.git diff --git a/TGControlPanel/ControlPanel/ByondPage.cs b/TGS.ControlPanel/ControlPanel/ByondPage.cs similarity index 96% rename from TGControlPanel/ControlPanel/ByondPage.cs rename to TGS.ControlPanel/ControlPanel/ByondPage.cs index 1e65d7daa2..4935b7b3e4 100644 --- a/TGControlPanel/ControlPanel/ByondPage.cs +++ b/TGS.ControlPanel/ControlPanel/ByondPage.cs @@ -1,9 +1,9 @@ using System; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { partial class ControlPanel { diff --git a/TGControlPanel/ControlPanel/ChatPage.cs b/TGS.ControlPanel/ControlPanel/ChatPage.cs similarity index 98% rename from TGControlPanel/ControlPanel/ChatPage.cs rename to TGS.ControlPanel/ControlPanel/ChatPage.cs index bea75efbff..96a666d5c6 100644 --- a/TGControlPanel/ControlPanel/ChatPage.cs +++ b/TGS.ControlPanel/ControlPanel/ChatPage.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { partial class ControlPanel { diff --git a/TGControlPanel/ControlPanel/ControlPanel.Designer.cs b/TGS.ControlPanel/ControlPanel/ControlPanel.Designer.cs similarity index 99% rename from TGControlPanel/ControlPanel/ControlPanel.Designer.cs rename to TGS.ControlPanel/ControlPanel/ControlPanel.Designer.cs index 2091401f42..ba5d05108f 100644 --- a/TGControlPanel/ControlPanel/ControlPanel.Designer.cs +++ b/TGS.ControlPanel/ControlPanel/ControlPanel.Designer.cs @@ -1,4 +1,4 @@ -namespace TGControlPanel +namespace TGS.ControlPanel { partial class ControlPanel { diff --git a/TGControlPanel/ControlPanel/ControlPanel.cs b/TGS.ControlPanel/ControlPanel/ControlPanel.cs similarity index 97% rename from TGControlPanel/ControlPanel/ControlPanel.cs rename to TGS.ControlPanel/ControlPanel/ControlPanel.cs index f662e50cae..eff20b2e33 100644 --- a/TGControlPanel/ControlPanel/ControlPanel.cs +++ b/TGS.ControlPanel/ControlPanel/ControlPanel.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { /// /// The main form diff --git a/TGControlPanel/ControlPanel/ControlPanel.resx b/TGS.ControlPanel/ControlPanel/ControlPanel.resx similarity index 100% rename from TGControlPanel/ControlPanel/ControlPanel.resx rename to TGS.ControlPanel/ControlPanel/ControlPanel.resx diff --git a/TGControlPanel/ControlPanel/RepoPage.cs b/TGS.ControlPanel/ControlPanel/RepoPage.cs similarity index 99% rename from TGControlPanel/ControlPanel/RepoPage.cs rename to TGS.ControlPanel/ControlPanel/RepoPage.cs index 6e99c62277..c6b5658e9d 100644 --- a/TGControlPanel/ControlPanel/RepoPage.cs +++ b/TGS.ControlPanel/ControlPanel/RepoPage.cs @@ -2,10 +2,10 @@ using System.ComponentModel; using System.Windows.Forms; using System.Threading; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { partial class ControlPanel { diff --git a/TGControlPanel/ControlPanel/ServerPage.cs b/TGS.ControlPanel/ControlPanel/ServerPage.cs similarity index 99% rename from TGControlPanel/ControlPanel/ServerPage.cs rename to TGS.ControlPanel/ControlPanel/ServerPage.cs index 10b5363383..406b402fd4 100644 --- a/TGControlPanel/ControlPanel/ServerPage.cs +++ b/TGS.ControlPanel/ControlPanel/ServerPage.cs @@ -5,10 +5,10 @@ using System.ComponentModel; using System.Reflection; using System.Threading.Tasks; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { partial class ControlPanel { diff --git a/TGControlPanel/ControlPanel/StaticPage.cs b/TGS.ControlPanel/ControlPanel/StaticPage.cs similarity index 99% rename from TGControlPanel/ControlPanel/StaticPage.cs rename to TGS.ControlPanel/ControlPanel/StaticPage.cs index f944570837..0d53e7b680 100644 --- a/TGControlPanel/ControlPanel/StaticPage.cs +++ b/TGS.ControlPanel/ControlPanel/StaticPage.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.IO; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { partial class ControlPanel { diff --git a/TGControlPanel/CountedForm.cs b/TGS.ControlPanel/CountedForm.cs similarity index 97% rename from TGControlPanel/CountedForm.cs rename to TGS.ControlPanel/CountedForm.cs index 37d7df2607..03ac979ab5 100644 --- a/TGControlPanel/CountedForm.cs +++ b/TGS.ControlPanel/CountedForm.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace TGControlPanel +namespace TGS.ControlPanel { /// /// Calls when all s are d diff --git a/TGControlPanel/GithubLoginPrompt.Designer.cs b/TGS.ControlPanel/GithubLoginPrompt.Designer.cs similarity index 99% rename from TGControlPanel/GithubLoginPrompt.Designer.cs rename to TGS.ControlPanel/GithubLoginPrompt.Designer.cs index 04df96ab1a..6035c273a7 100644 --- a/TGControlPanel/GithubLoginPrompt.Designer.cs +++ b/TGS.ControlPanel/GithubLoginPrompt.Designer.cs @@ -1,4 +1,4 @@ -namespace TGControlPanel +namespace TGS.ControlPanel { partial class GitHubLoginPrompt { diff --git a/TGControlPanel/GithubLoginPrompt.cs b/TGS.ControlPanel/GithubLoginPrompt.cs similarity index 96% rename from TGControlPanel/GithubLoginPrompt.cs rename to TGS.ControlPanel/GithubLoginPrompt.cs index a90c7353cc..8d676d1646 100644 --- a/TGControlPanel/GithubLoginPrompt.cs +++ b/TGS.ControlPanel/GithubLoginPrompt.cs @@ -2,9 +2,9 @@ using System; using System.Threading.Tasks; using System.Windows.Forms; -using TGServiceInterface; +using TGS.Interface; -namespace TGControlPanel +namespace TGS.ControlPanel { /// /// Used for recieving a GitHub API key for use in @@ -76,7 +76,7 @@ namespace TGControlPanel try { client.Credentials = new Credentials(UsernameTextBox.Text, PasswordTextBox.Text); - var token = await client.Authorization.Create(new NewAuthorization { Note = "TGControlPanel token to bypass rate limiting" }); + var token = await client.Authorization.Create(new NewAuthorization { Note = "TGS.ControlPanel token to bypass rate limiting" }); APIKey = token.Token; } catch (AuthorizationException) diff --git a/TGControlPanel/GithubLoginPrompt.resx b/TGS.ControlPanel/GithubLoginPrompt.resx similarity index 100% rename from TGControlPanel/GithubLoginPrompt.resx rename to TGS.ControlPanel/GithubLoginPrompt.resx diff --git a/TGControlPanel/InstanceSelector.Designer.cs b/TGS.ControlPanel/InstanceSelector.Designer.cs similarity index 99% rename from TGControlPanel/InstanceSelector.Designer.cs rename to TGS.ControlPanel/InstanceSelector.Designer.cs index cfaf0a5ab5..87ce1038b7 100644 --- a/TGControlPanel/InstanceSelector.Designer.cs +++ b/TGS.ControlPanel/InstanceSelector.Designer.cs @@ -1,4 +1,4 @@ -namespace TGControlPanel +namespace TGS.ControlPanel { partial class InstanceSelector { diff --git a/TGControlPanel/InstanceSelector.cs b/TGS.ControlPanel/InstanceSelector.cs similarity index 99% rename from TGControlPanel/InstanceSelector.cs rename to TGS.ControlPanel/InstanceSelector.cs index ba46fc11f6..504b2218b9 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGS.ControlPanel/InstanceSelector.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { /// /// Form used for managing manipulation functions diff --git a/TGControlPanel/InstanceSelector.resx b/TGS.ControlPanel/InstanceSelector.resx similarity index 100% rename from TGControlPanel/InstanceSelector.resx rename to TGS.ControlPanel/InstanceSelector.resx diff --git a/TGControlPanel/Login.Designer.cs b/TGS.ControlPanel/Login.Designer.cs similarity index 99% rename from TGControlPanel/Login.Designer.cs rename to TGS.ControlPanel/Login.Designer.cs index ab89ca606b..2e7a9afbc6 100644 --- a/TGControlPanel/Login.Designer.cs +++ b/TGS.ControlPanel/Login.Designer.cs @@ -1,4 +1,4 @@ -namespace TGControlPanel +namespace TGS.ControlPanel { partial class Login { diff --git a/TGControlPanel/Login.cs b/TGS.ControlPanel/Login.cs similarity index 98% rename from TGControlPanel/Login.cs rename to TGS.ControlPanel/Login.cs index 882592d1cc..4897e5260d 100644 --- a/TGControlPanel/Login.cs +++ b/TGS.ControlPanel/Login.cs @@ -1,8 +1,8 @@ using System; using System.Windows.Forms; -using TGServiceInterface; +using TGS.Interface; -namespace TGControlPanel +namespace TGS.ControlPanel { sealed partial class Login : CountedForm { diff --git a/TGControlPanel/Login.resx b/TGS.ControlPanel/Login.resx similarity index 100% rename from TGControlPanel/Login.resx rename to TGS.ControlPanel/Login.resx diff --git a/TGControlPanel/Program.cs b/TGS.ControlPanel/Program.cs similarity index 98% rename from TGControlPanel/Program.cs rename to TGS.ControlPanel/Program.cs index 4865d338df..c0598cbdd9 100644 --- a/TGControlPanel/Program.cs +++ b/TGS.ControlPanel/Program.cs @@ -1,9 +1,9 @@ using System; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { static class Program { diff --git a/TGControlPanel/Properties/AssemblyInfo.cs b/TGS.ControlPanel/Properties/AssemblyInfo.cs similarity index 97% rename from TGControlPanel/Properties/AssemblyInfo.cs rename to TGS.ControlPanel/Properties/AssemblyInfo.cs index 8b5fb88ca1..1f05bee96e 100644 --- a/TGControlPanel/Properties/AssemblyInfo.cs +++ b/TGS.ControlPanel/Properties/AssemblyInfo.cs @@ -1,16 +1,16 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TGStation Server Control Panel")] -[assembly: AssemblyDescription("Control panel for the TG Station Server Service")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("394e7643-6b8c-416f-ab18-95ac12648cdc")] +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TGStation Server Control Panel")] +[assembly: AssemblyDescription("Control panel for the TG Station Server Service")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("394e7643-6b8c-416f-ab18-95ac12648cdc")] diff --git a/TGControlPanel/Properties/Settings.Designer.cs b/TGS.ControlPanel/Properties/Settings.Designer.cs similarity index 99% rename from TGControlPanel/Properties/Settings.Designer.cs rename to TGS.ControlPanel/Properties/Settings.Designer.cs index 86ec264975..50131930ce 100644 --- a/TGControlPanel/Properties/Settings.Designer.cs +++ b/TGS.ControlPanel/Properties/Settings.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace TGControlPanel.Properties { +namespace TGS.ControlPanel.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/TGControlPanel/Properties/Settings.settings b/TGS.ControlPanel/Properties/Settings.settings similarity index 95% rename from TGControlPanel/Properties/Settings.settings rename to TGS.ControlPanel/Properties/Settings.settings index 54c6fc8cd4..2a1efd2454 100644 --- a/TGControlPanel/Properties/Settings.settings +++ b/TGS.ControlPanel/Properties/Settings.settings @@ -1,5 +1,5 @@  - + diff --git a/TGControlPanel/ServerOpForm.cs b/TGS.ControlPanel/ServerOpForm.cs similarity index 63% rename from TGControlPanel/ServerOpForm.cs rename to TGS.ControlPanel/ServerOpForm.cs index 2a886e742d..d3843c7c2b 100644 --- a/TGControlPanel/ServerOpForm.cs +++ b/TGS.ControlPanel/ServerOpForm.cs @@ -2,10 +2,10 @@ using System.Threading.Tasks; using System.Windows.Forms; -namespace TGControlPanel +namespace TGS.ControlPanel { /// - /// Used to provide an ATP function for calls into an + /// Used to provide an ATP function for calls into an /// #if !DEBUG abstract class ServerOpForm : Form @@ -14,9 +14,9 @@ namespace TGControlPanel #endif { /// - /// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor + /// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor /// - /// The operation to wrap + /// The operation to wrap /// A wrapping protected Task WrapServerOp(Action action) { diff --git a/TGControlPanel/TGControlPanel.csproj b/TGS.ControlPanel/TGS.ControlPanel.csproj similarity index 95% rename from TGControlPanel/TGControlPanel.csproj rename to TGS.ControlPanel/TGS.ControlPanel.csproj index fb3db6a4a6..8866aebb61 100644 --- a/TGControlPanel/TGControlPanel.csproj +++ b/TGS.ControlPanel/TGS.ControlPanel.csproj @@ -6,7 +6,7 @@ AnyCPU {394E7643-6B8C-416F-AB18-95AC12648CDC} WinExe - TGControlPanel + TGS.ControlPanel TGControlPanel v4.5.2 512 @@ -30,7 +30,7 @@ bin\Release\ TRACE - bin\x86\Release\TGControlPanel.xml + bin\x86\Release\TGS.ControlPanel.xml true true pdbonly @@ -139,9 +139,9 @@ - + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface + TGS.Interface diff --git a/TGControlPanel/TestMergeManager.Designer.cs b/TGS.ControlPanel/TestMergeManager.Designer.cs similarity index 99% rename from TGControlPanel/TestMergeManager.Designer.cs rename to TGS.ControlPanel/TestMergeManager.Designer.cs index ab229d5fdd..e73ba3944e 100644 --- a/TGControlPanel/TestMergeManager.Designer.cs +++ b/TGS.ControlPanel/TestMergeManager.Designer.cs @@ -1,4 +1,4 @@ -namespace TGControlPanel +namespace TGS.ControlPanel { partial class TestMergeManager { diff --git a/TGControlPanel/TestMergeManager.cs b/TGS.ControlPanel/TestMergeManager.cs similarity index 99% rename from TGControlPanel/TestMergeManager.cs rename to TGS.ControlPanel/TestMergeManager.cs index d766e3dfe0..f609142431 100644 --- a/TGControlPanel/TestMergeManager.cs +++ b/TGS.ControlPanel/TestMergeManager.cs @@ -4,10 +4,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel +namespace TGS.ControlPanel { sealed partial class TestMergeManager : ServerOpForm { diff --git a/TGControlPanel/TestMergeManager.resx b/TGS.ControlPanel/TestMergeManager.resx similarity index 100% rename from TGControlPanel/TestMergeManager.resx rename to TGS.ControlPanel/TestMergeManager.resx diff --git a/TGControlPanel/packages.config b/TGS.ControlPanel/packages.config similarity index 100% rename from TGControlPanel/packages.config rename to TGS.ControlPanel/packages.config diff --git a/TGControlPanel/tgs.ico b/TGS.ControlPanel/tgs.ico similarity index 100% rename from TGControlPanel/tgs.ico rename to TGS.ControlPanel/tgs.ico diff --git a/TGInstallerWrapper/App.config b/TGS.Installer.UI/App.config similarity index 100% rename from TGInstallerWrapper/App.config rename to TGS.Installer.UI/App.config diff --git a/TGInstallerWrapper/FodyWeavers.xml b/TGS.Installer.UI/FodyWeavers.xml similarity index 100% rename from TGInstallerWrapper/FodyWeavers.xml rename to TGS.Installer.UI/FodyWeavers.xml diff --git a/TGInstallerWrapper/Main.Designer.cs b/TGS.Installer.UI/Main.Designer.cs similarity index 99% rename from TGInstallerWrapper/Main.Designer.cs rename to TGS.Installer.UI/Main.Designer.cs index 885db27148..0ed1cf9dec 100644 --- a/TGInstallerWrapper/Main.Designer.cs +++ b/TGS.Installer.UI/Main.Designer.cs @@ -2,7 +2,7 @@ using System.Diagnostics; using System.Reflection; -namespace TGInstallerWrapper +namespace TGS.Installer.UI { partial class Main { diff --git a/TGInstallerWrapper/Main.cs b/TGS.Installer.UI/Main.cs similarity index 90% rename from TGInstallerWrapper/Main.cs rename to TGS.Installer.UI/Main.cs index df1b275a83..745db41727 100644 --- a/TGInstallerWrapper/Main.cs +++ b/TGS.Installer.UI/Main.cs @@ -6,10 +6,10 @@ using System.IO; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGInstallerWrapper +namespace TGS.Installer.UI { partial class Main : Form { @@ -149,12 +149,12 @@ namespace TGInstallerWrapper { while (true) { - var res = PromptKillProcesses("TGCommandLine"); + var res = PromptKillProcesses("TGS.CommandLine"); if (res == PKillType.Aborted) return; else if (res == PKillType.Killed) continue; - res = PromptKillProcesses("TGControlPanel"); + res = PromptKillProcesses("TGS.ControlPanel"); if (res == PKillType.Aborted) return; else if (res == PKillType.Killed) @@ -183,8 +183,8 @@ namespace TGInstallerWrapper ShowLogCheckbox.Enabled = false; InstallButton.Text = "Installing..."; - var msipath = Path.Combine(tempDir, "TGServiceInstaller.msi"); - File.WriteAllBytes(msipath, Properties.Resources.TGServiceInstaller); + var msipath = Path.Combine(tempDir, "TGS.Installer.msi"); + File.WriteAllBytes(msipath, Properties.Resources.TGSInstaller); File.WriteAllBytes(Path.Combine(tempDir, "cab1.cab"), Properties.Resources.cab1); ProgressBar.Style = ProgressBarStyle.Marquee; @@ -193,13 +193,13 @@ namespace TGInstallerWrapper if (ShowLogCheckbox.Checked) { logfile = Path.Combine(tempDir, "tgsinstall.log"); - Installer.EnableLog(InstallLogModes.Verbose | InstallLogModes.PropertyDump, logfile); + Microsoft.Deployment.WindowsInstaller.Installer.EnableLog(InstallLogModes.Verbose | InstallLogModes.PropertyDump, logfile); } var cl = String.Join(" ", args); - Installer.SetInternalUI(InstallUIOptions.Silent); - Installer.SetExternalUI(OnUIUpdate, InstallLogModes.Progress); + Microsoft.Deployment.WindowsInstaller.Installer.SetInternalUI(InstallUIOptions.Silent); + Microsoft.Deployment.WindowsInstaller.Installer.SetExternalUI(OnUIUpdate, InstallLogModes.Progress); - await Task.Factory.StartNew(() => Installer.InstallProduct(msipath, cl)); + await Task.Factory.StartNew(() => Microsoft.Deployment.WindowsInstaller.Installer.InstallProduct(msipath, cl)); if (cancelled) { diff --git a/TGInstallerWrapper/Main.resx b/TGS.Installer.UI/Main.resx similarity index 100% rename from TGInstallerWrapper/Main.resx rename to TGS.Installer.UI/Main.resx diff --git a/TGInstallerWrapper/Program.cs b/TGS.Installer.UI/Program.cs similarity index 91% rename from TGInstallerWrapper/Program.cs rename to TGS.Installer.UI/Program.cs index 96dc421f86..851a948e3b 100644 --- a/TGInstallerWrapper/Program.cs +++ b/TGS.Installer.UI/Program.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Forms; -namespace TGInstallerWrapper +namespace TGS.Installer.UI { static class Program { diff --git a/TGInstallerWrapper/Properties/AssemblyInfo.cs b/TGS.Installer.UI/Properties/AssemblyInfo.cs similarity index 100% rename from TGInstallerWrapper/Properties/AssemblyInfo.cs rename to TGS.Installer.UI/Properties/AssemblyInfo.cs diff --git a/TGInstallerWrapper/Properties/Resources.Designer.cs b/TGS.Installer.UI/Properties/Resources.Designer.cs similarity index 91% rename from TGInstallerWrapper/Properties/Resources.Designer.cs rename to TGS.Installer.UI/Properties/Resources.Designer.cs index cd95f1bb4f..9a0670c601 100644 --- a/TGInstallerWrapper/Properties/Resources.Designer.cs +++ b/TGS.Installer.UI/Properties/Resources.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace TGInstallerWrapper.Properties { +namespace TGS.Installer.UI.Properties { using System; @@ -39,7 +39,7 @@ namespace TGInstallerWrapper.Properties { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TGInstallerWrapper.Properties.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TGS.Installer.UI.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; @@ -73,9 +73,9 @@ namespace TGInstallerWrapper.Properties { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] TGServiceInstaller { + internal static byte[] TGSInstaller { get { - object obj = ResourceManager.GetObject("TGServiceInstaller", resourceCulture); + object obj = ResourceManager.GetObject("TGSInstaller", resourceCulture); return ((byte[])(obj)); } } diff --git a/TGInstallerWrapper/Properties/Resources.resx b/TGS.Installer.UI/Properties/Resources.resx similarity index 93% rename from TGInstallerWrapper/Properties/Resources.resx rename to TGS.Installer.UI/Properties/Resources.resx index 223c76093a..7e63714e76 100644 --- a/TGInstallerWrapper/Properties/Resources.resx +++ b/TGS.Installer.UI/Properties/Resources.resx @@ -119,9 +119,9 @@ - ..\..\TGServiceInstaller\bin\Release\cab1.cab;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\..\TGS.Installer\bin\Release\cab1.cab;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\..\TGServiceInstaller\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\..\TGS.Installer\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 \ No newline at end of file diff --git a/TGInstallerWrapper/TGInstallerWrapper.csproj b/TGS.Installer.UI/TGS.Installer.UI.csproj similarity index 96% rename from TGInstallerWrapper/TGInstallerWrapper.csproj rename to TGS.Installer.UI/TGS.Installer.UI.csproj index d84f79b22a..3329911b4a 100644 --- a/TGInstallerWrapper/TGInstallerWrapper.csproj +++ b/TGS.Installer.UI/TGS.Installer.UI.csproj @@ -6,7 +6,7 @@ AnyCPU {8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9} WinExe - TGInstallerWrapper + TGS.Installer.UI TG Station Server Installer v4.5.2 512 @@ -89,9 +89,9 @@ - + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface + TGS.Interface diff --git a/TGInstallerWrapper/app.manifest b/TGS.Installer.UI/app.manifest similarity index 100% rename from TGInstallerWrapper/app.manifest rename to TGS.Installer.UI/app.manifest diff --git a/TGInstallerWrapper/packages.config b/TGS.Installer.UI/packages.config similarity index 100% rename from TGInstallerWrapper/packages.config rename to TGS.Installer.UI/packages.config diff --git a/TGInstallerWrapper/tgs.ico b/TGS.Installer.UI/tgs.ico similarity index 100% rename from TGInstallerWrapper/tgs.ico rename to TGS.Installer.UI/tgs.ico diff --git a/TGServiceInstaller/Product.wxs b/TGS.Installer/Product.wxs similarity index 71% rename from TGServiceInstaller/Product.wxs rename to TGS.Installer/Product.wxs index d188e2477d..a65794dd14 100644 --- a/TGServiceInstaller/Product.wxs +++ b/TGS.Installer/Product.wxs @@ -1,152 +1,152 @@ - - - - - - - - - - - - - - - - - - - - - Installed AND NOT UPGRADINGPRODUCTCODE - - - - - - - - - - - - - - - - - - - - - - - - - - INSTALLSHORTCUTSTART = 1 - - - - - - - - - - - INSTALLSHORTCUTDESK = 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + Installed AND NOT UPGRADINGPRODUCTCODE + + + + + + + + + + + + + + + + + + + + + + + + + + INSTALLSHORTCUTSTART = 1 + + + + + + + + + + + INSTALLSHORTCUTDESK = 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TGServiceInstaller/TGServiceInstaller.wixproj b/TGS.Installer/TGS.Installer.wixproj similarity index 85% rename from TGServiceInstaller/TGServiceInstaller.wixproj rename to TGS.Installer/TGS.Installer.wixproj index c2985570e2..6d26789638 100644 --- a/TGServiceInstaller/TGServiceInstaller.wixproj +++ b/TGS.Installer/TGS.Installer.wixproj @@ -1,90 +1,90 @@ - - - - Debug - x86 - 3.10 - 154435f6-0890-42d4-9aec-b743d4fbc1cb - 2.0 - TGServiceInstaller - Package - - - bin\$(Configuration)\ - obj\$(Configuration)\ - Debug - - - bin\$(Configuration)\ - obj\$(Configuration)\ - True - True - - - - - - - TGControlPanel - {394e7643-6b8c-416f-ab18-95ac12648cdc} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - TGCommandLine - {89191f69-b18e-4b59-b72e-e12f9b6811a0} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - TGDreamDaemonBridge - {9a01ef03-8eae-45cb-8b87-4a17bd904557} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - TGServerService - {f32eda25-0855-411c-af5e-f0d042917e2d} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - TGServiceInterface - {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - - - - - - - - - - powershell -Command "& \"$(SolutionDir)Tools/SignBasics.ps1\"" - - - powershell -Command "& \"$(SolutionDir)Tools/SignMSI.ps1\"" - - - + + + + Debug + x86 + 3.10 + 154435f6-0890-42d4-9aec-b743d4fbc1cb + 2.0 + TGServiceInstaller + Package + + + bin\$(Configuration)\ + obj\$(Configuration)\ + Debug + + + bin\$(Configuration)\ + obj\$(Configuration)\ + True + True + + + + + + + TGS.ControlPanel + {394e7643-6b8c-416f-ab18-95ac12648cdc} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + TGS.CommandLine + {89191f69-b18e-4b59-b72e-e12f9b6811a0} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + TGS.Interface.Bridge + {9a01ef03-8eae-45cb-8b87-4a17bd904557} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + TGS.Server.Service + {f32eda25-0855-411c-af5e-f0d042917e2d} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + TGS.Interface + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + + + + + + + + + + powershell -Command "& \"$(SolutionDir)Tools/SignBasics.ps1\"" + + + powershell -Command "& \"$(SolutionDir)Tools/SignMSI.ps1\"" + + + \ No newline at end of file diff --git a/TGDreamDaemonBridge/DreamDaemonBridge.cs b/TGS.Interface.Bridge/DreamDaemonBridge.cs similarity index 92% rename from TGDreamDaemonBridge/DreamDaemonBridge.cs rename to TGS.Interface.Bridge/DreamDaemonBridge.cs index 07835d4232..7a6795c39a 100644 --- a/TGDreamDaemonBridge/DreamDaemonBridge.cs +++ b/TGS.Interface.Bridge/DreamDaemonBridge.cs @@ -2,10 +2,10 @@ using RGiesecke.DllExport; using System; using System.Collections.Generic; using System.Runtime.InteropServices; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGDreamDaemonBridge +namespace TGS.Interface.Bridge { /// /// Holds the proc that DD calls to access diff --git a/TGDreamDaemonBridge/FodyWeavers.xml b/TGS.Interface.Bridge/FodyWeavers.xml similarity index 100% rename from TGDreamDaemonBridge/FodyWeavers.xml rename to TGS.Interface.Bridge/FodyWeavers.xml diff --git a/TGDreamDaemonBridge/Properties/AssemblyInfo.cs b/TGS.Interface.Bridge/Properties/AssemblyInfo.cs similarity index 100% rename from TGDreamDaemonBridge/Properties/AssemblyInfo.cs rename to TGS.Interface.Bridge/Properties/AssemblyInfo.cs diff --git a/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj b/TGS.Interface.Bridge/TGS.Interface.Bridge.csproj similarity index 95% rename from TGDreamDaemonBridge/TGDreamDaemonBridge.csproj rename to TGS.Interface.Bridge/TGS.Interface.Bridge.csproj index 0cb0c67596..d960e47808 100644 --- a/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj +++ b/TGS.Interface.Bridge/TGS.Interface.Bridge.csproj @@ -7,7 +7,7 @@ {9A01EF03-8EAE-45CB-8B87-4A17BD904557} Library Properties - TGDreamDaemonBridge + TGS.Interface.Bridge TGDreamDaemonBridge v4.5.2 512 @@ -59,9 +59,9 @@ - + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface + TGS.Interface diff --git a/TGDreamDaemonBridge/packages.config b/TGS.Interface.Bridge/packages.config similarity index 100% rename from TGDreamDaemonBridge/packages.config rename to TGS.Interface.Bridge/packages.config diff --git a/TGServiceInterface/ChatSetupInfo.cs b/TGS.Interface/ChatSetupInfo.cs similarity index 96% rename from TGServiceInterface/ChatSetupInfo.cs rename to TGS.Interface/ChatSetupInfo.cs index 1f2d0d1967..6a1c346d2b 100644 --- a/TGServiceInterface/ChatSetupInfo.cs +++ b/TGS.Interface/ChatSetupInfo.cs @@ -1,344 +1,344 @@ -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using System.Web.Script.Serialization; - -namespace TGServiceInterface -{ - /// - /// For setting up authentication no matter the chat provider - /// - [DataContract] - [KnownType(typeof(IRCSetupInfo))] - [KnownType(typeof(DiscordSetupInfo))] - public class ChatSetupInfo - { - const int AdminListIndex = 0; - const int AdminModeIndex = 1; - const int AdminChannelIndex = 2; - const int DevChannelIndex = 3; - const int WDChannelIndex = 4; - const int GameChannelIndex = 5; - const int ProviderIndex = 6; - const int EnabledIndex = 7; - /// - /// Starting index of which child classes should use to write their custom data to - /// - protected const int BaseIndex = 8; - /// - /// Set to if a child constructor should use the baseInfo parameter of to initialize it's property fields, otherwise - /// - protected readonly bool InitializeFields; - - /// - /// Raw access to the underlying data - /// - [DataMember] - public IList DataFields { get; protected set; } - - /// - /// Constructs a from optional - /// - /// The that this is for - /// Optional past data - /// The number of fields in this chat provider - protected internal ChatSetupInfo(ChatProvider provider, ChatSetupInfo baseInfo, int numFields) - { - numFields += BaseIndex; - InitializeFields = baseInfo == null || baseInfo.DataFields.Count != numFields; - - if (InitializeFields) - { - DataFields = new List(numFields); - for (var I = 0; I < numFields; ++I) - DataFields.Add(null); - - AdminList = new List(); - AdminChannels = new List(); - DevChannels = new List(); - GameChannels = new List(); - WatchdogChannels = new List(); - AdminsAreSpecial = false; - Enabled = false; - } - else - DataFields = baseInfo.DataFields; - Provider = provider; - Specialize(true); //to check we have a valid provider - } - - /// - /// Recreates as the correct child - /// - /// If , is returned provided is a valid - /// A new based on the type - ChatSetupInfo Specialize(bool checkOnly) - { - switch (Provider) - { - case ChatProvider.IRC: - if (!checkOnly) - return new IRCSetupInfo(this); - break; - case ChatProvider.Discord: - if (!checkOnly) - return new DiscordSetupInfo(this); - break; - default: - throw new Exception("Invalid provider!"); - } - return null; - } - - /// - /// Properly formats a name for the - /// - /// The to format - /// The formatted - protected virtual string SanitizeChannelName(string channel) - { - return Specialize(false).SanitizeChannelName(channel); - } - - /// - /// Sanitizes a list of - /// - /// A of strings - void SanitizeChannelNames(IList channelnames) - { - for (var I = 0; I < channelnames.Count; ++I) - - if (String.IsNullOrWhiteSpace(channelnames[I])) - { - channelnames.RemoveAt(I); - --I; - } - else - channelnames[I] = SanitizeChannelName(channelnames[I].Trim()); - } - - /// - /// Constructs a from a data list - /// - /// The data - public ChatSetupInfo(IList DeserializedData) - { - DataFields = DeserializedData; - Specialize(false); //ensure provider type is valid - } - /// - /// The list of admin entries - /// - public List AdminList - { - get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminListIndex]); } - set { DataFields[AdminListIndex] = new JavaScriptSerializer().Serialize(value); } - } - /// - /// If AdminList corresponds to a Provider specific recognization method - /// - public bool AdminsAreSpecial - { - get { return Convert.ToBoolean(DataFields[AdminModeIndex]); } - set { DataFields[AdminModeIndex] = Convert.ToString(value); } - } - /// - /// The channels from which admin commands/messages can be sent/received - /// - public List AdminChannels - { - get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminChannelIndex]); } - set - { - SanitizeChannelNames(value); - DataFields[AdminChannelIndex] = new JavaScriptSerializer().Serialize(value); - } - } - /// - /// The channels to which repo and compile messages are sent - /// - public List DevChannels - { - get { return new JavaScriptSerializer().Deserialize>(DataFields[DevChannelIndex]); } - set - { - SanitizeChannelNames(value); - DataFields[DevChannelIndex] = new JavaScriptSerializer().Serialize(value); - } - } - /// - /// The channels to which watchdog messages are sent - /// - public List WatchdogChannels - { - get { return new JavaScriptSerializer().Deserialize>(DataFields[WDChannelIndex]); } - set - { - SanitizeChannelNames(value); - DataFields[WDChannelIndex] = new JavaScriptSerializer().Serialize(value); - } - } - /// - /// The channels to which game messages are sent - /// - public List GameChannels - { - get { return new JavaScriptSerializer().Deserialize>(DataFields[GameChannelIndex]); } - set - { - SanitizeChannelNames(value); - DataFields[GameChannelIndex] = new JavaScriptSerializer().Serialize(value); - } - } - /// - /// If this chat provider is enabled - /// - public bool Enabled - { - get { return Convert.ToBoolean(DataFields[EnabledIndex]); } - set { DataFields[EnabledIndex] = Convert.ToString(value); } - } - - /// - /// The type of provider - /// - public ChatProvider Provider - { - get { return (ChatProvider)Convert.ToInt32(DataFields[ProviderIndex]); } - set { DataFields[ProviderIndex] = Convert.ToString((int)value); } - } - } - - /// - /// Chat provider for IRC. Admin entries should be user nicknames in normal mode or required channel flags in special mode - /// - [DataContract] - public sealed class IRCSetupInfo : ChatSetupInfo - { - const int URLIndex = 0; - const int PortIndex = 1; - const int NickIndex = 2; - const int AuthTargetIndex = 3; - const int AuthMessageIndex = 4; - const int AuthLevelIndex = 5; - const int FieldsLen = 6; - - /// - /// Construct IRC setup info from optional generic info. Defaults to TGS3 on rizons IRC server - /// - /// Optional generic info - public IRCSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.IRC, baseInfo, FieldsLen) - { - if (!InitializeFields) - return; - - Nickname = "TGS3"; - URL = "irc.rizon.net"; - Port = 6667; - AuthTarget = ""; - AuthMessage = ""; - AdminsAreSpecial = true; - AuthLevel = IRCMode.Op; - } - - /// - protected override string SanitizeChannelName(string working) - { - if (working[0] != '#') - return "#" + working; - return working; - } - - /// - /// The port of the IRC server - /// - public ushort Port - { - get { return Convert.ToUInt16(DataFields[BaseIndex + PortIndex]); } - set { DataFields[BaseIndex + PortIndex] = value.ToString(); } - } - /// - /// The URL of the IRC server - /// - public string URL - { - get { return DataFields[BaseIndex + URLIndex]; } - set { DataFields[BaseIndex + URLIndex] = value; } - } - /// - /// The nickname of the IRC bot - /// - public string Nickname - { - get { return DataFields[BaseIndex + NickIndex]; } - set { DataFields[BaseIndex + NickIndex] = value; } - } - /// - /// The target for sending authentication messages - /// - public string AuthTarget - { - get { return DataFields[BaseIndex + AuthTargetIndex]; } - set { DataFields[BaseIndex + AuthTargetIndex] = value; } - } - /// - /// The authentication message - /// - public string AuthMessage - { - get { return DataFields[BaseIndex + AuthMessageIndex]; } - set { DataFields[BaseIndex + AuthMessageIndex] = value; } - } - /// - /// The minimum mode required to use admin bot commands when in special auth mode - /// - public IRCMode AuthLevel - { - get { return (IRCMode)Convert.ToInt32(DataFields[BaseIndex + AuthLevelIndex]); } - set { DataFields[BaseIndex + AuthLevelIndex] = Convert.ToString((int)value); } - } - } - - /// - /// Chat provider for Discord. Admin entires should be user ids in normal mode or group ids in special mode - /// - [DataContract] - public sealed class DiscordSetupInfo : ChatSetupInfo - { - const int BotTokenIndex = 0; - const int FieldsLen = 1; - /// - /// Construct Discord setup info from optional generic info. Default is not a valid discord bot tokent - /// - /// Optional generic info - public DiscordSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.Discord, baseInfo, FieldsLen) - { - if (!InitializeFields) - return; - BotToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //needless to say, this is fake - } - /// - protected override string SanitizeChannelName(string working) - { - working = working.Replace("<", "").Replace(">", "").Replace("&", ""); //filter out some stuff that can come in the copypasta - try - { - Convert.ToUInt64(working); - } - catch - { - throw new Exception("Invalid Discord channel ID!"); - } - return working; - } - - /// - /// The Discord bot token to use. See https://discordapp.com/developers/applications/me for registering bot accounts - /// - public string BotToken - { - get { return DataFields[BaseIndex + BotTokenIndex]; } - set { DataFields[BaseIndex + BotTokenIndex] = value; } - } - } -} +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Web.Script.Serialization; + +namespace TGS.Interface +{ + /// + /// For setting up authentication no matter the chat provider + /// + [DataContract] + [KnownType(typeof(IRCSetupInfo))] + [KnownType(typeof(DiscordSetupInfo))] + public class ChatSetupInfo + { + const int AdminListIndex = 0; + const int AdminModeIndex = 1; + const int AdminChannelIndex = 2; + const int DevChannelIndex = 3; + const int WDChannelIndex = 4; + const int GameChannelIndex = 5; + const int ProviderIndex = 6; + const int EnabledIndex = 7; + /// + /// Starting index of which child classes should use to write their custom data to + /// + protected const int BaseIndex = 8; + /// + /// Set to if a child constructor should use the baseInfo parameter of to initialize it's property fields, otherwise + /// + protected readonly bool InitializeFields; + + /// + /// Raw access to the underlying data + /// + [DataMember] + public IList DataFields { get; protected set; } + + /// + /// Constructs a from optional + /// + /// The that this is for + /// Optional past data + /// The number of fields in this chat provider + protected internal ChatSetupInfo(ChatProvider provider, ChatSetupInfo baseInfo, int numFields) + { + numFields += BaseIndex; + InitializeFields = baseInfo == null || baseInfo.DataFields.Count != numFields; + + if (InitializeFields) + { + DataFields = new List(numFields); + for (var I = 0; I < numFields; ++I) + DataFields.Add(null); + + AdminList = new List(); + AdminChannels = new List(); + DevChannels = new List(); + GameChannels = new List(); + WatchdogChannels = new List(); + AdminsAreSpecial = false; + Enabled = false; + } + else + DataFields = baseInfo.DataFields; + Provider = provider; + Specialize(true); //to check we have a valid provider + } + + /// + /// Recreates as the correct child + /// + /// If , is returned provided is a valid + /// A new based on the type + ChatSetupInfo Specialize(bool checkOnly) + { + switch (Provider) + { + case ChatProvider.IRC: + if (!checkOnly) + return new IRCSetupInfo(this); + break; + case ChatProvider.Discord: + if (!checkOnly) + return new DiscordSetupInfo(this); + break; + default: + throw new Exception("Invalid provider!"); + } + return null; + } + + /// + /// Properly formats a name for the + /// + /// The to format + /// The formatted + protected virtual string SanitizeChannelName(string channel) + { + return Specialize(false).SanitizeChannelName(channel); + } + + /// + /// Sanitizes a list of + /// + /// A of strings + void SanitizeChannelNames(IList channelnames) + { + for (var I = 0; I < channelnames.Count; ++I) + + if (String.IsNullOrWhiteSpace(channelnames[I])) + { + channelnames.RemoveAt(I); + --I; + } + else + channelnames[I] = SanitizeChannelName(channelnames[I].Trim()); + } + + /// + /// Constructs a from a data list + /// + /// The data + public ChatSetupInfo(IList DeserializedData) + { + DataFields = DeserializedData; + Specialize(false); //ensure provider type is valid + } + /// + /// The list of admin entries + /// + public List AdminList + { + get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminListIndex]); } + set { DataFields[AdminListIndex] = new JavaScriptSerializer().Serialize(value); } + } + /// + /// If AdminList corresponds to a Provider specific recognization method + /// + public bool AdminsAreSpecial + { + get { return Convert.ToBoolean(DataFields[AdminModeIndex]); } + set { DataFields[AdminModeIndex] = Convert.ToString(value); } + } + /// + /// The channels from which admin commands/messages can be sent/received + /// + public List AdminChannels + { + get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminChannelIndex]); } + set + { + SanitizeChannelNames(value); + DataFields[AdminChannelIndex] = new JavaScriptSerializer().Serialize(value); + } + } + /// + /// The channels to which repo and compile messages are sent + /// + public List DevChannels + { + get { return new JavaScriptSerializer().Deserialize>(DataFields[DevChannelIndex]); } + set + { + SanitizeChannelNames(value); + DataFields[DevChannelIndex] = new JavaScriptSerializer().Serialize(value); + } + } + /// + /// The channels to which watchdog messages are sent + /// + public List WatchdogChannels + { + get { return new JavaScriptSerializer().Deserialize>(DataFields[WDChannelIndex]); } + set + { + SanitizeChannelNames(value); + DataFields[WDChannelIndex] = new JavaScriptSerializer().Serialize(value); + } + } + /// + /// The channels to which game messages are sent + /// + public List GameChannels + { + get { return new JavaScriptSerializer().Deserialize>(DataFields[GameChannelIndex]); } + set + { + SanitizeChannelNames(value); + DataFields[GameChannelIndex] = new JavaScriptSerializer().Serialize(value); + } + } + /// + /// If this chat provider is enabled + /// + public bool Enabled + { + get { return Convert.ToBoolean(DataFields[EnabledIndex]); } + set { DataFields[EnabledIndex] = Convert.ToString(value); } + } + + /// + /// The type of provider + /// + public ChatProvider Provider + { + get { return (ChatProvider)Convert.ToInt32(DataFields[ProviderIndex]); } + set { DataFields[ProviderIndex] = Convert.ToString((int)value); } + } + } + + /// + /// Chat provider for IRC. Admin entries should be user nicknames in normal mode or required channel flags in special mode + /// + [DataContract] + public sealed class IRCSetupInfo : ChatSetupInfo + { + const int URLIndex = 0; + const int PortIndex = 1; + const int NickIndex = 2; + const int AuthTargetIndex = 3; + const int AuthMessageIndex = 4; + const int AuthLevelIndex = 5; + const int FieldsLen = 6; + + /// + /// Construct IRC setup info from optional generic info. Defaults to TGS3 on rizons IRC server + /// + /// Optional generic info + public IRCSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.IRC, baseInfo, FieldsLen) + { + if (!InitializeFields) + return; + + Nickname = "TGS3"; + URL = "irc.rizon.net"; + Port = 6667; + AuthTarget = ""; + AuthMessage = ""; + AdminsAreSpecial = true; + AuthLevel = IRCMode.Op; + } + + /// + protected override string SanitizeChannelName(string working) + { + if (working[0] != '#') + return "#" + working; + return working; + } + + /// + /// The port of the IRC server + /// + public ushort Port + { + get { return Convert.ToUInt16(DataFields[BaseIndex + PortIndex]); } + set { DataFields[BaseIndex + PortIndex] = value.ToString(); } + } + /// + /// The URL of the IRC server + /// + public string URL + { + get { return DataFields[BaseIndex + URLIndex]; } + set { DataFields[BaseIndex + URLIndex] = value; } + } + /// + /// The nickname of the IRC bot + /// + public string Nickname + { + get { return DataFields[BaseIndex + NickIndex]; } + set { DataFields[BaseIndex + NickIndex] = value; } + } + /// + /// The target for sending authentication messages + /// + public string AuthTarget + { + get { return DataFields[BaseIndex + AuthTargetIndex]; } + set { DataFields[BaseIndex + AuthTargetIndex] = value; } + } + /// + /// The authentication message + /// + public string AuthMessage + { + get { return DataFields[BaseIndex + AuthMessageIndex]; } + set { DataFields[BaseIndex + AuthMessageIndex] = value; } + } + /// + /// The minimum mode required to use admin bot commands when in special auth mode + /// + public IRCMode AuthLevel + { + get { return (IRCMode)Convert.ToInt32(DataFields[BaseIndex + AuthLevelIndex]); } + set { DataFields[BaseIndex + AuthLevelIndex] = Convert.ToString((int)value); } + } + } + + /// + /// Chat provider for Discord. Admin entires should be user ids in normal mode or group ids in special mode + /// + [DataContract] + public sealed class DiscordSetupInfo : ChatSetupInfo + { + const int BotTokenIndex = 0; + const int FieldsLen = 1; + /// + /// Construct Discord setup info from optional generic info. Default is not a valid discord bot tokent + /// + /// Optional generic info + public DiscordSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.Discord, baseInfo, FieldsLen) + { + if (!InitializeFields) + return; + BotToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //needless to say, this is fake + } + /// + protected override string SanitizeChannelName(string working) + { + working = working.Replace("<", "").Replace(">", "").Replace("&", ""); //filter out some stuff that can come in the copypasta + try + { + Convert.ToUInt64(working); + } + catch + { + throw new Exception("Invalid Discord channel ID!"); + } + return working; + } + + /// + /// The Discord bot token to use. See https://discordapp.com/developers/applications/me for registering bot accounts + /// + public string BotToken + { + get { return DataFields[BaseIndex + BotTokenIndex]; } + set { DataFields[BaseIndex + BotTokenIndex] = value; } + } + } +} diff --git a/TGServiceInterface/Command.cs b/TGS.Interface/Command.cs similarity index 99% rename from TGServiceInterface/Command.cs rename to TGS.Interface/Command.cs index 5355a0d55e..ac64ab1914 100644 --- a/TGServiceInterface/Command.cs +++ b/TGS.Interface/Command.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Helper for creating a text tree diff --git a/TGServiceInterface/Components/Administration.cs b/TGS.Interface/Components/Administration.cs similarity index 97% rename from TGServiceInterface/Components/Administration.cs rename to TGS.Interface/Components/Administration.cs index b177312820..884c5b725a 100644 --- a/TGServiceInterface/Components/Administration.cs +++ b/TGS.Interface/Components/Administration.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Manage the group that is used to access the service, can only be used by an administrator diff --git a/TGServiceInterface/Components/Byond.cs b/TGS.Interface/Components/Byond.cs similarity index 97% rename from TGServiceInterface/Components/Byond.cs rename to TGS.Interface/Components/Byond.cs index d640179d6c..7563000999 100644 --- a/TGServiceInterface/Components/Byond.cs +++ b/TGS.Interface/Components/Byond.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// diff --git a/TGServiceInterface/Components/Chat.cs b/TGS.Interface/Components/Chat.cs similarity index 97% rename from TGServiceInterface/Components/Chat.cs rename to TGS.Interface/Components/Chat.cs index e52659d3f7..5333e4e649 100644 --- a/TGServiceInterface/Components/Chat.cs +++ b/TGS.Interface/Components/Chat.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Interface for handling chat bot diff --git a/TGServiceInterface/Components/Compiler.cs b/TGS.Interface/Components/Compiler.cs similarity index 98% rename from TGServiceInterface/Components/Compiler.cs rename to TGS.Interface/Components/Compiler.cs index f5b261fb62..ce87ff125e 100644 --- a/TGServiceInterface/Components/Compiler.cs +++ b/TGS.Interface/Components/Compiler.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// For managing the Game A/B/Live folders, compiling, and hotswapping them diff --git a/TGServiceInterface/Components/Config.cs b/TGS.Interface/Components/Config.cs similarity index 98% rename from TGServiceInterface/Components/Config.cs rename to TGS.Interface/Components/Config.cs index 1055352aad..5b33051d0d 100644 --- a/TGServiceInterface/Components/Config.cs +++ b/TGS.Interface/Components/Config.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// For modifying the in game config diff --git a/TGServiceInterface/Components/Connectivity.cs b/TGS.Interface/Components/Connectivity.cs similarity index 91% rename from TGServiceInterface/Components/Connectivity.cs rename to TGS.Interface/Components/Connectivity.cs index d3077d3dd9..d7c5b57f64 100644 --- a/TGServiceInterface/Components/Connectivity.cs +++ b/TGS.Interface/Components/Connectivity.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Used for testing connections to the service without authentication diff --git a/TGServiceInterface/Components/DreamDaemon.cs b/TGS.Interface/Components/DreamDaemon.cs similarity index 99% rename from TGServiceInterface/Components/DreamDaemon.cs rename to TGS.Interface/Components/DreamDaemon.cs index b21fdda493..0892e3f8a1 100644 --- a/TGServiceInterface/Components/DreamDaemon.cs +++ b/TGS.Interface/Components/DreamDaemon.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// diff --git a/TGServiceInterface/Components/Instance.cs b/TGS.Interface/Components/Instance.cs similarity index 93% rename from TGServiceInterface/Components/Instance.cs rename to TGS.Interface/Components/Instance.cs index c4c771d4ef..1cc79e153b 100644 --- a/TGServiceInterface/Components/Instance.cs +++ b/TGS.Interface/Components/Instance.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Metadata for a server instance diff --git a/TGServiceInterface/Components/InstanceManager.cs b/TGS.Interface/Components/InstanceManager.cs similarity index 98% rename from TGServiceInterface/Components/InstanceManager.cs rename to TGS.Interface/Components/InstanceManager.cs index 3467c009c1..f148acb644 100644 --- a/TGServiceInterface/Components/InstanceManager.cs +++ b/TGS.Interface/Components/InstanceManager.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Used for managing s diff --git a/TGServiceInterface/Components/Interop.cs b/TGS.Interface/Components/Interop.cs similarity index 93% rename from TGServiceInterface/Components/Interop.cs rename to TGS.Interface/Components/Interop.cs index e57e74cb08..80dc2c7c7c 100644 --- a/TGServiceInterface/Components/Interop.cs +++ b/TGS.Interface/Components/Interop.cs @@ -1,6 +1,6 @@ using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Used by DreamDaemon to access the interop API with call()(). Restrictions are in place so that only a DreamDaemon instance launched by the service can use this API diff --git a/TGServiceInterface/Components/Landing.cs b/TGS.Interface/Components/Landing.cs similarity index 94% rename from TGServiceInterface/Components/Landing.cs rename to TGS.Interface/Components/Landing.cs index a1d18c8c88..da7cd28b9e 100644 --- a/TGServiceInterface/Components/Landing.cs +++ b/TGS.Interface/Components/Landing.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Used for general authentication and listing s diff --git a/TGServiceInterface/Components/Repository.cs b/TGS.Interface/Components/Repository.cs similarity index 99% rename from TGServiceInterface/Components/Repository.cs rename to TGS.Interface/Components/Repository.cs index 9e0f83105e..f9a395a915 100644 --- a/TGServiceInterface/Components/Repository.cs +++ b/TGS.Interface/Components/Repository.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Interface for managing the code repository diff --git a/TGServiceInterface/Components/Service.cs b/TGS.Interface/Components/Service.cs similarity index 97% rename from TGServiceInterface/Components/Service.cs rename to TGS.Interface/Components/Service.cs index d9fecd397f..17fc5f7096 100644 --- a/TGServiceInterface/Components/Service.cs +++ b/TGS.Interface/Components/Service.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ServiceModel; -namespace TGServiceInterface.Components +namespace TGS.Interface.Components { /// /// Interface for managing the service diff --git a/TGServiceInterface/Enumerations.cs b/TGS.Interface/Enumerations.cs similarity index 99% rename from TGServiceInterface/Enumerations.cs rename to TGS.Interface/Enumerations.cs index 5f65b463b0..b1d9586769 100644 --- a/TGServiceInterface/Enumerations.cs +++ b/TGS.Interface/Enumerations.cs @@ -1,6 +1,6 @@ using System; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Description of the connectivity level to an or the diff --git a/TGServiceInterface/Helpers.cs b/TGS.Interface/Helpers.cs similarity index 98% rename from TGServiceInterface/Helpers.cs rename to TGS.Interface/Helpers.cs index 471d84ccfd..a7780a1aba 100644 --- a/TGServiceInterface/Helpers.cs +++ b/TGS.Interface/Helpers.cs @@ -2,7 +2,7 @@ using System.Security.Cryptography; using System.Text; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Helper functions used across the server suite diff --git a/TGServiceInterface/InstanceMetadata.cs b/TGS.Interface/InstanceMetadata.cs similarity index 96% rename from TGServiceInterface/InstanceMetadata.cs rename to TGS.Interface/InstanceMetadata.cs index 5a08e5b355..d98677bbe6 100644 --- a/TGServiceInterface/InstanceMetadata.cs +++ b/TGS.Interface/InstanceMetadata.cs @@ -1,6 +1,6 @@ using System.Runtime.Serialization; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Metadata about an diff --git a/TGServiceInterface/Properties/AssemblyInfo.cs b/TGS.Interface/Properties/AssemblyInfo.cs similarity index 98% rename from TGServiceInterface/Properties/AssemblyInfo.cs rename to TGS.Interface/Properties/AssemblyInfo.cs index 1e86b8b310..c9d6fe7641 100644 --- a/TGServiceInterface/Properties/AssemblyInfo.cs +++ b/TGS.Interface/Properties/AssemblyInfo.cs @@ -1,16 +1,16 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TGStation Server Service Interface")] -[assembly: AssemblyDescription("Used by user programs to access the TGStation Server Service")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab")] +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TGStation Server Service Interface")] +[assembly: AssemblyDescription("Used by user programs to access the TGStation Server Service")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab")] diff --git a/TGServiceInterface/PullRequestInfo.cs b/TGS.Interface/PullRequestInfo.cs similarity index 97% rename from TGServiceInterface/PullRequestInfo.cs rename to TGS.Interface/PullRequestInfo.cs index 6f6635ab7b..58eab112ff 100644 --- a/TGServiceInterface/PullRequestInfo.cs +++ b/TGS.Interface/PullRequestInfo.cs @@ -1,6 +1,6 @@ using System.Runtime.Serialization; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Information about a pull request diff --git a/TGServiceInterface/RootCommand.cs b/TGS.Interface/RootCommand.cs similarity index 99% rename from TGServiceInterface/RootCommand.cs rename to TGS.Interface/RootCommand.cs index 90b26f352e..129c772478 100644 --- a/TGServiceInterface/RootCommand.cs +++ b/TGS.Interface/RootCommand.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Helper for creating commands that contain sub commands diff --git a/TGServiceInterface/ServerInterface.cs b/TGS.Interface/ServerInterface.cs similarity index 99% rename from TGServiceInterface/ServerInterface.cs rename to TGS.Interface/ServerInterface.cs index 62608e7cf9..e92e630e19 100644 --- a/TGServiceInterface/ServerInterface.cs +++ b/TGS.Interface/ServerInterface.cs @@ -7,9 +7,9 @@ using System.Net.Security; using System.Reflection; using System.Security.Principal; using System.ServiceModel; -using TGServiceInterface.Components; +using TGS.Interface.Components; -namespace TGServiceInterface +namespace TGS.Interface { /// /// Main for communicating the diff --git a/TGServiceInterface/TGServiceInterface.csproj b/TGS.Interface/TGS.Interface.csproj similarity index 92% rename from TGServiceInterface/TGServiceInterface.csproj rename to TGS.Interface/TGS.Interface.csproj index c5a0a379a6..fa07f5838f 100644 --- a/TGServiceInterface/TGServiceInterface.csproj +++ b/TGS.Interface/TGS.Interface.csproj @@ -1,81 +1,81 @@ - - - - - Debug - AnyCPU - {AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB} - Library - Properties - TGServiceInterface - TGServiceInterface - v4.5.2 - 512 - - - tgs.ico - - - true - bin\Debug\ - DEBUG;TRACE - full - AnyCPU - prompt - MinimumRecommendedRules.ruleset - - - bin\Release\ - TRACE - bin\x86\Release\TGServiceInterface.xml - true - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + AnyCPU + {AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB} + Library + Properties + TGS.Interface + TGServiceInterface + v4.5.2 + 512 + + + tgs.ico + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\ + TRACE + bin\x86\Release\TGS.Interface.xml + true + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TGServiceInterface/TGServiceInterface.nuspec b/TGS.Interface/TGS.Interface.nuspec similarity index 96% rename from TGServiceInterface/TGServiceInterface.nuspec rename to TGS.Interface/TGS.Interface.nuspec index 44637c7556..80bbf50f80 100644 --- a/TGServiceInterface/TGServiceInterface.nuspec +++ b/TGS.Interface/TGS.Interface.nuspec @@ -1,7 +1,7 @@ - $id$ + TGServiceInterface $version$ Cyberboss https://github.com/tgstation/tgstation-server/blob/master/LICENSE diff --git a/TGServerService/tgs.ico b/TGS.Interface/tgs.ico similarity index 100% rename from TGServerService/tgs.ico rename to TGS.Interface/tgs.ico diff --git a/TGServerService/App.config b/TGS.Server.Service/App.config similarity index 60% rename from TGServerService/App.config rename to TGS.Server.Service/App.config index 42fede526f..cfd0a6b77d 100644 --- a/TGServerService/App.config +++ b/TGS.Server.Service/App.config @@ -2,15 +2,15 @@ -
-
+
+
- + C:\Python27 @@ -23,6 +23,6 @@ 38607 - + diff --git a/TGServerService/ChatCommands/ByondCommand.cs b/TGS.Server.Service/ChatCommands/ByondCommand.cs similarity index 93% rename from TGServerService/ChatCommands/ByondCommand.cs rename to TGS.Server.Service/ChatCommands/ByondCommand.cs index 27cd19dadf..5cc1a90740 100644 --- a/TGServerService/ChatCommands/ByondCommand.cs +++ b/TGS.Server.Service/ChatCommands/ByondCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using TGServiceInterface; +using TGS.Interface; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// Retrieve the installed, staged, or latest availab diff --git a/TGServerService/ChatCommands/ChatCommand.cs b/TGS.Server.Service/ChatCommands/ChatCommand.cs similarity index 95% rename from TGServerService/ChatCommands/ChatCommand.cs rename to TGS.Server.Service/ChatCommands/ChatCommand.cs index 17794613fa..7137fa0447 100644 --- a/TGServerService/ChatCommands/ChatCommand.cs +++ b/TGS.Server.Service/ChatCommands/ChatCommand.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Threading; -using TGServiceInterface; +using TGS.Interface; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// A command heard by a diff --git a/TGServerService/ChatCommands/CommandInfo.cs b/TGS.Server.Service/ChatCommands/CommandInfo.cs similarity index 94% rename from TGServerService/ChatCommands/CommandInfo.cs rename to TGS.Server.Service/ChatCommands/CommandInfo.cs index 913bd50e70..bc6ae15eed 100644 --- a/TGServerService/ChatCommands/CommandInfo.cs +++ b/TGS.Server.Service/ChatCommands/CommandInfo.cs @@ -1,4 +1,4 @@ -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// Metadata about the currently running diff --git a/TGServerService/ChatCommands/KekCommand.cs b/TGS.Server.Service/ChatCommands/KekCommand.cs similarity index 91% rename from TGServerService/ChatCommands/KekCommand.cs rename to TGS.Server.Service/ChatCommands/KekCommand.cs index 1c2eda51c6..6fe495690c 100644 --- a/TGServerService/ChatCommands/KekCommand.cs +++ b/TGS.Server.Service/ChatCommands/KekCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// kek diff --git a/TGServerService/ChatCommands/PullRequestsCommand.cs b/TGS.Server.Service/ChatCommands/PullRequestsCommand.cs similarity index 95% rename from TGServerService/ChatCommands/PullRequestsCommand.cs rename to TGS.Server.Service/ChatCommands/PullRequestsCommand.cs index 50495174c5..f3046931cc 100644 --- a/TGServerService/ChatCommands/PullRequestsCommand.cs +++ b/TGS.Server.Service/ChatCommands/PullRequestsCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// Retrieve the list of test-merged github pull requests diff --git a/TGServerService/ChatCommands/RevisionCommand.cs b/TGS.Server.Service/ChatCommands/RevisionCommand.cs similarity index 94% rename from TGServerService/ChatCommands/RevisionCommand.cs rename to TGS.Server.Service/ChatCommands/RevisionCommand.cs index 18b28b96ac..3b91cdebd9 100644 --- a/TGServerService/ChatCommands/RevisionCommand.cs +++ b/TGS.Server.Service/ChatCommands/RevisionCommand.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// Retrieves the git SHA of the live DreamDaemon code diff --git a/TGServerService/ChatCommands/RootChatCommand.cs b/TGS.Server.Service/ChatCommands/RootChatCommand.cs similarity index 91% rename from TGServerService/ChatCommands/RootChatCommand.cs rename to TGS.Server.Service/ChatCommands/RootChatCommand.cs index 82bb3e172e..1fac6ee2ce 100644 --- a/TGServerService/ChatCommands/RootChatCommand.cs +++ b/TGS.Server.Service/ChatCommands/RootChatCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using TGServiceInterface; +using TGS.Interface; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// The main root chat command diff --git a/TGServerService/ChatCommands/ServerChatCommand.cs b/TGS.Server.Service/ChatCommands/ServerChatCommand.cs similarity index 97% rename from TGServerService/ChatCommands/ServerChatCommand.cs rename to TGS.Server.Service/ChatCommands/ServerChatCommand.cs index f7551e60af..0729409c1e 100644 --- a/TGServerService/ChatCommands/ServerChatCommand.cs +++ b/TGS.Server.Service/ChatCommands/ServerChatCommand.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// s generated by DreamDaemon via the API diff --git a/TGServerService/ChatCommands/VersionCommand.cs b/TGS.Server.Service/ChatCommands/VersionCommand.cs similarity index 93% rename from TGServerService/ChatCommands/VersionCommand.cs rename to TGS.Server.Service/ChatCommands/VersionCommand.cs index d066d83971..afbd926c02 100644 --- a/TGServerService/ChatCommands/VersionCommand.cs +++ b/TGS.Server.Service/ChatCommands/VersionCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TGServerService.ChatCommands +namespace TGS.Server.Service.ChatCommands { /// /// Retrieve the current service version diff --git a/TGServerService/ChatProviders/ChatProvider.cs b/TGS.Server.Service/ChatProviders/ChatProvider.cs similarity index 97% rename from TGServerService/ChatProviders/ChatProvider.cs rename to TGS.Server.Service/ChatProviders/ChatProvider.cs index da6ff62999..dbcf6d14d7 100644 --- a/TGServerService/ChatProviders/ChatProvider.cs +++ b/TGS.Server.Service/ChatProviders/ChatProvider.cs @@ -1,7 +1,7 @@ using System; -using TGServiceInterface; +using TGS.Interface; -namespace TGServerService.ChatProviders +namespace TGS.Server.Service.ChatProviders { /// /// Callback for the chat provider recieving a diff --git a/TGServerService/ChatProviders/DiscordChatProvider.cs b/TGS.Server.Service/ChatProviders/DiscordChatProvider.cs similarity index 99% rename from TGServerService/ChatProviders/DiscordChatProvider.cs rename to TGS.Server.Service/ChatProviders/DiscordChatProvider.cs index 1b347b0de2..1b2a936cb5 100644 --- a/TGServerService/ChatProviders/DiscordChatProvider.cs +++ b/TGS.Server.Service/ChatProviders/DiscordChatProvider.cs @@ -4,9 +4,9 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using TGServiceInterface; +using TGS.Interface; -namespace TGServerService.ChatProviders +namespace TGS.Server.Service.ChatProviders { /// /// for Discord: https://discordapp.com/ diff --git a/TGServerService/ChatProviders/IRCChatProvider.cs b/TGS.Server.Service/ChatProviders/IRCChatProvider.cs similarity index 99% rename from TGServerService/ChatProviders/IRCChatProvider.cs rename to TGS.Server.Service/ChatProviders/IRCChatProvider.cs index a41a7fd72b..550f3a1aee 100644 --- a/TGServerService/ChatProviders/IRCChatProvider.cs +++ b/TGS.Server.Service/ChatProviders/IRCChatProvider.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Threading; -using TGServiceInterface; +using TGS.Interface; using Meebey.SmartIrc4net; -namespace TGServerService.ChatProviders +namespace TGS.Server.Service.ChatProviders { /// /// for internet relay chat diff --git a/TGServerService/DeprecatedInstanceConfig.cs b/TGS.Server.Service/DeprecatedInstanceConfig.cs similarity index 99% rename from TGServerService/DeprecatedInstanceConfig.cs rename to TGS.Server.Service/DeprecatedInstanceConfig.cs index 9eff86cc04..c6127601af 100644 --- a/TGServerService/DeprecatedInstanceConfig.cs +++ b/TGS.Server.Service/DeprecatedInstanceConfig.cs @@ -1,7 +1,7 @@ using System; using System.Configuration; -namespace TGServerService +namespace TGS.Server.Service { /// /// Used to migrate old config settings diff --git a/TGServerService/EventID.cs b/TGS.Server.Service/EventID.cs similarity index 68% rename from TGServerService/EventID.cs rename to TGS.Server.Service/EventID.cs index dab2bca4dd..ef542764dd 100644 --- a/TGServerService/EventID.cs +++ b/TGS.Server.Service/EventID.cs @@ -1,6 +1,6 @@ using System; -namespace TGServerService +namespace TGS.Server.Service { /// /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults @@ -20,7 +20,7 @@ namespace TGServerService /// ChatProviderStartFail = 300, /// - /// Error: When a bad is passed + /// Error: When a bad is passed /// InvalidChatProvider = 400, /// @@ -41,38 +41,38 @@ namespace TGServerService /// BYONDUpdateComplete = 800, /// - /// Error: Failed to move the with TGServiceInterface.Components.ITGAdministration.MoveServer(string) + /// Error: Failed to move the with TGS.Interface.Components.ITGAdministration.MoveServer(string) /// [Obsolete("Not in use anymore", true)] ServerMoveFailed = 900, /// - /// Warning: Failed to delete the old directory during a TGServiceInterface.Components.ITGAdministration.MoveServer(string) operation + /// Warning: Failed to delete the old directory during a TGS.Interface.Components.ITGAdministration.MoveServer(string) operation /// [Obsolete("Not in use anymore", true)] ServerMovePartial = 1000, /// - /// Info: Successful completion of a TGServiceInterface.Components.ITGAdministration.MoveServer(string) operation + /// Info: Successful completion of a TGS.Interface.Components.ITGAdministration.MoveServer(string) operation /// [Obsolete("Not in use anymore", true)] ServerMoveComplete = 1100, /// - /// Error: An internal error occurred during a operation + /// Error: An internal error occurred during a operation /// DMCompileCrash = 1200, /// - /// Error: An internal error occurred during a operation + /// Error: An internal error occurred during a operation /// DMInitializeCrash = 1300, /// - /// Warning: Compile failure of the target .dme in a operation + /// Warning: Compile failure of the target .dme in a operation /// DMCompileError = 1400, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// DMCompileSuccess = 1500, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// DMCompileCancel = 1600, /// @@ -88,7 +88,7 @@ namespace TGServerService /// DDWatchdogCrash = 1900, /// - /// Info: The watchdog has exited, either for an or , or operation + /// Info: The watchdog has exited, either for an or , or operation /// DDWatchdogExit = 2000, /// @@ -101,15 +101,15 @@ namespace TGServerService /// DDWatchdogRebootingServer = 2200, /// - /// Info: The watchdog is performing a operation + /// Info: The watchdog is performing a operation /// DDWatchdogRestart = 2300, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// DDWatchdogRestarted = 2400, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// DDWatchdogStarted = 2500, /// @@ -157,35 +157,35 @@ namespace TGServerService [Obsolete("Not in use anymore", true)] NudgeCrash = 3400, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// RepoClone = 3500, /// - /// Warning: An error occurred during a operation + /// Warning: An error occurred during a operation /// RepoCloneFail = 3600, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// RepoCheckout = 3700, /// - /// Warning: An error occurred during a operation + /// Warning: An error occurred during a operation /// RepoCheckoutFail = 3800, /// - /// Info: Successful completion of a operation with a parameter + /// Info: Successful completion of a operation with a parameter /// RepoHardUpdate = 3900, /// - /// Warning: An error occurred during a operation with a parameter + /// Warning: An error occurred during a operation with a parameter /// RepoHardUpdateFail = 4000, /// - /// Info: Successful completion of a operation with a parameter + /// Info: Successful completion of a operation with a parameter /// RepoMergeUpdate = 4100, /// - /// Warning: An error occurred during a operation with a parameter + /// Warning: An error occurred during a operation with a parameter /// RepoMergeUpdateFail = 4200, /// @@ -197,19 +197,19 @@ namespace TGServerService /// RepoBackupTagFail = 4400, /// - /// Info: Successful completion of a operation with a parameter + /// Info: Successful completion of a operation with a parameter /// RepoResetTracked = 4500, /// - /// Warning: An error occurred during a operation with a parameter + /// Warning: An error occurred during a operation with a parameter /// RepoResetTrackedFail = 4600, /// - /// Info: Successful completion of a operation with a parameter + /// Info: Successful completion of a operation with a parameter /// RepoReset = 4700, /// - /// Warning: An error occurred during a operation with a parameter + /// Warning: An error occurred during a operation with a parameter /// RepoResetFail = 4800, /// @@ -217,11 +217,11 @@ namespace TGServerService /// RepoPRListError = 4900, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// RepoPRMerge = 5000, /// - /// Warning: An error occurred during a operation + /// Warning: An error occurred during a operation /// RepoPRMergeFail = 5100, /// @@ -233,27 +233,27 @@ namespace TGServerService /// RepoCommitFail = 5300, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// RepoPush = 5400, /// - /// Warning: An error occurred during a operation + /// Warning: An error occurred during a operation /// RepoPushFail = 5500, /// - /// Info: Successful completion of a operation + /// Info: Successful completion of a operation /// RepoChangelog = 5600, /// - /// Warning: An error occurred during a operation + /// Warning: An error occurred during a operation /// RepoChangelogFail = 5700, /// - /// Info: When the dll is updated for the + /// Info: When the dll is updated for the /// BridgeDLLUpdated = 5800, /// - /// Error: An error occurred while updating the dll for the + /// Error: An error occurred while updating the dll for the /// BridgeDLLUpdateFail = 5900, /// @@ -269,7 +269,7 @@ namespace TGServerService /// WorldReboot = 6200, /// - /// Info: When the output of is applied to the live + /// Info: When the output of is applied to the live /// ServerUpdateApplied = 6300, /// @@ -287,7 +287,7 @@ namespace TGServerService /// Submodule = 6600, /// - /// This event is of type or . It occurs when a user different from the previous one tries and either succeeds or fails to access a . DreamDaemon itself successfully accessing will not trigger this + /// This event is of type or . It occurs when a user different from the previous one tries and either succeeds or fails to access a . DreamDaemon itself successfully accessing will not trigger this /// Authentication = 6700, /// @@ -299,7 +299,7 @@ namespace TGServerService /// PreactionFail = 6900, /// - /// Warning: When a command from DreamDaemon fails + /// Warning: When a command from DreamDaemon fails /// InteropCallException = 7000, /// diff --git a/TGServerService/InstanceConfig.cs b/TGS.Server.Service/InstanceConfig.cs similarity index 99% rename from TGServerService/InstanceConfig.cs rename to TGS.Server.Service/InstanceConfig.cs index a7afc8ab5f..d824c418c0 100644 --- a/TGServerService/InstanceConfig.cs +++ b/TGS.Server.Service/InstanceConfig.cs @@ -1,8 +1,8 @@ using System.IO; using System.Web.Script.Serialization; -using TGServiceInterface; +using TGS.Interface; -namespace TGServerService +namespace TGS.Server.Service { /// /// Configuration settings for a diff --git a/TGServerService/MessageType.cs b/TGS.Server.Service/MessageType.cs similarity index 94% rename from TGServerService/MessageType.cs rename to TGS.Server.Service/MessageType.cs index 8db0cf2298..803a3fb4a5 100644 --- a/TGServerService/MessageType.cs +++ b/TGS.Server.Service/MessageType.cs @@ -1,6 +1,6 @@ using System; -namespace TGServerService +namespace TGS.Server.Service { /// /// Type of chat message, these may be OR'd together diff --git a/TGServerService/ProcessExtension.cs b/TGS.Server.Service/ProcessExtension.cs similarity index 98% rename from TGServerService/ProcessExtension.cs rename to TGS.Server.Service/ProcessExtension.cs index ecf336a9a0..fab7bebdcc 100644 --- a/TGServerService/ProcessExtension.cs +++ b/TGS.Server.Service/ProcessExtension.cs @@ -2,7 +2,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; -namespace TGServerService +namespace TGS.Server.Service { /// /// Helpers to ing and a . Lightly massaged code from https://stackoverflow.com/a/13109774. Documentation linked from MSDN on 20/10/2017 diff --git a/TGServerService/Program.cs b/TGS.Server.Service/Program.cs similarity index 99% rename from TGServerService/Program.cs rename to TGS.Server.Service/Program.cs index 1394802800..8d12789234 100644 --- a/TGServerService/Program.cs +++ b/TGS.Server.Service/Program.cs @@ -4,7 +4,7 @@ using System.IO; using System.ServiceProcess; using System.Threading.Tasks; -namespace TGServerService +namespace TGS.Server.Service { static class Program { diff --git a/TGServerService/ProjectInstaller.cs b/TGS.Server.Service/ProjectInstaller.cs similarity index 96% rename from TGServerService/ProjectInstaller.cs rename to TGS.Server.Service/ProjectInstaller.cs index f5c0f1a911..10c319e3d0 100644 --- a/TGServerService/ProjectInstaller.cs +++ b/TGS.Server.Service/ProjectInstaller.cs @@ -2,7 +2,7 @@ using System.Configuration.Install; using System.ServiceProcess; -namespace TGServerService +namespace TGS.Server.Service { /// /// This tells the .msi there is a Windows in this that needs installation diff --git a/TGServerService/Properties/AssemblyInfo.cs b/TGS.Server.Service/Properties/AssemblyInfo.cs similarity index 97% rename from TGServerService/Properties/AssemblyInfo.cs rename to TGS.Server.Service/Properties/AssemblyInfo.cs index e9ebd6fc8c..b7a644ae25 100644 --- a/TGServerService/Properties/AssemblyInfo.cs +++ b/TGS.Server.Service/Properties/AssemblyInfo.cs @@ -1,16 +1,16 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TGStation Server Service")] -[assembly: AssemblyDescription("Server Service for running BYOND games")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f32eda25-0855-411c-af5e-f0d042917e2d")] +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TGStation Server Service")] +[assembly: AssemblyDescription("Server Service for running BYOND games")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f32eda25-0855-411c-af5e-f0d042917e2d")] diff --git a/TGServerService/Properties/Settings.Designer.cs b/TGS.Server.Service/Properties/Settings.Designer.cs similarity index 98% rename from TGServerService/Properties/Settings.Designer.cs rename to TGS.Server.Service/Properties/Settings.Designer.cs index 1bbb0d95f0..9b807e1637 100644 --- a/TGServerService/Properties/Settings.Designer.cs +++ b/TGS.Server.Service/Properties/Settings.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace TGServerService.Properties { +namespace TGS.Server.Service.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/TGServerService/Properties/Settings.settings b/TGS.Server.Service/Properties/Settings.settings similarity index 91% rename from TGServerService/Properties/Settings.settings rename to TGS.Server.Service/Properties/Settings.settings index 447b6c7ee3..3770ccac32 100644 --- a/TGServerService/Properties/Settings.settings +++ b/TGS.Server.Service/Properties/Settings.settings @@ -1,5 +1,5 @@  - + diff --git a/TGServerService/RepoConfig.cs b/TGS.Server.Service/RepoConfig.cs similarity index 97% rename from TGServerService/RepoConfig.cs rename to TGS.Server.Service/RepoConfig.cs index d406e658ff..d3b7cf2d5b 100644 --- a/TGServerService/RepoConfig.cs +++ b/TGS.Server.Service/RepoConfig.cs @@ -4,7 +4,7 @@ using System.IO; using System.Linq; using System.Web.Script.Serialization; -namespace TGServerService +namespace TGS.Server.Service { /// /// Repository specific information for a @@ -12,7 +12,7 @@ namespace TGServerService sealed class RepoConfig : IEquatable { /// - /// If this json is setup to support + /// If this json is setup to support /// public readonly bool ChangelogSupport; /// diff --git a/TGServerService/RootAuthorizationManager.cs b/TGS.Server.Service/RootAuthorizationManager.cs similarity index 95% rename from TGServerService/RootAuthorizationManager.cs rename to TGS.Server.Service/RootAuthorizationManager.cs index f3f45d0983..4c62acb8a7 100644 --- a/TGServerService/RootAuthorizationManager.cs +++ b/TGS.Server.Service/RootAuthorizationManager.cs @@ -4,9 +4,9 @@ using System.Diagnostics; using System.Linq; using System.Security.Principal; using System.ServiceModel; -using TGServiceInterface.Components; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { /// /// A used to determine only if the caller is an admin diff --git a/TGServerService/ServerInstance/Administration.cs b/TGS.Server.Service/ServerInstance/Administration.cs similarity index 98% rename from TGServerService/ServerInstance/Administration.cs rename to TGS.Server.Service/ServerInstance/Administration.cs index affe43a2b7..03b7caf1c3 100644 --- a/TGServerService/ServerInstance/Administration.cs +++ b/TGS.Server.Service/ServerInstance/Administration.cs @@ -3,10 +3,10 @@ using System.DirectoryServices.AccountManagement; using System.Security.Principal; using System.ServiceModel; using System.Threading; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { //note this only works with MACHINE LOCAL groups and admins for now //if someone wants AD shit, code it yourself diff --git a/TGServerService/ServerInstance/Byond.cs b/TGS.Server.Service/ServerInstance/Byond.cs similarity index 99% rename from TGServerService/ServerInstance/Byond.cs rename to TGS.Server.Service/ServerInstance/Byond.cs index 2b902a52f6..bd00bfb10f 100644 --- a/TGServerService/ServerInstance/Byond.cs +++ b/TGS.Server.Service/ServerInstance/Byond.cs @@ -5,10 +5,10 @@ using System.IO.Compression; using System.Net; using System.Text.RegularExpressions; using System.Threading; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { sealed partial class ServerInstance : ITGByond { diff --git a/TGServerService/ServerInstance/Chat.cs b/TGS.Server.Service/ServerInstance/Chat.cs similarity index 97% rename from TGServerService/ServerInstance/Chat.cs rename to TGS.Server.Service/ServerInstance/Chat.cs index ede8605480..8c6bb66464 100644 --- a/TGServerService/ServerInstance/Chat.cs +++ b/TGS.Server.Service/ServerInstance/Chat.cs @@ -2,12 +2,12 @@ using System.Linq; using System.Collections.Generic; using System.Web.Script.Serialization; -using TGServerService.ChatCommands; -using TGServerService.ChatProviders; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Server.Service.ChatCommands; +using TGS.Server.Service.ChatProviders; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { sealed partial class ServerInstance : ITGChat { diff --git a/TGServerService/ServerInstance/Compiler.cs b/TGS.Server.Service/ServerInstance/Compiler.cs similarity index 99% rename from TGServerService/ServerInstance/Compiler.cs rename to TGS.Server.Service/ServerInstance/Compiler.cs index 6ccda81072..dd5a2867ea 100644 --- a/TGServerService/ServerInstance/Compiler.cs +++ b/TGS.Server.Service/ServerInstance/Compiler.cs @@ -6,10 +6,10 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { sealed partial class ServerInstance : ITGCompiler { diff --git a/TGServerService/ServerInstance/Config.cs b/TGS.Server.Service/ServerInstance/Config.cs similarity index 99% rename from TGServerService/ServerInstance/Config.cs rename to TGS.Server.Service/ServerInstance/Config.cs index d59fef5909..af81f094cc 100644 --- a/TGServerService/ServerInstance/Config.cs +++ b/TGS.Server.Service/ServerInstance/Config.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.IO; using System.ServiceModel; -using TGServiceInterface.Components; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { //knobs and such sealed partial class ServerInstance : ITGConfig diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGS.Server.Service/ServerInstance/DreamDaemon.cs similarity index 99% rename from TGServerService/ServerInstance/DreamDaemon.cs rename to TGS.Server.Service/ServerInstance/DreamDaemon.cs index 0321025126..1682f4b7a5 100644 --- a/TGServerService/ServerInstance/DreamDaemon.cs +++ b/TGS.Server.Service/ServerInstance/DreamDaemon.cs @@ -5,10 +5,10 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Timers; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { //manages the dd window. //It's not possible to actually click it while starting it in CL mode, so in order to change visibility, security, etc. It restarts the process when the world reboots @@ -537,7 +537,7 @@ namespace TGServerService //We could be debugging from the project directory if (!File.Exists(BridgePath)) //A little hackish debug mode doctoring never hurt anyone - BridgePath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(InterfacePath)))), "TGDreamDaemonBridge/bin/x86/Debug", BridgeDLLName); + BridgePath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(InterfacePath)))), "TGS.Interface.Bridge/bin/x86/Debug", BridgeDLLName); #endif try { diff --git a/TGServerService/ServerInstance/Interop.cs b/TGS.Server.Service/ServerInstance/Interop.cs similarity index 98% rename from TGServerService/ServerInstance/Interop.cs rename to TGS.Server.Service/ServerInstance/Interop.cs index ba64d4a372..621b0502cc 100644 --- a/TGServerService/ServerInstance/Interop.cs +++ b/TGS.Server.Service/ServerInstance/Interop.cs @@ -6,11 +6,11 @@ using System.Text; using System.Threading; using System.Web.Script.Serialization; using System.Web.Security; -using TGServerService.ChatCommands; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Server.Service.ChatCommands; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { //handles talking between the world and us sealed partial class ServerInstance : ITGInterop diff --git a/TGServerService/ServerInstance/PreactionHandler.cs b/TGS.Server.Service/ServerInstance/PreactionHandler.cs similarity index 99% rename from TGServerService/ServerInstance/PreactionHandler.cs rename to TGS.Server.Service/ServerInstance/PreactionHandler.cs index 84bc7d8ff9..f3991ef8f6 100644 --- a/TGServerService/ServerInstance/PreactionHandler.cs +++ b/TGS.Server.Service/ServerInstance/PreactionHandler.cs @@ -2,7 +2,7 @@ using System.Diagnostics; using System.IO; -namespace TGServerService +namespace TGS.Server.Service { // Some useful functions for triggering pre action events sealed partial class ServerInstance diff --git a/TGServerService/ServerInstance/Repository.cs b/TGS.Server.Service/ServerInstance/Repository.cs similarity index 99% rename from TGServerService/ServerInstance/Repository.cs rename to TGS.Server.Service/ServerInstance/Repository.cs index 993da4654b..4ff01a7cb9 100644 --- a/TGServerService/ServerInstance/Repository.cs +++ b/TGS.Server.Service/ServerInstance/Repository.cs @@ -7,10 +7,10 @@ using System.Linq; using System.Net; using System.Threading; using System.Web.Script.Serialization; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { sealed partial class ServerInstance : ITGRepository, IDisposable { @@ -81,7 +81,7 @@ namespace TGServerService /// Repository Repo; /// - /// Used for reporting operation progress to the + /// Used for reporting operation progress to the /// int currentProgress = -1; diff --git a/TGServerService/ServerInstance/ServerInstance.cs b/TGS.Server.Service/ServerInstance/ServerInstance.cs similarity index 98% rename from TGServerService/ServerInstance/ServerInstance.cs rename to TGS.Server.Service/ServerInstance/ServerInstance.cs index dca0af9150..64ef3506ca 100644 --- a/TGServerService/ServerInstance/ServerInstance.cs +++ b/TGS.Server.Service/ServerInstance/ServerInstance.cs @@ -2,9 +2,9 @@ using System.Diagnostics; using System.IO; using System.ServiceModel; -using TGServiceInterface.Components; +using TGS.Interface.Components; -namespace TGServerService +namespace TGS.Server.Service { //I know the fact that this is one massive partial class is gonna trigger everyone //There really was no other succinct way to do it (<= He's lying through his teeth, don't listen to him) diff --git a/TGServerService/Service.cs b/TGS.Server.Service/Service.cs similarity index 96% rename from TGServerService/Service.cs rename to TGS.Server.Service/Service.cs index 75f0f23cac..99ec13e82e 100644 --- a/TGServerService/Service.cs +++ b/TGS.Server.Service/Service.cs @@ -1,693 +1,693 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.IO; -using System.Security.Principal; -using System.ServiceModel; -using System.ServiceProcess; -using TGServiceInterface; -using TGServiceInterface.Components; - -namespace TGServerService -{ - /// - /// The windows service the application runs as - /// - [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] - class Service : ServiceBase, ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager - { - /// - /// The logging ID used for events - /// - public const byte LoggingID = 0; - - /// - /// The service version based on the - /// - public static readonly string VersionString = "/tg/station 13 Server Service v" + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; - - /// - /// Singleton instance - /// - static Service ActiveService; - - /// - /// Cancels WCF's user impersonation to allow clean access to writing log files - /// - public static void CancelImpersonation() - { - WindowsIdentity.Impersonate(IntPtr.Zero); - } - - /// - /// Writes an event to Windows the event log - /// - /// The log message - /// The of the message - /// The of the event - /// The logging source ID for the event - public static void WriteEntry(string message, EventID id, EventLogEntryType eventType, byte loggingID) - { - ActiveService.EventLog.WriteEntry(message, eventType, (int)id + loggingID); - } - - /// - /// Checks an for illegal characters - /// - /// The name to check - /// if contains no illegal characters, error message otherwise - static string CheckInstanceName(string instanceName) - { - char[] bannedCharacters = { ';', '&', '=', '%' }; - foreach (var I in bannedCharacters) - if (instanceName.Contains(I.ToString())) - return "Instance names may not contain the following characters: ';', '&', '=', or '%'"; - return null; - } - - /// - /// Sets up ServiceName and - /// - public Service() - { - ServiceName = "TG Station Server"; - if (ActiveService != null) - throw new Exception("There is already a Service instance running!"); - ActiveService = this; - } - - /// - /// Clears - /// - /// if this method was invoked from , otherwise it was invoked by the finalizer - protected override void Dispose(bool disposing) - { - ActiveService = null; - base.Dispose(disposing); - } - - /// - /// The WCF host that contains connects to - /// - ServiceHost serviceHost; - /// - /// Map of to the respective hosting the - /// - IDictionary hosts; - /// - /// List of s in use - /// - IList UsedLoggingIDs = new List(); - - /// - /// Migrates the .NET config from to + 1 - /// - /// The version to migrate from - void MigrateSettings(int oldVersion) - { - var Config = Properties.Settings.Default; - switch (oldVersion) - { - case 6: //switch to per-instance configs - var IC = DeprecatedInstanceConfig.CreateFromNETSettings(); - IC.Save(); - Config.InstancePaths.Add(IC.Directory); - break; - } - } - - /// - /// Enumerates configured s. Detaches those that fail to load - /// - /// Each configured - IEnumerable GetInstanceConfigs() - { - var pathsToRemove = new List(); - lock (this) - { - var IPS = Properties.Settings.Default.InstancePaths; - foreach (var I in IPS) - { - IInstanceConfig ic; - try - { - ic = InstanceConfig.Load(I); - } - catch (Exception e) - { - WriteEntry(String.Format("Unable load instance config at path {0}. Error: {1} Detaching...", I, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - pathsToRemove.Add(I); - continue; - } - yield return ic; - } - foreach (var I in pathsToRemove) - IPS.Remove(I); - } - } - - /// - /// Overrides and saves the configured if requested by command line parameters - /// - /// The command line parameters for the - void ChangePortFromCommandLine(string[] args) - { - var Config = Properties.Settings.Default; - - for (var I = 0; I < args.Length - 1; ++I) - if (args[I].ToLower() == "-port") - { - try - { - var res = Convert.ToUInt16(args[I + 1]); - if (res == 0) - throw new Exception("Cannot bind to port 0"); - Config.RemoteAccessPort = res; - } - catch (Exception e) - { - throw new Exception("Invalid argument for \"-port\"", e); - } - Config.Save(); - break; - } - } - - /// - /// Called by the Windows service manager. Initializes and starts configured s - /// - /// Command line arguments for the - protected override void OnStart(string[] args) - { - Environment.CurrentDirectory = Directory.CreateDirectory(Path.GetTempPath() + "/TGStationServerService").FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png - - SetupConfig(); - - ChangePortFromCommandLine(args); - - SetupService(); - - SetupInstances(); - - OnlineAllHosts(); - } - - /// - /// Writes some changes to the that always need to be done. - /// - void PrePrepConfig() - { - var Config = Properties.Settings.Default; - - if (Config.InstancePaths == null) - Config.InstancePaths = new StringCollection(); - } - - /// - /// Upgrades up the service configuration - /// - void SetupConfig() - { - var Config = Properties.Settings.Default; - if (Config.UpgradeRequired) - { - var newVersion = Config.SettingsVersion; - Config.Upgrade(); - - PrePrepConfig(); - - for (var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion) - MigrateSettings(oldVersion); - - Config.SettingsVersion = newVersion; - - Config.UpgradeRequired = false; - Config.Save(); - } - else - PrePrepConfig(); - } - - /// - /// Creates the for - /// - void SetupService() - { - serviceHost = CreateHost(this, ServerInterface.MasterInterfaceName); - foreach (var I in ServerInterface.ValidServiceInterfaces) - AddEndpoint(serviceHost, I); - serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us - } - - /// - /// Opens all created s - /// - void OnlineAllHosts() - { - serviceHost.Open(); - foreach (var I in hosts) - I.Value.Open(); - } - - /// - /// Creates a for using the default pipe, CloseTimeout for the , and the configured - /// - /// The - /// The URL to access components on the - /// The created - static ServiceHost CreateHost(object singleton, string endpointPostfix) - { - return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) - { - CloseTimeout = new TimeSpan(0, 0, 5) - }; - } - - /// - /// Creates s for all s as listed in , detaches bad ones - /// - void SetupInstances() - { - hosts = new Dictionary(); - var pathsToRemove = new List(); - var seenNames = new List(); - foreach (var I in GetInstanceConfigs()) - { - if (seenNames.Contains(I.Name)) - { - WriteEntry(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - pathsToRemove.Add(I.Directory); - } - if (I.Enabled && SetupInstance(I) == null) - pathsToRemove.Add(I.Directory); - else - seenNames.Add(I.Name); - } - foreach (var I in pathsToRemove) - Properties.Settings.Default.InstancePaths.Remove(I); - } - - /// - /// Unlocks a acquired with - /// - /// The to unlock - void UnlockLoggingID(byte ID) - { - lock (UsedLoggingIDs) - { - UsedLoggingIDs.Remove(ID); - } - } - - /// - /// Gets and locks a - /// - /// A logging ID for the must be released using - byte LockLoggingID() - { - lock (UsedLoggingIDs) - { - for (byte I = 1; I < 100; ++I) - if (!UsedLoggingIDs.Contains(I)) - { - UsedLoggingIDs.Add(I); - return I; - } - } - throw new Exception("All logging IDs in use!"); - } - - /// - /// Creates and starts a for a at - /// - /// The for the - /// The inactive on success, on failure - ServiceHost SetupInstance(IInstanceConfig config) - { - ServerInstance instance; - string instanceName; - try - { - if (hosts.ContainsKey(config.Directory)) - { - 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); - return null; - } - if (!config.Enabled) - return null; - var ID = LockLoggingID(); - WriteEntry(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, config.Directory, ID), EventID.InstanceIDAssigned, EventLogEntryType.Information, ID); - instanceName = config.Name; - instance = new ServerInstance(config, ID); - } - catch (Exception e) - { - WriteEntry(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", config.Directory, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - return null; - } - - var host = CreateHost(instance, String.Format("{0}/{1}", ServerInterface.InstanceInterfaceName, instanceName)); - hosts.Add(instanceName, host); - - foreach (var J in ServerInterface.ValidInstanceInterfaces) - AddEndpoint(host, J); - - host.Authorization.ServiceAuthorizationManager = instance; - return host; - } - - /// - /// Adds a WCF endpoint for a component - /// - /// The service host to add the component to - /// The type of the component - void AddEndpoint(ServiceHost host, Type typetype) - { - var bindingName = typetype.Name; - host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = ServerInterface.TransferLimitLocal }, bindingName); - var httpsBinding = new WSHttpBinding() - { - SendTimeout = new TimeSpan(0, 0, 40), - MaxReceivedMessageSize = ServerInterface.TransferLimitRemote - }; - var requireAuth = typetype.Name != typeof(ITGConnectivity).Name; - httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; - httpsBinding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check - httpsBinding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None; - host.AddServiceEndpoint(typetype, httpsBinding, bindingName); - } - - /// - /// Shuts down all active s and calls on it's - /// - protected override void OnStop() - { - lock (this) - { - try - { - foreach (var I in hosts) - { - var host = I.Value; - var instance = (ServerInstance)host.SingletonInstance; - host.Close(); - instance.Dispose(); - UnlockLoggingID(instance.LoggingID); - } - } - catch (Exception e) - { - WriteEntry(e.ToString(), EventID.ServiceShutdownFail, EventLogEntryType.Error, LoggingID); - } - serviceHost.Close(); - } - Properties.Settings.Default.Save(); - ActiveService = null; - } - - /// - public void VerifyConnection() { } - - /// - public void PrepareForUpdate() - { - foreach (var I in hosts) - ((ServerInstance)I.Value.SingletonInstance).Reattach(false); - } - - /// - public ushort RemoteAccessPort() - { - return Properties.Settings.Default.RemoteAccessPort; - } - - /// - public string SetRemoteAccessPort(ushort port) - { - if (port == 0) - return "Cannot bind to port 0"; - Properties.Settings.Default.RemoteAccessPort = port; - return null; - } - - /// - public string Version() - { - return VersionString; - } - - /// - public bool SetPythonPath(string path) - { - if (!Directory.Exists(path)) - return false; - Properties.Settings.Default.PythonPath = Path.GetFullPath(path); - return true; - } - - /// - public string PythonPath() - { - return Properties.Settings.Default.PythonPath; - } - - /// - public IList ListInstances() - { - var result = new List(); - lock (this) - foreach (var ic in GetInstanceConfigs()) - result.Add(new InstanceMetadata - { - Name = ic.Name, - Path = ic.Directory, - Enabled = ic.Enabled, - LoggingID = (byte)(ic.Enabled ? ((ServerInstance)hosts[ic.Name].SingletonInstance).LoggingID : 0) - }); - return result; - } - - /// - public string CreateInstance(string Name, string path) - { - path = Program.NormalizePath(path); - var res = CheckInstanceName(Name); - if (res != null) - return res; - if (File.Exists(path) || Directory.Exists(path)) - return "Cannot create instance at pre-existing path!"; - var Config = Properties.Settings.Default; - lock (this) - { - if (Config.InstancePaths.Contains(path)) - return String.Format("Instance at {0} already exists!", path); - foreach (var oic in GetInstanceConfigs()) - if (Name == oic.Name) - return String.Format("Instance named {0} already exists!", oic.Name); - IInstanceConfig ic; - try - { - ic = new InstanceConfig(path) - { - Name = Name - }; - Directory.CreateDirectory(path); - ic.Save(); - Properties.Settings.Default.InstancePaths.Add(path); - } - catch (Exception e) - { - return e.ToString(); - } - return SetupOneInstance(ic); - } - } - - /// - /// Starts and onlines an instance located at - /// - /// The for the - /// on success, error message on failure - string SetupOneInstance(IInstanceConfig config) - { - if (!config.Enabled) - return null; - try - { - var host = SetupInstance(config); - if (host != null) - host.Open(); - else - lock (this) - Properties.Settings.Default.InstancePaths.Remove(config.Directory); - return null; - } - catch (Exception e) - { - return "Instance set up but an error occurred while starting it: " + e.ToString(); - } - } - - /// - public string ImportInstance(string path) - { - path = Program.NormalizePath(path); - var Config = Properties.Settings.Default; - lock (this) - { - if (Config.InstancePaths.Contains(path)) - return String.Format("Instance at {0} already exists!", path); - if(!Directory.Exists(path)) - return String.Format("There is no instance located at {0}!", path); - IInstanceConfig ic; - try - { - ic = InstanceConfig.Load(path); - foreach(var oic in GetInstanceConfigs()) - if(ic.Name == oic.Name) - return String.Format("Instance named {0} already exists!", oic.Name); - ic.Save(); - Properties.Settings.Default.InstancePaths.Add(path); - } - catch (Exception e) - { - return e.ToString(); - } - return SetupOneInstance(ic); - } - } - - /// - public bool InstanceEnabled(string Name) - { - lock(this) - { - return hosts.ContainsKey(Name); - } - } - - /// - public string SetInstanceEnabled(string Name, bool enabled) - { - return SetInstanceEnabledImpl(Name, enabled, out string path); - } - - - /// - /// Sets a 's enabled status - /// - /// The whom's status should be changed - /// to enable the , to disable it - /// The path to the modified - /// on success, error message on failure - string SetInstanceEnabledImpl(string Name, bool enabled, out string path) - { - path = null; - lock (this) - { - var hostIsOnline = hosts.ContainsKey(Name); - if (enabled) - { - if (hostIsOnline) - return null; - foreach (var ic in GetInstanceConfigs()) - if (ic.Name == Name) - { - path = ic.Directory; - ic.Enabled = true; - ic.Save(); - return SetupOneInstance(ic); - } - return String.Format("Instance {0} does not exist!", Name); - } - else - { - if (!hostIsOnline) - return null; - var host = hosts[Name]; - hosts.Remove(Name); - var inst = (ServerInstance)host.SingletonInstance; - host.Close(); - path = inst.ServerDirectory(); - inst.Offline(); - inst.Dispose(); - UnlockLoggingID(inst.LoggingID); - return null; - } - } - } - - /// - public string RenameInstance(string name, string new_name) - { - if (name == new_name) - return null; - var res = CheckInstanceName(new_name); - if (res != null) - return res; - lock (this) - { - //we have to check em all anyway - IInstanceConfig the_droid_were_looking_for = null; - foreach (var ic in GetInstanceConfigs()) - if (ic.Name == name) - { - the_droid_were_looking_for = ic; - break; - } - else if (ic.Name == new_name) - return String.Format("There is already another instance named {0}!", new_name); - if (the_droid_were_looking_for == null) - return String.Format("There is no instance named {0}!", name); - var ie = InstanceEnabled(name); - if(ie) - SetInstanceEnabled(name, false); - the_droid_were_looking_for.Name = new_name; - string result = ""; - try - { - the_droid_were_looking_for.Save(); - result = null; - } - catch(Exception e) - { - result = "Could not save instance config! Error: " + e.ToString(); - } - finally - { - if (ie) - { - var resRestore = SetInstanceEnabled(new_name, true); - if (resRestore != null) - result = (result + " " + resRestore).Trim(); - } - } - return result; - } - } - - /// - public string DetachInstance(string name) - { - lock (this) - { - var res = SetInstanceEnabledImpl(name, false, out string path); - if (res != null) - return res; - if (path == null) //gotta find it ourselves - foreach (var ic in GetInstanceConfigs()) - if (ic.Name == name) - { - path = ic.Directory; - break; - } - if (path == null) - return String.Format("No instance named {0} exists!", name); - Properties.Settings.Default.InstancePaths.Remove(path); - return null; - } - } - } -} +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.IO; +using System.Security.Principal; +using System.ServiceModel; +using System.ServiceProcess; +using TGS.Interface; +using TGS.Interface.Components; + +namespace TGS.Server.Service +{ + /// + /// The windows service the application runs as + /// + [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] + class Service : ServiceBase, ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager + { + /// + /// The logging ID used for events + /// + public const byte LoggingID = 0; + + /// + /// The service version based on the + /// + public static readonly string VersionString = "/tg/station 13 Server Service v" + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; + + /// + /// Singleton instance + /// + static Service ActiveService; + + /// + /// Cancels WCF's user impersonation to allow clean access to writing log files + /// + public static void CancelImpersonation() + { + WindowsIdentity.Impersonate(IntPtr.Zero); + } + + /// + /// Writes an event to Windows the event log + /// + /// The log message + /// The of the message + /// The of the event + /// The logging source ID for the event + public static void WriteEntry(string message, EventID id, EventLogEntryType eventType, byte loggingID) + { + ActiveService.EventLog.WriteEntry(message, eventType, (int)id + loggingID); + } + + /// + /// Checks an for illegal characters + /// + /// The name to check + /// if contains no illegal characters, error message otherwise + static string CheckInstanceName(string instanceName) + { + char[] bannedCharacters = { ';', '&', '=', '%' }; + foreach (var I in bannedCharacters) + if (instanceName.Contains(I.ToString())) + return "Instance names may not contain the following characters: ';', '&', '=', or '%'"; + return null; + } + + /// + /// Sets up ServiceName and + /// + public Service() + { + ServiceName = "TG Station Server"; + if (ActiveService != null) + throw new Exception("There is already a Service instance running!"); + ActiveService = this; + } + + /// + /// Clears + /// + /// if this method was invoked from , otherwise it was invoked by the finalizer + protected override void Dispose(bool disposing) + { + ActiveService = null; + base.Dispose(disposing); + } + + /// + /// The WCF host that contains connects to + /// + ServiceHost serviceHost; + /// + /// Map of to the respective hosting the + /// + IDictionary hosts; + /// + /// List of s in use + /// + IList UsedLoggingIDs = new List(); + + /// + /// Migrates the .NET config from to + 1 + /// + /// The version to migrate from + void MigrateSettings(int oldVersion) + { + var Config = Properties.Settings.Default; + switch (oldVersion) + { + case 6: //switch to per-instance configs + var IC = DeprecatedInstanceConfig.CreateFromNETSettings(); + IC.Save(); + Config.InstancePaths.Add(IC.Directory); + break; + } + } + + /// + /// Enumerates configured s. Detaches those that fail to load + /// + /// Each configured + IEnumerable GetInstanceConfigs() + { + var pathsToRemove = new List(); + lock (this) + { + var IPS = Properties.Settings.Default.InstancePaths; + foreach (var I in IPS) + { + IInstanceConfig ic; + try + { + ic = InstanceConfig.Load(I); + } + catch (Exception e) + { + WriteEntry(String.Format("Unable load instance config at path {0}. Error: {1} Detaching...", I, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); + pathsToRemove.Add(I); + continue; + } + yield return ic; + } + foreach (var I in pathsToRemove) + IPS.Remove(I); + } + } + + /// + /// Overrides and saves the configured if requested by command line parameters + /// + /// The command line parameters for the + void ChangePortFromCommandLine(string[] args) + { + var Config = Properties.Settings.Default; + + for (var I = 0; I < args.Length - 1; ++I) + if (args[I].ToLower() == "-port") + { + try + { + var res = Convert.ToUInt16(args[I + 1]); + if (res == 0) + throw new Exception("Cannot bind to port 0"); + Config.RemoteAccessPort = res; + } + catch (Exception e) + { + throw new Exception("Invalid argument for \"-port\"", e); + } + Config.Save(); + break; + } + } + + /// + /// Called by the Windows service manager. Initializes and starts configured s + /// + /// Command line arguments for the + protected override void OnStart(string[] args) + { + Environment.CurrentDirectory = Directory.CreateDirectory(Path.GetTempPath() + "/TGStationServerService").FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png + + SetupConfig(); + + ChangePortFromCommandLine(args); + + SetupService(); + + SetupInstances(); + + OnlineAllHosts(); + } + + /// + /// Writes some changes to the that always need to be done. + /// + void PrePrepConfig() + { + var Config = Properties.Settings.Default; + + if (Config.InstancePaths == null) + Config.InstancePaths = new StringCollection(); + } + + /// + /// Upgrades up the service configuration + /// + void SetupConfig() + { + var Config = Properties.Settings.Default; + if (Config.UpgradeRequired) + { + var newVersion = Config.SettingsVersion; + Config.Upgrade(); + + PrePrepConfig(); + + for (var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion) + MigrateSettings(oldVersion); + + Config.SettingsVersion = newVersion; + + Config.UpgradeRequired = false; + Config.Save(); + } + else + PrePrepConfig(); + } + + /// + /// Creates the for + /// + void SetupService() + { + serviceHost = CreateHost(this, ServerInterface.MasterInterfaceName); + foreach (var I in ServerInterface.ValidServiceInterfaces) + AddEndpoint(serviceHost, I); + serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us + } + + /// + /// Opens all created s + /// + void OnlineAllHosts() + { + serviceHost.Open(); + foreach (var I in hosts) + I.Value.Open(); + } + + /// + /// Creates a for using the default pipe, CloseTimeout for the , and the configured + /// + /// The + /// The URL to access components on the + /// The created + static ServiceHost CreateHost(object singleton, string endpointPostfix) + { + return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) + { + CloseTimeout = new TimeSpan(0, 0, 5) + }; + } + + /// + /// Creates s for all s as listed in , detaches bad ones + /// + void SetupInstances() + { + hosts = new Dictionary(); + var pathsToRemove = new List(); + var seenNames = new List(); + foreach (var I in GetInstanceConfigs()) + { + if (seenNames.Contains(I.Name)) + { + WriteEntry(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); + pathsToRemove.Add(I.Directory); + } + if (I.Enabled && SetupInstance(I) == null) + pathsToRemove.Add(I.Directory); + else + seenNames.Add(I.Name); + } + foreach (var I in pathsToRemove) + Properties.Settings.Default.InstancePaths.Remove(I); + } + + /// + /// Unlocks a acquired with + /// + /// The to unlock + void UnlockLoggingID(byte ID) + { + lock (UsedLoggingIDs) + { + UsedLoggingIDs.Remove(ID); + } + } + + /// + /// Gets and locks a + /// + /// A logging ID for the must be released using + byte LockLoggingID() + { + lock (UsedLoggingIDs) + { + for (byte I = 1; I < 100; ++I) + if (!UsedLoggingIDs.Contains(I)) + { + UsedLoggingIDs.Add(I); + return I; + } + } + throw new Exception("All logging IDs in use!"); + } + + /// + /// Creates and starts a for a at + /// + /// The for the + /// The inactive on success, on failure + ServiceHost SetupInstance(IInstanceConfig config) + { + ServerInstance instance; + string instanceName; + try + { + if (hosts.ContainsKey(config.Directory)) + { + 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); + return null; + } + if (!config.Enabled) + return null; + var ID = LockLoggingID(); + WriteEntry(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, config.Directory, ID), EventID.InstanceIDAssigned, EventLogEntryType.Information, ID); + instanceName = config.Name; + instance = new ServerInstance(config, ID); + } + catch (Exception e) + { + WriteEntry(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", config.Directory, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); + return null; + } + + var host = CreateHost(instance, String.Format("{0}/{1}", ServerInterface.InstanceInterfaceName, instanceName)); + hosts.Add(instanceName, host); + + foreach (var J in ServerInterface.ValidInstanceInterfaces) + AddEndpoint(host, J); + + host.Authorization.ServiceAuthorizationManager = instance; + return host; + } + + /// + /// Adds a WCF endpoint for a component + /// + /// The service host to add the component to + /// The type of the component + void AddEndpoint(ServiceHost host, Type typetype) + { + var bindingName = typetype.Name; + host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = ServerInterface.TransferLimitLocal }, bindingName); + var httpsBinding = new WSHttpBinding() + { + SendTimeout = new TimeSpan(0, 0, 40), + MaxReceivedMessageSize = ServerInterface.TransferLimitRemote + }; + var requireAuth = typetype.Name != typeof(ITGConnectivity).Name; + httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; + httpsBinding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check + httpsBinding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None; + host.AddServiceEndpoint(typetype, httpsBinding, bindingName); + } + + /// + /// Shuts down all active s and calls on it's + /// + protected override void OnStop() + { + lock (this) + { + try + { + foreach (var I in hosts) + { + var host = I.Value; + var instance = (ServerInstance)host.SingletonInstance; + host.Close(); + instance.Dispose(); + UnlockLoggingID(instance.LoggingID); + } + } + catch (Exception e) + { + WriteEntry(e.ToString(), EventID.ServiceShutdownFail, EventLogEntryType.Error, LoggingID); + } + serviceHost.Close(); + } + Properties.Settings.Default.Save(); + ActiveService = null; + } + + /// + public void VerifyConnection() { } + + /// + public void PrepareForUpdate() + { + foreach (var I in hosts) + ((ServerInstance)I.Value.SingletonInstance).Reattach(false); + } + + /// + public ushort RemoteAccessPort() + { + return Properties.Settings.Default.RemoteAccessPort; + } + + /// + public string SetRemoteAccessPort(ushort port) + { + if (port == 0) + return "Cannot bind to port 0"; + Properties.Settings.Default.RemoteAccessPort = port; + return null; + } + + /// + public string Version() + { + return VersionString; + } + + /// + public bool SetPythonPath(string path) + { + if (!Directory.Exists(path)) + return false; + Properties.Settings.Default.PythonPath = Path.GetFullPath(path); + return true; + } + + /// + public string PythonPath() + { + return Properties.Settings.Default.PythonPath; + } + + /// + public IList ListInstances() + { + var result = new List(); + lock (this) + foreach (var ic in GetInstanceConfigs()) + result.Add(new InstanceMetadata + { + Name = ic.Name, + Path = ic.Directory, + Enabled = ic.Enabled, + LoggingID = (byte)(ic.Enabled ? ((ServerInstance)hosts[ic.Name].SingletonInstance).LoggingID : 0) + }); + return result; + } + + /// + public string CreateInstance(string Name, string path) + { + path = Program.NormalizePath(path); + var res = CheckInstanceName(Name); + if (res != null) + return res; + if (File.Exists(path) || Directory.Exists(path)) + return "Cannot create instance at pre-existing path!"; + var Config = Properties.Settings.Default; + lock (this) + { + if (Config.InstancePaths.Contains(path)) + return String.Format("Instance at {0} already exists!", path); + foreach (var oic in GetInstanceConfigs()) + if (Name == oic.Name) + return String.Format("Instance named {0} already exists!", oic.Name); + IInstanceConfig ic; + try + { + ic = new InstanceConfig(path) + { + Name = Name + }; + Directory.CreateDirectory(path); + ic.Save(); + Properties.Settings.Default.InstancePaths.Add(path); + } + catch (Exception e) + { + return e.ToString(); + } + return SetupOneInstance(ic); + } + } + + /// + /// Starts and onlines an instance located at + /// + /// The for the + /// on success, error message on failure + string SetupOneInstance(IInstanceConfig config) + { + if (!config.Enabled) + return null; + try + { + var host = SetupInstance(config); + if (host != null) + host.Open(); + else + lock (this) + Properties.Settings.Default.InstancePaths.Remove(config.Directory); + return null; + } + catch (Exception e) + { + return "Instance set up but an error occurred while starting it: " + e.ToString(); + } + } + + /// + public string ImportInstance(string path) + { + path = Program.NormalizePath(path); + var Config = Properties.Settings.Default; + lock (this) + { + if (Config.InstancePaths.Contains(path)) + return String.Format("Instance at {0} already exists!", path); + if(!Directory.Exists(path)) + return String.Format("There is no instance located at {0}!", path); + IInstanceConfig ic; + try + { + ic = InstanceConfig.Load(path); + foreach(var oic in GetInstanceConfigs()) + if(ic.Name == oic.Name) + return String.Format("Instance named {0} already exists!", oic.Name); + ic.Save(); + Properties.Settings.Default.InstancePaths.Add(path); + } + catch (Exception e) + { + return e.ToString(); + } + return SetupOneInstance(ic); + } + } + + /// + public bool InstanceEnabled(string Name) + { + lock(this) + { + return hosts.ContainsKey(Name); + } + } + + /// + public string SetInstanceEnabled(string Name, bool enabled) + { + return SetInstanceEnabledImpl(Name, enabled, out string path); + } + + + /// + /// Sets a 's enabled status + /// + /// The whom's status should be changed + /// to enable the , to disable it + /// The path to the modified + /// on success, error message on failure + string SetInstanceEnabledImpl(string Name, bool enabled, out string path) + { + path = null; + lock (this) + { + var hostIsOnline = hosts.ContainsKey(Name); + if (enabled) + { + if (hostIsOnline) + return null; + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == Name) + { + path = ic.Directory; + ic.Enabled = true; + ic.Save(); + return SetupOneInstance(ic); + } + return String.Format("Instance {0} does not exist!", Name); + } + else + { + if (!hostIsOnline) + return null; + var host = hosts[Name]; + hosts.Remove(Name); + var inst = (ServerInstance)host.SingletonInstance; + host.Close(); + path = inst.ServerDirectory(); + inst.Offline(); + inst.Dispose(); + UnlockLoggingID(inst.LoggingID); + return null; + } + } + } + + /// + public string RenameInstance(string name, string new_name) + { + if (name == new_name) + return null; + var res = CheckInstanceName(new_name); + if (res != null) + return res; + lock (this) + { + //we have to check em all anyway + IInstanceConfig the_droid_were_looking_for = null; + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == name) + { + the_droid_were_looking_for = ic; + break; + } + else if (ic.Name == new_name) + return String.Format("There is already another instance named {0}!", new_name); + if (the_droid_were_looking_for == null) + return String.Format("There is no instance named {0}!", name); + var ie = InstanceEnabled(name); + if(ie) + SetInstanceEnabled(name, false); + the_droid_were_looking_for.Name = new_name; + string result = ""; + try + { + the_droid_were_looking_for.Save(); + result = null; + } + catch(Exception e) + { + result = "Could not save instance config! Error: " + e.ToString(); + } + finally + { + if (ie) + { + var resRestore = SetInstanceEnabled(new_name, true); + if (resRestore != null) + result = (result + " " + resRestore).Trim(); + } + } + return result; + } + } + + /// + public string DetachInstance(string name) + { + lock (this) + { + var res = SetInstanceEnabledImpl(name, false, out string path); + if (res != null) + return res; + if (path == null) //gotta find it ourselves + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == name) + { + path = ic.Directory; + break; + } + if (path == null) + return String.Format("No instance named {0} exists!", name); + Properties.Settings.Default.InstancePaths.Remove(path); + return null; + } + } + } +} diff --git a/TGServerService/TGServerService.csproj b/TGS.Server.Service/TGS.Server.Service.csproj similarity index 97% rename from TGServerService/TGServerService.csproj rename to TGS.Server.Service/TGS.Server.Service.csproj index 71ec660335..37e2262efc 100644 --- a/TGServerService/TGServerService.csproj +++ b/TGS.Server.Service/TGS.Server.Service.csproj @@ -7,7 +7,7 @@ AnyCPU {F32EDA25-0855-411C-AF5E-F0D042917E2D} WinExe - TGServerService + TGS.Server.Service TGServerService v4.5.2 512 @@ -32,7 +32,7 @@ bin\Release\ TRACE - bin\x86\Release\TGServerService.xml + bin\x86\Release\TGS.Server.Service.xml true true pdbonly @@ -143,9 +143,9 @@ - + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface + TGS.Interface diff --git a/TGServerService/packages.config b/TGS.Server.Service/packages.config similarity index 100% rename from TGServerService/packages.config rename to TGS.Server.Service/packages.config diff --git a/TGServiceInterface/tgs.ico b/TGS.Server.Service/tgs.ico similarity index 100% rename from TGServiceInterface/tgs.ico rename to TGS.Server.Service/tgs.ico diff --git a/TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs b/TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs similarity index 86% rename from TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs rename to TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs index 0c80b404da..04d6bc1343 100644 --- a/TGServiceTests/CommandLine/Commands/Repository/RepositoryCommandTest.cs +++ b/TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs @@ -1,9 +1,9 @@ using Moq; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; using TGServiceTests; -namespace TGCommandLine.Commands.Repository.Tests +namespace TGS.CommandLine.Commands.Repository.Tests { public abstract class RepositoryCommandTest : OutputProcOverriderTest { diff --git a/TGServiceTests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs b/TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs similarity index 93% rename from TGServiceTests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs rename to TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs index 9810387d9c..54df717166 100644 --- a/TGServiceTests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs +++ b/TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs @@ -1,10 +1,10 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine.Commands.Repository.Tests +namespace TGS.CommandLine.Commands.Repository.Tests { /// /// Tests for diff --git a/TGServiceTests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs b/TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs similarity index 92% rename from TGServiceTests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs rename to TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs index 10b4656086..3efebced20 100644 --- a/TGServiceTests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs +++ b/TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs @@ -1,10 +1,10 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGCommandLine.Commands.Repository.Tests +namespace TGS.CommandLine.Commands.Repository.Tests { /// /// Tests for diff --git a/TGServiceTests/ControlPanel/TestInstanceSelector.cs b/TGS.Tests/ControlPanel/TestInstanceSelector.cs similarity index 88% rename from TGServiceTests/ControlPanel/TestInstanceSelector.cs rename to TGS.Tests/ControlPanel/TestInstanceSelector.cs index e5f9da9cd3..913d89017d 100644 --- a/TGServiceTests/ControlPanel/TestInstanceSelector.cs +++ b/TGS.Tests/ControlPanel/TestInstanceSelector.cs @@ -1,10 +1,10 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System.Collections.Generic; -using TGServiceInterface; -using TGServiceInterface.Components; +using TGS.Interface; +using TGS.Interface.Components; -namespace TGControlPanel.Tests +namespace TGS.ControlPanel.Tests { /// /// Tests for diff --git a/TGServiceTests/OutputProcOverriderTest.cs b/TGS.Tests/OutputProcOverriderTest.cs similarity index 95% rename from TGServiceTests/OutputProcOverriderTest.cs rename to TGS.Tests/OutputProcOverriderTest.cs index d118f07faf..f73a473e0a 100644 --- a/TGServiceTests/OutputProcOverriderTest.cs +++ b/TGS.Tests/OutputProcOverriderTest.cs @@ -1,5 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using TGServiceInterface; +using TGS.Interface; namespace TGServiceTests { diff --git a/TGServiceTests/Properties/AssemblyInfo.cs b/TGS.Tests/Properties/AssemblyInfo.cs similarity index 100% rename from TGServiceTests/Properties/AssemblyInfo.cs rename to TGS.Tests/Properties/AssemblyInfo.cs diff --git a/TGServiceTests/Service/ServiceAccessor.cs b/TGS.Tests/Service/ServiceAccessor.cs similarity index 93% rename from TGServiceTests/Service/ServiceAccessor.cs rename to TGS.Tests/Service/ServiceAccessor.cs index 97c20d0d78..adf073c53e 100644 --- a/TGServiceTests/Service/ServiceAccessor.cs +++ b/TGS.Tests/Service/ServiceAccessor.cs @@ -1,6 +1,6 @@  -namespace TGServerService.Tests +namespace TGS.Server.Service.Tests { /// /// For accessing service control methods of diff --git a/TGServiceTests/Service/TestInstanceConfig.cs b/TGS.Tests/Service/TestInstanceConfig.cs similarity index 97% rename from TGServiceTests/Service/TestInstanceConfig.cs rename to TGS.Tests/Service/TestInstanceConfig.cs index 586ccd4990..a319a968ef 100644 --- a/TGServiceTests/Service/TestInstanceConfig.cs +++ b/TGS.Tests/Service/TestInstanceConfig.cs @@ -2,7 +2,7 @@ using System.IO; using TGServiceTests; -namespace TGServerService.Tests +namespace TGS.Server.Service.Tests { /// /// Tests for diff --git a/TGServiceTests/Service/TestServerInstance.cs b/TGS.Tests/Service/TestServerInstance.cs similarity index 97% rename from TGServiceTests/Service/TestServerInstance.cs rename to TGS.Tests/Service/TestServerInstance.cs index e8c8629549..7888567999 100644 --- a/TGServiceTests/Service/TestServerInstance.cs +++ b/TGS.Tests/Service/TestServerInstance.cs @@ -2,7 +2,7 @@ using Moq; using TGServiceTests; -namespace TGServerService.Tests +namespace TGS.Server.Service.Tests { /// /// Tests for diff --git a/TGServiceTests/Service/TestService.cs b/TGS.Tests/Service/TestService.cs similarity index 98% rename from TGServiceTests/Service/TestService.cs rename to TGS.Tests/Service/TestService.cs index 8c19056596..249517064f 100644 --- a/TGServiceTests/Service/TestService.cs +++ b/TGS.Tests/Service/TestService.cs @@ -1,7 +1,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using TGServiceTests; -namespace TGServerService.Tests +namespace TGS.Server.Service.Tests { /// /// Tests for diff --git a/TGServiceTests/ServiceInterface/TestHelpers.cs b/TGS.Tests/ServiceInterface/TestHelpers.cs similarity index 98% rename from TGServiceTests/ServiceInterface/TestHelpers.cs rename to TGS.Tests/ServiceInterface/TestHelpers.cs index 6a0086bd7c..2742f1e854 100644 --- a/TGServiceTests/ServiceInterface/TestHelpers.cs +++ b/TGS.Tests/ServiceInterface/TestHelpers.cs @@ -1,7 +1,7 @@ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace TGServiceInterface.Tests +namespace TGS.Interface.Tests { /// /// Tests for diff --git a/TGServiceTests/ServiceInterface/TestInterface.cs b/TGS.Tests/ServiceInterface/TestInterface.cs similarity index 97% rename from TGServiceTests/ServiceInterface/TestInterface.cs rename to TGS.Tests/ServiceInterface/TestInterface.cs index f8fa81420a..cd4f55ac9d 100644 --- a/TGServiceTests/ServiceInterface/TestInterface.cs +++ b/TGS.Tests/ServiceInterface/TestInterface.cs @@ -2,9 +2,9 @@ using System.Net; using System.ServiceModel; using Microsoft.VisualStudio.TestTools.UnitTesting; -using TGServiceInterface.Components; +using TGS.Interface.Components; -namespace TGServiceInterface.Tests +namespace TGS.Interface.Tests { /// /// Tests for diff --git a/TGServiceTests/TGServiceTests.csproj b/TGS.Tests/TGS.Tests.csproj similarity index 91% rename from TGServiceTests/TGServiceTests.csproj rename to TGS.Tests/TGS.Tests.csproj index f61981f9ee..ba749c6384 100644 --- a/TGServiceTests/TGServiceTests.csproj +++ b/TGS.Tests/TGS.Tests.csproj @@ -1,116 +1,116 @@ - - - - - Debug - AnyCPU - {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971} - Library - Properties - TGServiceTests - TGServiceTests - v4.6.1 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 15.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - false - - - - ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll - - - ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - ..\packages\Moq.4.7.145\lib\net45\Moq.dll - - - - - - - - - - - - - - - - - - Component - - - - - - - - - - - - - - {89191f69-b18e-4b59-b72e-e12f9b6811a0} - TGCommandLine - - - {394e7643-6b8c-416f-ab18-95ac12648cdc} - TGControlPanel - - - {8956d4c3-bfb9-448e-bf5f-ee7e6f9996f9} - TGInstallerWrapper - - - {f32eda25-0855-411c-af5e-f0d042917e2d} - TGServerService - - - {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - + + + + + Debug + AnyCPU + {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971} + Library + Properties + TGS.Tests + TGS.Tests + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll + + + ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + ..\packages\Moq.4.7.145\lib\net45\Moq.dll + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + {89191f69-b18e-4b59-b72e-e12f9b6811a0} + TGCommandLine + + + {394e7643-6b8c-416f-ab18-95ac12648cdc} + TGControlPanel + + + {8956d4c3-bfb9-448e-bf5f-ee7e6f9996f9} + TGInstallerWrapper + + + {f32eda25-0855-411c-af5e-f0d042917e2d} + TGServerService + + + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} + TGServiceInterface + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/TGServiceTests/TempDirectoryRequiredTest.cs b/TGS.Tests/TempDirectoryRequiredTest.cs similarity index 100% rename from TGServiceTests/TempDirectoryRequiredTest.cs rename to TGS.Tests/TempDirectoryRequiredTest.cs diff --git a/TGServiceTests/packages.config b/TGS.Tests/packages.config similarity index 100% rename from TGServiceTests/packages.config rename to TGS.Tests/packages.config diff --git a/TGStationServer3.sln b/TGStationServer3.sln index 19f07e4862..8759bbedc0 100644 --- a/TGStationServer3.sln +++ b/TGStationServer3.sln @@ -3,15 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27004.2006 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGServerService", "TGServerService\TGServerService.csproj", "{F32EDA25-0855-411C-AF5E-F0D042917E2D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Service", "TGS.Server.Service\TGS.Server.Service.csproj", "{F32EDA25-0855-411C-AF5E-F0D042917E2D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGControlPanel", "TGControlPanel\TGControlPanel.csproj", "{394E7643-6B8C-416F-AB18-95AC12648CDC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.ControlPanel", "TGS.ControlPanel\TGS.ControlPanel.csproj", "{394E7643-6B8C-416F-AB18-95AC12648CDC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGCommandLine", "TGCommandLine\TGCommandLine.csproj", "{89191F69-B18E-4B59-B72E-E12F9B6811A0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.CommandLine", "TGS.CommandLine\TGS.CommandLine.csproj", "{89191F69-B18E-4B59-B72E-E12F9B6811A0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGServiceInterface", "TGServiceInterface\TGServiceInterface.csproj", "{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Interface", "TGS.Interface\TGS.Interface.csproj", "{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}" EndProject -Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "TGServiceInstaller", "TGServiceInstaller\TGServiceInstaller.wixproj", "{154435F6-0890-42D4-9AEC-B743D4FBC1CB}" +Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "TGS.Installer", "TGS.Installer\TGS.Installer.wixproj", "{154435F6-0890-42D4-9AEC-B743D4FBC1CB}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2D8FC6AA-1D33-44B6-81C2-35ED7A87EDBC}" ProjectSection(SolutionItems) = preProject @@ -24,7 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution tgs.ico = tgs.ico EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGInstallerWrapper", "TGInstallerWrapper\TGInstallerWrapper.csproj", "{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Installer.UI", "TGS.Installer.UI\TGS.Installer.UI.csproj", "{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}" ProjectSection(ProjectDependencies) = postProject {AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB} = {AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB} {154435F6-0890-42D4-9AEC-B743D4FBC1CB} = {154435F6-0890-42D4-9AEC-B743D4FBC1CB} @@ -93,9 +93,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{287B .github\CONTRIBUTING.md = .github\CONTRIBUTING.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGDreamDaemonBridge", "TGDreamDaemonBridge\TGDreamDaemonBridge.csproj", "{9A01EF03-8EAE-45CB-8B87-4A17BD904557}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Interface.Bridge", "TGS.Interface.Bridge\TGS.Interface.Bridge.csproj", "{9A01EF03-8EAE-45CB-8B87-4A17BD904557}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGServiceTests", "TGServiceTests\TGServiceTests.csproj", "{FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Tests", "TGS.Tests\TGS.Tests.csproj", "{FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Tools/CoverageExclusions.runsettings b/Tools/CoverageExclusions.runsettings index 92eee55060..9cf93cc0e8 100644 --- a/Tools/CoverageExclusions.runsettings +++ b/Tools/CoverageExclusions.runsettings @@ -10,7 +10,7 @@ - .*\\TGServiceTests\\.* + .*\\TGS.Tests\\.* diff --git a/Tools/PostCIBuild.ps1 b/Tools/PostCIBuild.ps1 index 69110e5756..5c76553308 100644 --- a/Tools/PostCIBuild.ps1 +++ b/Tools/PostCIBuild.ps1 @@ -10,12 +10,12 @@ function CodeSign #Sign the output files if (Test-Path env:snk_passphrase) { - CodeSign "$bf/TGServiceTests/bin/Release/TGServiceTests.dll" - CodeSign "$bf/TGInstallerWrapper/bin/Release/TG Station Server Installer.exe" + CodeSign "$bf/TGS.Tests/bin/Release/TGS.Tests.dll" + CodeSign "$bf/TGS.Installer.UI/bin/Release/TG Station Server Installer.exe" $env:snk_passphrase = "" } -$src = "$bf\TGInstallerWrapper\bin\Release" +$src = "$bf\TGS.Installer.UI\bin\Release" $version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$src\TG Station Server Installer.exe").FileVersion $destination = "$bf\TGS3-Server-v$version.exe" @@ -28,10 +28,10 @@ $destination_md5sha = "$bf\MD5-SHA1-Server-v$version.txt" $src2 = "$bf\ClientApps" [system.io.directory]::CreateDirectory($src2) -Copy-Item "$bf\TGCommandLine\bin\Release\TGCommandLine.exe" "$src2\TGCommandLine.exe" -Copy-Item "$bf\TGControlPanel\bin\Release\TGControlPanel.exe" "$src2\TGControlPanel.exe" -Copy-Item "$bf\TGControlPanel\bin\Release\Octokit.dll" "$src2\Octokit.dll" -Copy-Item "$bf\TGServiceInterface\bin\Release\TGServiceInterface.dll" "$src2\TGServiceInterface.dll" +Copy-Item "$bf\TGS.CommandLine\bin\Release\TGCommandLine.exe" "$src2\TGCommandLine.exe" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\TGControlPanel.exe" "$src2\TGControlPanel.exe" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\Octokit.dll" "$src2\Octokit.dll" +Copy-Item "$bf\TGS.Interface\bin\Release\TGServiceInterface.dll" "$src2\TGServiceInterface.dll" $dest2 = "$bf\TGS3-Client-v$version.zip" diff --git a/Tools/SignBasics.ps1 b/Tools/SignBasics.ps1 index a0941adb99..a87d6920c9 100644 --- a/Tools/SignBasics.ps1 +++ b/Tools/SignBasics.ps1 @@ -9,9 +9,9 @@ function CodeSign #Sign the output files if (Test-Path env:snk_passphrase) { - CodeSign "$bf/TGCommandLine/bin/Release/TGCommandLine.exe" - CodeSign "$bf/TGControlPanel/bin/Release/TGControlPanel.exe" - CodeSign "$bf/TGServerService/bin/Release/TGServerService.exe" - CodeSign "$bf/TGDreamDaemonBridge/bin/x86/Release/TGDreamDaemonBridge.dll" - CodeSign "$bf/TGServiceInterface/bin/Release/TGServiceInterface.dll" + CodeSign "$bf/TGS.CommandLine/bin/Release/TGCommandLine.exe" + CodeSign "$bf/TGS.ControlPanel/bin/Release/TGControlPanel.exe" + CodeSign "$bf/TGS.Server.Service/bin/Release/TGServerService.exe" + CodeSign "$bf/TGS.Interface.Bridge/bin/x86/Release/TGDreamDaemonBridge.dll" + CodeSign "$bf/TGS.Interface/bin/Release/TGServiceInterface.dll" } diff --git a/Tools/SignMSI.ps1 b/Tools/SignMSI.ps1 index 50d76dbdbd..dd921d188b 100644 --- a/Tools/SignMSI.ps1 +++ b/Tools/SignMSI.ps1 @@ -9,5 +9,5 @@ function CodeSign #Sign the output files if (Test-Path env:snk_passphrase) { - CodeSign "$bf/TGServiceInstaller/bin/Release/TGServiceInstaller.msi" + CodeSign "$bf/TGS.Installer/bin/Release/TGServiceInstaller.msi" } diff --git a/appveyor.yml b/appveyor.yml index 724d59cbe9..476fddd2c7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -34,11 +34,11 @@ build: after_build: - ps: Tools/PostCIBuild.ps1 - ps: if($env:APPVEYOR_REPO_COMMIT_MESSAGE -match "\[TGSDeploy\]"){$env:TGSDeploy = "Do it."} - - ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/TGServerService/bin/Release/TGServerService.exe").FileVersion + - ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/TGS.Server.Service/bin/Release/TGS.Server.Service.exe").FileVersion test_script: - set path=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\TestAgent\Common7\IDE\CommonExtensions\Microsoft\TestWindow;%path% - copy "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\appveyor.*" "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\TestAgent\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions" /y - - vstest.console /logger:Appveyor "TGServiceTests\bin\Release\TGServiceTests.dll" /Enablecodecoverage /Settings:"Tools/CoverageExclusions.runsettings" /inIsolation /Platform:x64 + - vstest.console /logger:Appveyor "TGS.Tests\bin\Release\TGS.Tests.dll" /Enablecodecoverage /Settings:"Tools/CoverageExclusions.runsettings" /inIsolation /Platform:x64 after_test: - ps: Tools/UploadCoverage.ps1 - ps: Tools/BuildDox.ps1 From 1372f2daeaed074bc0bfea788fc33aa01039fabe Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Sun, 12 Nov 2017 23:37:57 -0500 Subject: [PATCH 04/31] Split the service and server functions --- .github/CONTRIBUTING.md | 2 +- README.md | 2 +- TGS.Installer/Product.wxs | 31 +- TGS.Installer/TGS.Installer.wixproj | 8 + TGS.Server.Service/App.config | 26 +- TGS.Server.Service/Properties/AssemblyInfo.cs | 4 +- TGS.Server.Service/Service.cs | 694 +---------------- TGS.Server.Service/TGS.Server.Service.csproj | 133 +--- TGS.Server/App.config | 27 + .../ChatCommands/ByondCommand.cs | 2 +- .../ChatCommands/ChatCommand.cs | 2 +- .../ChatCommands/CommandInfo.cs | 2 +- .../ChatCommands/KekCommand.cs | 2 +- .../ChatCommands/PullRequestsCommand.cs | 2 +- .../ChatCommands/RevisionCommand.cs | 2 +- .../ChatCommands/RootChatCommand.cs | 2 +- .../ChatCommands/ServerChatCommand.cs | 4 +- .../ChatCommands/VersionCommand.cs | 2 +- .../ChatProviders/ChatProvider.cs | 2 +- .../ChatProviders/DiscordChatProvider.cs | 4 +- .../ChatProviders/IRCChatProvider.cs | 4 +- .../DeprecatedInstanceConfig.cs | 10 +- {TGS.Server.Service => TGS.Server}/EventID.cs | 8 +- .../Program.cs => TGS.Server/Helpers.cs | 16 +- TGS.Server/ILogger.cs | 39 + .../InstanceConfig.cs | 2 +- .../MessageType.cs | 2 +- .../ProcessExtension.cs | 2 +- TGS.Server/Properties/AssemblyInfo.cs | 16 + .../Properties/Settings.Designer.cs | 2 +- .../Properties/Settings.settings | 2 +- .../RepoConfig.cs | 2 +- .../RootAuthorizationManager.cs | 5 +- TGS.Server/Server.cs | 704 ++++++++++++++++++ .../ServerInstance/Administration.cs | 4 +- .../ServerInstance/Byond.cs | 8 +- .../ServerInstance/Chat.cs | 10 +- .../ServerInstance/Compiler.cs | 10 +- .../ServerInstance/Config.cs | 16 +- .../ServerInstance/DreamDaemon.cs | 4 +- .../ServerInstance/Interop.cs | 4 +- .../ServerInstance/PreactionHandler.cs | 2 +- .../ServerInstance/Repository.cs | 16 +- .../ServerInstance/ServerInstance.cs | 12 +- TGS.Server/TGS.Server.csproj | 153 ++++ .../packages.config | 0 {TGS.Server.Service => TGS.Server}/tgs.ico | Bin TGS.Tests/Service/ServiceAccessor.cs | 27 - TGS.Tests/Service/TestInstanceConfig.cs | 62 -- TGS.Tests/Service/TestServerInstance.cs | 50 -- TGS.Tests/Service/TestService.cs | 73 -- TGS.Tests/TGS.Tests.csproj | 8 +- TGStationServer3.sln | 12 +- Tools/SignBasics.ps1 | 1 + appveyor.yml | 2 +- 55 files changed, 1112 insertions(+), 1129 deletions(-) create mode 100644 TGS.Server/App.config rename {TGS.Server.Service => TGS.Server}/ChatCommands/ByondCommand.cs (95%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/ChatCommand.cs (96%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/CommandInfo.cs (94%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/KekCommand.cs (91%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/PullRequestsCommand.cs (95%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/RevisionCommand.cs (94%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/RootChatCommand.cs (94%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/ServerChatCommand.cs (93%) rename {TGS.Server.Service => TGS.Server}/ChatCommands/VersionCommand.cs (93%) rename {TGS.Server.Service => TGS.Server}/ChatProviders/ChatProvider.cs (98%) rename {TGS.Server.Service => TGS.Server}/ChatProviders/DiscordChatProvider.cs (98%) rename {TGS.Server.Service => TGS.Server}/ChatProviders/IRCChatProvider.cs (99%) rename {TGS.Server.Service => TGS.Server}/DeprecatedInstanceConfig.cs (94%) rename {TGS.Server.Service => TGS.Server}/EventID.cs (98%) rename TGS.Server.Service/Program.cs => TGS.Server/Helpers.cs (97%) create mode 100644 TGS.Server/ILogger.cs rename {TGS.Server.Service => TGS.Server}/InstanceConfig.cs (99%) rename {TGS.Server.Service => TGS.Server}/MessageType.cs (94%) rename {TGS.Server.Service => TGS.Server}/ProcessExtension.cs (98%) create mode 100644 TGS.Server/Properties/AssemblyInfo.cs rename {TGS.Server.Service => TGS.Server}/Properties/Settings.Designer.cs (98%) rename {TGS.Server.Service => TGS.Server}/Properties/Settings.settings (91%) rename {TGS.Server.Service => TGS.Server}/RepoConfig.cs (99%) rename {TGS.Server.Service => TGS.Server}/RootAuthorizationManager.cs (83%) create mode 100644 TGS.Server/Server.cs rename {TGS.Server.Service => TGS.Server}/ServerInstance/Administration.cs (98%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/Byond.cs (98%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/Chat.cs (96%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/Compiler.cs (98%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/Config.cs (95%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/DreamDaemon.cs (99%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/Interop.cs (99%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/PreactionHandler.cs (99%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/Repository.cs (99%) rename {TGS.Server.Service => TGS.Server}/ServerInstance/ServerInstance.cs (91%) create mode 100644 TGS.Server/TGS.Server.csproj rename {TGS.Server.Service => TGS.Server}/packages.config (100%) rename {TGS.Server.Service => TGS.Server}/tgs.ico (100%) delete mode 100644 TGS.Tests/Service/ServiceAccessor.cs delete mode 100644 TGS.Tests/Service/TestInstanceConfig.cs delete mode 100644 TGS.Tests/Service/TestServerInstance.cs delete mode 100644 TGS.Tests/Service/TestService.cs diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b839e64b22..b404563eeb 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -32,7 +32,7 @@ The [WiX Toolset](http://wixtoolset.org/) is used for creating the installer .ms #### Debugging -So you've built the project and everything's good, right? Now you have to debug it. Debugging the command line and control panel are easy enough, just launch them like any other process. Debugging the TGS.Server.Service itself though requires a bit of finagling due to how Windows services work. +So you've built the project and everything's good, right? Now you have to debug it. Debugging the command line and control panel are easy enough, just launch them like any other process. Debugging the TGS.Server itself though requires a bit of finagling due to how Windows services work. 1. Uninstall any release versions of TG Station Server 3 you may have on your machine 1. Open an administrative Windows cmd prompt diff --git a/README.md b/README.md index e99ccffc5f..8c1ca4f6c4 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ You can clear all active test merges using `Reset to Origin Branch` in the `Repo ### Viewing Server Logs * Logs are stored in the Windows event viewer under `Windows Logs` -> `Application`. You'll need to filter this list for `TG Station Server` -* Every event type is keyed with an ID. A complete listing of these IDs and their purpose can be found [here](https://github.com/tgstation/tgstation-server/blob/master/TGS.Server.Service/EventID.cs). +* Every event type is keyed with an ID. A complete listing of these IDs and their purpose can be found [here](https://github.com/tgstation/tgstation-server/blob/master/TGS.Server/EventID.cs). * You can also import the custom view `View TGS3 Logs.xml` in this folder to have them automatically filtered ### Enabling upstream changelog generation diff --git a/TGS.Installer/Product.wxs b/TGS.Installer/Product.wxs index a65794dd14..dfb6546fce 100644 --- a/TGS.Installer/Product.wxs +++ b/TGS.Installer/Product.wxs @@ -84,37 +84,40 @@ + + + - + - + - + - + - + - + - + - + @@ -128,24 +131,24 @@ - + - + - + - + - + - + diff --git a/TGS.Installer/TGS.Installer.wixproj b/TGS.Installer/TGS.Installer.wixproj index 6d26789638..bc81125088 100644 --- a/TGS.Installer/TGS.Installer.wixproj +++ b/TGS.Installer/TGS.Installer.wixproj @@ -50,6 +50,14 @@ TGS.Server.Service + {3f81e398-b223-4006-b40c-c2800714ce29} + True + True + Binaries;Content;Satellites + INSTALLFOLDER + + + TGS.Server {f32eda25-0855-411c-af5e-f0d042917e2d} True True diff --git a/TGS.Server.Service/App.config b/TGS.Server.Service/App.config index cfd0a6b77d..8227adb989 100644 --- a/TGS.Server.Service/App.config +++ b/TGS.Server.Service/App.config @@ -1,28 +1,6 @@ - + - - -
-
- - - + - - - - C:\Python27 - - - True - - - 7 - - - 38607 - - - diff --git a/TGS.Server.Service/Properties/AssemblyInfo.cs b/TGS.Server.Service/Properties/AssemblyInfo.cs index b7a644ae25..e4e22f2673 100644 --- a/TGS.Server.Service/Properties/AssemblyInfo.cs +++ b/TGS.Server.Service/Properties/AssemblyInfo.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("TGStation Server Service")] -[assembly: AssemblyDescription("Server Service for running BYOND games")] +[assembly: AssemblyDescription("Windows service adapter for TGStation Server")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from @@ -13,4 +13,4 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f32eda25-0855-411c-af5e-f0d042917e2d")] +[assembly: Guid("3f81e398-b223-4006-b40c-c2800714ce29")] diff --git a/TGS.Server.Service/Service.cs b/TGS.Server.Service/Service.cs index 99ec13e82e..af88d24b50 100644 --- a/TGS.Server.Service/Service.cs +++ b/TGS.Server.Service/Service.cs @@ -1,693 +1,63 @@ using System; -using System.Collections.Generic; -using System.Collections.Specialized; using System.Diagnostics; -using System.IO; -using System.Security.Principal; -using System.ServiceModel; using System.ServiceProcess; -using TGS.Interface; -using TGS.Interface.Components; namespace TGS.Server.Service { /// - /// The windows service the application runs as + /// Windows adapter for /// - [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] - class Service : ServiceBase, ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager + public sealed class Service : ServiceBase, ILogger { /// - /// The logging ID used for events + /// The entry point for the program. Calls with a new as a parameter /// - public const byte LoggingID = 0; + public static void Main() => Run(new Service()); /// - /// The service version based on the + /// The the manages /// - public static readonly string VersionString = "/tg/station 13 Server Service v" + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion; + Server activeServer; - /// - /// Singleton instance - /// - static Service ActiveService; - - /// - /// Cancels WCF's user impersonation to allow clean access to writing log files - /// - public static void CancelImpersonation() + /// + public void WriteAccess(string username, bool authSuccess, byte loggingID) { - WindowsIdentity.Impersonate(IntPtr.Zero); + EventLog.WriteEntry(String.Format("Access from: {0}", username), authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit , (int)EventID.Authentication + loggingID); + } + + /// + public void WriteError(string message, EventID id, byte loggingID) + { + EventLog.WriteEntry(message, EventLogEntryType.Error, (int)id + loggingID); + } + + /// + public void WriteInfo(string message, EventID id, byte loggingID) + { + EventLog.WriteEntry(message, EventLogEntryType.Information, (int)id + loggingID); + } + + /// + public void WriteWarning(string message, EventID id, byte loggingID) + { + EventLog.WriteEntry(message, EventLogEntryType.Warning, (int)id + loggingID); } /// - /// Writes an event to Windows the event log + /// Called when the is started. Creates a new /// - /// The log message - /// The of the message - /// The of the event - /// The logging source ID for the event - public static void WriteEntry(string message, EventID id, EventLogEntryType eventType, byte loggingID) - { - ActiveService.EventLog.WriteEntry(message, eventType, (int)id + loggingID); - } - - /// - /// Checks an for illegal characters - /// - /// The name to check - /// if contains no illegal characters, error message otherwise - static string CheckInstanceName(string instanceName) - { - char[] bannedCharacters = { ';', '&', '=', '%' }; - foreach (var I in bannedCharacters) - if (instanceName.Contains(I.ToString())) - return "Instance names may not contain the following characters: ';', '&', '=', or '%'"; - return null; - } - - /// - /// Sets up ServiceName and - /// - public Service() - { - ServiceName = "TG Station Server"; - if (ActiveService != null) - throw new Exception("There is already a Service instance running!"); - ActiveService = this; - } - - /// - /// Clears - /// - /// if this method was invoked from , otherwise it was invoked by the finalizer - protected override void Dispose(bool disposing) - { - ActiveService = null; - base.Dispose(disposing); - } - - /// - /// The WCF host that contains connects to - /// - ServiceHost serviceHost; - /// - /// Map of to the respective hosting the - /// - IDictionary hosts; - /// - /// List of s in use - /// - IList UsedLoggingIDs = new List(); - - /// - /// Migrates the .NET config from to + 1 - /// - /// The version to migrate from - void MigrateSettings(int oldVersion) - { - var Config = Properties.Settings.Default; - switch (oldVersion) - { - case 6: //switch to per-instance configs - var IC = DeprecatedInstanceConfig.CreateFromNETSettings(); - IC.Save(); - Config.InstancePaths.Add(IC.Directory); - break; - } - } - - /// - /// Enumerates configured s. Detaches those that fail to load - /// - /// Each configured - IEnumerable GetInstanceConfigs() - { - var pathsToRemove = new List(); - lock (this) - { - var IPS = Properties.Settings.Default.InstancePaths; - foreach (var I in IPS) - { - IInstanceConfig ic; - try - { - ic = InstanceConfig.Load(I); - } - catch (Exception e) - { - WriteEntry(String.Format("Unable load instance config at path {0}. Error: {1} Detaching...", I, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - pathsToRemove.Add(I); - continue; - } - yield return ic; - } - foreach (var I in pathsToRemove) - IPS.Remove(I); - } - } - - /// - /// Overrides and saves the configured if requested by command line parameters - /// - /// The command line parameters for the - void ChangePortFromCommandLine(string[] args) - { - var Config = Properties.Settings.Default; - - for (var I = 0; I < args.Length - 1; ++I) - if (args[I].ToLower() == "-port") - { - try - { - var res = Convert.ToUInt16(args[I + 1]); - if (res == 0) - throw new Exception("Cannot bind to port 0"); - Config.RemoteAccessPort = res; - } - catch (Exception e) - { - throw new Exception("Invalid argument for \"-port\"", e); - } - Config.Save(); - break; - } - } - - /// - /// Called by the Windows service manager. Initializes and starts configured s - /// - /// Command line arguments for the + /// The service start arguments protected override void OnStart(string[] args) { - Environment.CurrentDirectory = Directory.CreateDirectory(Path.GetTempPath() + "/TGStationServerService").FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png - - SetupConfig(); - - ChangePortFromCommandLine(args); - - SetupService(); - - SetupInstances(); - - OnlineAllHosts(); + activeServer = new Server(args, this); } /// - /// Writes some changes to the that always need to be done. - /// - void PrePrepConfig() - { - var Config = Properties.Settings.Default; - - if (Config.InstancePaths == null) - Config.InstancePaths = new StringCollection(); - } - - /// - /// Upgrades up the service configuration - /// - void SetupConfig() - { - var Config = Properties.Settings.Default; - if (Config.UpgradeRequired) - { - var newVersion = Config.SettingsVersion; - Config.Upgrade(); - - PrePrepConfig(); - - for (var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion) - MigrateSettings(oldVersion); - - Config.SettingsVersion = newVersion; - - Config.UpgradeRequired = false; - Config.Save(); - } - else - PrePrepConfig(); - } - - /// - /// Creates the for - /// - void SetupService() - { - serviceHost = CreateHost(this, ServerInterface.MasterInterfaceName); - foreach (var I in ServerInterface.ValidServiceInterfaces) - AddEndpoint(serviceHost, I); - serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us - } - - /// - /// Opens all created s - /// - void OnlineAllHosts() - { - serviceHost.Open(); - foreach (var I in hosts) - I.Value.Open(); - } - - /// - /// Creates a for using the default pipe, CloseTimeout for the , and the configured - /// - /// The - /// The URL to access components on the - /// The created - static ServiceHost CreateHost(object singleton, string endpointPostfix) - { - return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) - { - CloseTimeout = new TimeSpan(0, 0, 5) - }; - } - - /// - /// Creates s for all s as listed in , detaches bad ones - /// - void SetupInstances() - { - hosts = new Dictionary(); - var pathsToRemove = new List(); - var seenNames = new List(); - foreach (var I in GetInstanceConfigs()) - { - if (seenNames.Contains(I.Name)) - { - WriteEntry(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - pathsToRemove.Add(I.Directory); - } - if (I.Enabled && SetupInstance(I) == null) - pathsToRemove.Add(I.Directory); - else - seenNames.Add(I.Name); - } - foreach (var I in pathsToRemove) - Properties.Settings.Default.InstancePaths.Remove(I); - } - - /// - /// Unlocks a acquired with - /// - /// The to unlock - void UnlockLoggingID(byte ID) - { - lock (UsedLoggingIDs) - { - UsedLoggingIDs.Remove(ID); - } - } - - /// - /// Gets and locks a - /// - /// A logging ID for the must be released using - byte LockLoggingID() - { - lock (UsedLoggingIDs) - { - for (byte I = 1; I < 100; ++I) - if (!UsedLoggingIDs.Contains(I)) - { - UsedLoggingIDs.Add(I); - return I; - } - } - throw new Exception("All logging IDs in use!"); - } - - /// - /// Creates and starts a for a at - /// - /// The for the - /// The inactive on success, on failure - ServiceHost SetupInstance(IInstanceConfig config) - { - ServerInstance instance; - string instanceName; - try - { - if (hosts.ContainsKey(config.Directory)) - { - 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); - return null; - } - if (!config.Enabled) - return null; - var ID = LockLoggingID(); - WriteEntry(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, config.Directory, ID), EventID.InstanceIDAssigned, EventLogEntryType.Information, ID); - instanceName = config.Name; - instance = new ServerInstance(config, ID); - } - catch (Exception e) - { - WriteEntry(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", config.Directory, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - return null; - } - - var host = CreateHost(instance, String.Format("{0}/{1}", ServerInterface.InstanceInterfaceName, instanceName)); - hosts.Add(instanceName, host); - - foreach (var J in ServerInterface.ValidInstanceInterfaces) - AddEndpoint(host, J); - - host.Authorization.ServiceAuthorizationManager = instance; - return host; - } - - /// - /// Adds a WCF endpoint for a component - /// - /// The service host to add the component to - /// The type of the component - void AddEndpoint(ServiceHost host, Type typetype) - { - var bindingName = typetype.Name; - host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = ServerInterface.TransferLimitLocal }, bindingName); - var httpsBinding = new WSHttpBinding() - { - SendTimeout = new TimeSpan(0, 0, 40), - MaxReceivedMessageSize = ServerInterface.TransferLimitRemote - }; - var requireAuth = typetype.Name != typeof(ITGConnectivity).Name; - httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; - httpsBinding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check - httpsBinding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None; - host.AddServiceEndpoint(typetype, httpsBinding, bindingName); - } - - /// - /// Shuts down all active s and calls on it's + /// Called when the is stopped. Calls on /// protected override void OnStop() { - lock (this) - { - try - { - foreach (var I in hosts) - { - var host = I.Value; - var instance = (ServerInstance)host.SingletonInstance; - host.Close(); - instance.Dispose(); - UnlockLoggingID(instance.LoggingID); - } - } - catch (Exception e) - { - WriteEntry(e.ToString(), EventID.ServiceShutdownFail, EventLogEntryType.Error, LoggingID); - } - serviceHost.Close(); - } - Properties.Settings.Default.Save(); - ActiveService = null; - } - - /// - public void VerifyConnection() { } - - /// - public void PrepareForUpdate() - { - foreach (var I in hosts) - ((ServerInstance)I.Value.SingletonInstance).Reattach(false); - } - - /// - public ushort RemoteAccessPort() - { - return Properties.Settings.Default.RemoteAccessPort; - } - - /// - public string SetRemoteAccessPort(ushort port) - { - if (port == 0) - return "Cannot bind to port 0"; - Properties.Settings.Default.RemoteAccessPort = port; - return null; - } - - /// - public string Version() - { - return VersionString; - } - - /// - public bool SetPythonPath(string path) - { - if (!Directory.Exists(path)) - return false; - Properties.Settings.Default.PythonPath = Path.GetFullPath(path); - return true; - } - - /// - public string PythonPath() - { - return Properties.Settings.Default.PythonPath; - } - - /// - public IList ListInstances() - { - var result = new List(); - lock (this) - foreach (var ic in GetInstanceConfigs()) - result.Add(new InstanceMetadata - { - Name = ic.Name, - Path = ic.Directory, - Enabled = ic.Enabled, - LoggingID = (byte)(ic.Enabled ? ((ServerInstance)hosts[ic.Name].SingletonInstance).LoggingID : 0) - }); - return result; - } - - /// - public string CreateInstance(string Name, string path) - { - path = Program.NormalizePath(path); - var res = CheckInstanceName(Name); - if (res != null) - return res; - if (File.Exists(path) || Directory.Exists(path)) - return "Cannot create instance at pre-existing path!"; - var Config = Properties.Settings.Default; - lock (this) - { - if (Config.InstancePaths.Contains(path)) - return String.Format("Instance at {0} already exists!", path); - foreach (var oic in GetInstanceConfigs()) - if (Name == oic.Name) - return String.Format("Instance named {0} already exists!", oic.Name); - IInstanceConfig ic; - try - { - ic = new InstanceConfig(path) - { - Name = Name - }; - Directory.CreateDirectory(path); - ic.Save(); - Properties.Settings.Default.InstancePaths.Add(path); - } - catch (Exception e) - { - return e.ToString(); - } - return SetupOneInstance(ic); - } - } - - /// - /// Starts and onlines an instance located at - /// - /// The for the - /// on success, error message on failure - string SetupOneInstance(IInstanceConfig config) - { - if (!config.Enabled) - return null; - try - { - var host = SetupInstance(config); - if (host != null) - host.Open(); - else - lock (this) - Properties.Settings.Default.InstancePaths.Remove(config.Directory); - return null; - } - catch (Exception e) - { - return "Instance set up but an error occurred while starting it: " + e.ToString(); - } - } - - /// - public string ImportInstance(string path) - { - path = Program.NormalizePath(path); - var Config = Properties.Settings.Default; - lock (this) - { - if (Config.InstancePaths.Contains(path)) - return String.Format("Instance at {0} already exists!", path); - if(!Directory.Exists(path)) - return String.Format("There is no instance located at {0}!", path); - IInstanceConfig ic; - try - { - ic = InstanceConfig.Load(path); - foreach(var oic in GetInstanceConfigs()) - if(ic.Name == oic.Name) - return String.Format("Instance named {0} already exists!", oic.Name); - ic.Save(); - Properties.Settings.Default.InstancePaths.Add(path); - } - catch (Exception e) - { - return e.ToString(); - } - return SetupOneInstance(ic); - } - } - - /// - public bool InstanceEnabled(string Name) - { - lock(this) - { - return hosts.ContainsKey(Name); - } - } - - /// - public string SetInstanceEnabled(string Name, bool enabled) - { - return SetInstanceEnabledImpl(Name, enabled, out string path); - } - - - /// - /// Sets a 's enabled status - /// - /// The whom's status should be changed - /// to enable the , to disable it - /// The path to the modified - /// on success, error message on failure - string SetInstanceEnabledImpl(string Name, bool enabled, out string path) - { - path = null; - lock (this) - { - var hostIsOnline = hosts.ContainsKey(Name); - if (enabled) - { - if (hostIsOnline) - return null; - foreach (var ic in GetInstanceConfigs()) - if (ic.Name == Name) - { - path = ic.Directory; - ic.Enabled = true; - ic.Save(); - return SetupOneInstance(ic); - } - return String.Format("Instance {0} does not exist!", Name); - } - else - { - if (!hostIsOnline) - return null; - var host = hosts[Name]; - hosts.Remove(Name); - var inst = (ServerInstance)host.SingletonInstance; - host.Close(); - path = inst.ServerDirectory(); - inst.Offline(); - inst.Dispose(); - UnlockLoggingID(inst.LoggingID); - return null; - } - } - } - - /// - public string RenameInstance(string name, string new_name) - { - if (name == new_name) - return null; - var res = CheckInstanceName(new_name); - if (res != null) - return res; - lock (this) - { - //we have to check em all anyway - IInstanceConfig the_droid_were_looking_for = null; - foreach (var ic in GetInstanceConfigs()) - if (ic.Name == name) - { - the_droid_were_looking_for = ic; - break; - } - else if (ic.Name == new_name) - return String.Format("There is already another instance named {0}!", new_name); - if (the_droid_were_looking_for == null) - return String.Format("There is no instance named {0}!", name); - var ie = InstanceEnabled(name); - if(ie) - SetInstanceEnabled(name, false); - the_droid_were_looking_for.Name = new_name; - string result = ""; - try - { - the_droid_were_looking_for.Save(); - result = null; - } - catch(Exception e) - { - result = "Could not save instance config! Error: " + e.ToString(); - } - finally - { - if (ie) - { - var resRestore = SetInstanceEnabled(new_name, true); - if (resRestore != null) - result = (result + " " + resRestore).Trim(); - } - } - return result; - } - } - - /// - public string DetachInstance(string name) - { - lock (this) - { - var res = SetInstanceEnabledImpl(name, false, out string path); - if (res != null) - return res; - if (path == null) //gotta find it ourselves - foreach (var ic in GetInstanceConfigs()) - if (ic.Name == name) - { - path = ic.Directory; - break; - } - if (path == null) - return String.Format("No instance named {0} exists!", name); - Properties.Settings.Default.InstancePaths.Remove(path); - return null; - } + activeServer.Dispose(); } } } diff --git a/TGS.Server.Service/TGS.Server.Service.csproj b/TGS.Server.Service/TGS.Server.Service.csproj index 37e2262efc..cd31701a92 100644 --- a/TGS.Server.Service/TGS.Server.Service.csproj +++ b/TGS.Server.Service/TGS.Server.Service.csproj @@ -1,162 +1,63 @@  - Debug AnyCPU - {F32EDA25-0855-411C-AF5E-F0D042917E2D} + {3F81E398-B223-4006-B40C-C2800714CE29} WinExe TGS.Server.Service TGServerService v4.5.2 512 true - - - - tgs.ico - - + + AnyCPU true + full + false bin\Debug\ DEBUG;TRACE - full - AnyCPU prompt - MinimumRecommendedRules.ruleset - true + 4 - + + AnyCPU + pdbonly + true bin\Release\ TRACE - bin\x86\Release\TGS.Server.Service.xml - true - true - pdbonly - AnyCPU prompt - MinimumRecommendedRules.ruleset - true + 4 - false + TGS.Server.Service.Service - - ..\packages\Discord.Net.Core.1.0.2\lib\net45\Discord.Net.Core.dll - - - ..\packages\Discord.Net.Rest.1.0.2\lib\net45\Discord.Net.Rest.dll - - - ..\packages\Discord.Net.WebSocket.1.0.2\lib\net45\Discord.Net.WebSocket.dll - - - ..\packages\LibGit2Sharp-SSH.1.0.22\lib\net40\LibGit2Sharp.dll - - - ..\packages\SmartIrc4net.1.1\lib\Meebey.SmartIrc4net.dll - - - ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - - ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - - - - ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings - - Component Component - - + - - Designer - - - Designer - - - SettingsSingleFileGenerator - Settings.Designer.cs - + - - {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGS.Interface + + {f32eda25-0855-411c-af5e-f0d042917e2d} + TGS.Server - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - \ No newline at end of file diff --git a/TGS.Server/App.config b/TGS.Server/App.config new file mode 100644 index 0000000000..91aa70ce1c --- /dev/null +++ b/TGS.Server/App.config @@ -0,0 +1,27 @@ + + + + +
+ + + + + + + + + C:\Python27 + + + True + + + 7 + + + 38607 + + + + diff --git a/TGS.Server.Service/ChatCommands/ByondCommand.cs b/TGS.Server/ChatCommands/ByondCommand.cs similarity index 95% rename from TGS.Server.Service/ChatCommands/ByondCommand.cs rename to TGS.Server/ChatCommands/ByondCommand.cs index 5cc1a90740..b983339816 100644 --- a/TGS.Server.Service/ChatCommands/ByondCommand.cs +++ b/TGS.Server/ChatCommands/ByondCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using TGS.Interface; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// Retrieve the installed, staged, or latest availab diff --git a/TGS.Server.Service/ChatCommands/ChatCommand.cs b/TGS.Server/ChatCommands/ChatCommand.cs similarity index 96% rename from TGS.Server.Service/ChatCommands/ChatCommand.cs rename to TGS.Server/ChatCommands/ChatCommand.cs index 7137fa0447..f742fadbf6 100644 --- a/TGS.Server.Service/ChatCommands/ChatCommand.cs +++ b/TGS.Server/ChatCommands/ChatCommand.cs @@ -2,7 +2,7 @@ using System.Threading; using TGS.Interface; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// A command heard by a diff --git a/TGS.Server.Service/ChatCommands/CommandInfo.cs b/TGS.Server/ChatCommands/CommandInfo.cs similarity index 94% rename from TGS.Server.Service/ChatCommands/CommandInfo.cs rename to TGS.Server/ChatCommands/CommandInfo.cs index bc6ae15eed..4e650eaf89 100644 --- a/TGS.Server.Service/ChatCommands/CommandInfo.cs +++ b/TGS.Server/ChatCommands/CommandInfo.cs @@ -1,4 +1,4 @@ -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// Metadata about the currently running diff --git a/TGS.Server.Service/ChatCommands/KekCommand.cs b/TGS.Server/ChatCommands/KekCommand.cs similarity index 91% rename from TGS.Server.Service/ChatCommands/KekCommand.cs rename to TGS.Server/ChatCommands/KekCommand.cs index 6fe495690c..1826bf1876 100644 --- a/TGS.Server.Service/ChatCommands/KekCommand.cs +++ b/TGS.Server/ChatCommands/KekCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// kek diff --git a/TGS.Server.Service/ChatCommands/PullRequestsCommand.cs b/TGS.Server/ChatCommands/PullRequestsCommand.cs similarity index 95% rename from TGS.Server.Service/ChatCommands/PullRequestsCommand.cs rename to TGS.Server/ChatCommands/PullRequestsCommand.cs index f3046931cc..e03d426c04 100644 --- a/TGS.Server.Service/ChatCommands/PullRequestsCommand.cs +++ b/TGS.Server/ChatCommands/PullRequestsCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// Retrieve the list of test-merged github pull requests diff --git a/TGS.Server.Service/ChatCommands/RevisionCommand.cs b/TGS.Server/ChatCommands/RevisionCommand.cs similarity index 94% rename from TGS.Server.Service/ChatCommands/RevisionCommand.cs rename to TGS.Server/ChatCommands/RevisionCommand.cs index 3b91cdebd9..7fd99c0f28 100644 --- a/TGS.Server.Service/ChatCommands/RevisionCommand.cs +++ b/TGS.Server/ChatCommands/RevisionCommand.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// Retrieves the git SHA of the live DreamDaemon code diff --git a/TGS.Server.Service/ChatCommands/RootChatCommand.cs b/TGS.Server/ChatCommands/RootChatCommand.cs similarity index 94% rename from TGS.Server.Service/ChatCommands/RootChatCommand.cs rename to TGS.Server/ChatCommands/RootChatCommand.cs index 1fac6ee2ce..800147a412 100644 --- a/TGS.Server.Service/ChatCommands/RootChatCommand.cs +++ b/TGS.Server/ChatCommands/RootChatCommand.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using TGS.Interface; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// The main root chat command diff --git a/TGS.Server.Service/ChatCommands/ServerChatCommand.cs b/TGS.Server/ChatCommands/ServerChatCommand.cs similarity index 93% rename from TGS.Server.Service/ChatCommands/ServerChatCommand.cs rename to TGS.Server/ChatCommands/ServerChatCommand.cs index 0729409c1e..fee9f70eb5 100644 --- a/TGS.Server.Service/ChatCommands/ServerChatCommand.cs +++ b/TGS.Server/ChatCommands/ServerChatCommand.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// s generated by DreamDaemon via the API @@ -37,7 +37,7 @@ namespace TGS.Server.Service.ChatCommands /// protected override ExitCode Run(IList parameters) { - var res = Instance.SendCommand(String.Format("{0};sender={1};custom={2}", Keyword, CommandInfo.Value.Speaker, Program.SanitizeTopicString(String.Join(" ", parameters)))); + var res = Instance.SendCommand(String.Format("{0};sender={1};custom={2}", Keyword, CommandInfo.Value.Speaker, Helpers.SanitizeTopicString(String.Join(" ", parameters)))); if (res != "SUCCESS" && !String.IsNullOrWhiteSpace(res)) OutputProc(res); return ExitCode.Normal; diff --git a/TGS.Server.Service/ChatCommands/VersionCommand.cs b/TGS.Server/ChatCommands/VersionCommand.cs similarity index 93% rename from TGS.Server.Service/ChatCommands/VersionCommand.cs rename to TGS.Server/ChatCommands/VersionCommand.cs index afbd926c02..538bcb4e7f 100644 --- a/TGS.Server.Service/ChatCommands/VersionCommand.cs +++ b/TGS.Server/ChatCommands/VersionCommand.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TGS.Server.Service.ChatCommands +namespace TGS.Server.ChatCommands { /// /// Retrieve the current service version diff --git a/TGS.Server.Service/ChatProviders/ChatProvider.cs b/TGS.Server/ChatProviders/ChatProvider.cs similarity index 98% rename from TGS.Server.Service/ChatProviders/ChatProvider.cs rename to TGS.Server/ChatProviders/ChatProvider.cs index dbcf6d14d7..974d79eaf8 100644 --- a/TGS.Server.Service/ChatProviders/ChatProvider.cs +++ b/TGS.Server/ChatProviders/ChatProvider.cs @@ -1,7 +1,7 @@ using System; using TGS.Interface; -namespace TGS.Server.Service.ChatProviders +namespace TGS.Server.ChatProviders { /// /// Callback for the chat provider recieving a diff --git a/TGS.Server.Service/ChatProviders/DiscordChatProvider.cs b/TGS.Server/ChatProviders/DiscordChatProvider.cs similarity index 98% rename from TGS.Server.Service/ChatProviders/DiscordChatProvider.cs rename to TGS.Server/ChatProviders/DiscordChatProvider.cs index 1b2a936cb5..7809df8af9 100644 --- a/TGS.Server.Service/ChatProviders/DiscordChatProvider.cs +++ b/TGS.Server/ChatProviders/DiscordChatProvider.cs @@ -6,7 +6,7 @@ using System.Threading; using System.Threading.Tasks; using TGS.Interface; -namespace TGS.Server.Service.ChatProviders +namespace TGS.Server.ChatProviders { /// /// for Discord: https://discordapp.com/ @@ -179,7 +179,6 @@ namespace TGS.Server.Service.ChatProviders lock (DiscordLock) { var tasks = new List(); - var Config = Properties.Settings.Default; foreach (var I in client.Guilds) foreach (var J in I.TextChannels) { @@ -208,7 +207,6 @@ namespace TGS.Server.Service.ChatProviders lock (DiscordLock) { var tasks = new List(); - var Config = Properties.Settings.Default; var channel = Convert.ToUInt64(channelname); if (SeenPrivateChannels.ContainsKey(channel)) SeenPrivateChannels[channel].SendMessageAsync(message).Wait(); diff --git a/TGS.Server.Service/ChatProviders/IRCChatProvider.cs b/TGS.Server/ChatProviders/IRCChatProvider.cs similarity index 99% rename from TGS.Server.Service/ChatProviders/IRCChatProvider.cs rename to TGS.Server/ChatProviders/IRCChatProvider.cs index 550f3a1aee..9074219cec 100644 --- a/TGS.Server.Service/ChatProviders/IRCChatProvider.cs +++ b/TGS.Server/ChatProviders/IRCChatProvider.cs @@ -4,7 +4,7 @@ using System.Threading; using TGS.Interface; using Meebey.SmartIrc4net; -namespace TGS.Server.Service.ChatProviders +namespace TGS.Server.ChatProviders { /// /// for internet relay chat @@ -48,7 +48,7 @@ namespace TGS.Server.Service.ChatProviders irc = new IrcFeatures() { SupportNonRfc = true, - CtcpUserInfo = Service.VersionString, + CtcpUserInfo = Server.VersionString, AutoRejoin = true, AutoRejoinOnKick = true, AutoRelogin = true, diff --git a/TGS.Server.Service/DeprecatedInstanceConfig.cs b/TGS.Server/DeprecatedInstanceConfig.cs similarity index 94% rename from TGS.Server.Service/DeprecatedInstanceConfig.cs rename to TGS.Server/DeprecatedInstanceConfig.cs index c6127601af..3cac746331 100644 --- a/TGS.Server.Service/DeprecatedInstanceConfig.cs +++ b/TGS.Server/DeprecatedInstanceConfig.cs @@ -1,7 +1,7 @@ using System; using System.Configuration; -namespace TGS.Server.Service +namespace TGS.Server { /// /// Used to migrate old config settings @@ -19,8 +19,8 @@ namespace TGS.Server.Service /// An based off the old .NET setting file public static IInstanceConfig CreateFromNETSettings() { - var Config = Properties.Settings.Default; - var result = new DeprecatedInstanceConfig(Program.NormalizePath(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3"))); + var Config = TGServerService.Properties.Settings.Default; + var result = new DeprecatedInstanceConfig(Helpers.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); @@ -53,7 +53,7 @@ namespace TGS.Server.Service //try it the simple way first try { - var result = (T)Properties.Settings.Default.GetPreviousVersion(property); + var result = (T)TGServerService.Properties.Settings.Default.GetPreviousVersion(property); return result == null ? defaultValue : result; } catch @@ -65,7 +65,7 @@ namespace TGS.Server.Service //Which means we can never fucking delete config settings //Which is fucking retarded //This hooks into the settings provider and forces it to load it anyway - var Config = Properties.Settings.Default; + var Config = TGServerService.Properties.Settings.Default; var Provider = Config.Properties[nameof(Config.SettingsVersion)].Provider; //nameof for sanity var sp = new SettingsProperty(property) diff --git a/TGS.Server.Service/EventID.cs b/TGS.Server/EventID.cs similarity index 98% rename from TGS.Server.Service/EventID.cs rename to TGS.Server/EventID.cs index ef542764dd..0f7267594b 100644 --- a/TGS.Server.Service/EventID.cs +++ b/TGS.Server/EventID.cs @@ -1,6 +1,6 @@ using System; -namespace TGS.Server.Service +namespace TGS.Server { /// /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults @@ -76,11 +76,11 @@ namespace TGS.Server.Service /// DMCompileCancel = 1600, /// - /// Error: Failed to reattach the watchdog to a running DreamDaemon instance after a update + /// Error: Failed to reattach the watchdog to a running DreamDaemon instance after a update /// DDReattachFail = 1700, /// - /// Info: Successfully reattached the watchdog to a running DreamDaemon instance after a update + /// Info: Successfully reattached the watchdog to a running DreamDaemon instance after a update /// DDReattachSuccess = 1800, /// @@ -261,7 +261,7 @@ namespace TGS.Server.Service /// InstanceInitializationFailure = 6000, /// - /// Error: When an exception occurs while the is stopping + /// Error: When an exception occurs while the is stopping /// ServiceShutdownFail = 6100, /// diff --git a/TGS.Server.Service/Program.cs b/TGS.Server/Helpers.cs similarity index 97% rename from TGS.Server.Service/Program.cs rename to TGS.Server/Helpers.cs index 8d12789234..7cff312bca 100644 --- a/TGS.Server.Service/Program.cs +++ b/TGS.Server/Helpers.cs @@ -1,21 +1,15 @@ using System; using System.Collections.Generic; using System.IO; -using System.ServiceProcess; using System.Threading.Tasks; -namespace TGS.Server.Service +namespace TGS.Server { - static class Program + /// + /// Generic helpers for the + /// + static class Helpers { - /// - /// Entry point to the program - /// - static void Main() { - using (var S = new Service()) - ServiceBase.Run(S); - } - /// /// Copy a file from to , but first ensure the destination directory exists /// diff --git a/TGS.Server/ILogger.cs b/TGS.Server/ILogger.cs new file mode 100644 index 0000000000..b63246f06a --- /dev/null +++ b/TGS.Server/ILogger.cs @@ -0,0 +1,39 @@ +namespace TGS.Server +{ + /// + /// Used for writing logs to a provider + /// + public interface ILogger + { + /// + /// Writes information to the log + /// + /// The log message + /// The of the message + /// The 0-99 ID of the log source + void WriteInfo(string message, EventID id, byte loggingID); + + /// + /// Writes an error to the log + /// + /// The log message + /// The of the message + /// The 0-99 ID of the log source + void WriteError(string message, EventID id, byte loggingID); + + /// + /// Writes a warning to the log + /// + /// The log message + /// The of the message + /// The 0-99 ID of the log source + void WriteWarning(string message, EventID id, byte loggingID); + /// + /// Writes an access event to the log + /// + /// The (un)authenticated Windows user's name + /// if authenticated sucessfully, otherwise + /// The 0-99 ID of the log source + void WriteAccess(string username, bool authSuccess, byte loggingID); + } +} diff --git a/TGS.Server.Service/InstanceConfig.cs b/TGS.Server/InstanceConfig.cs similarity index 99% rename from TGS.Server.Service/InstanceConfig.cs rename to TGS.Server/InstanceConfig.cs index d824c418c0..11d2469192 100644 --- a/TGS.Server.Service/InstanceConfig.cs +++ b/TGS.Server/InstanceConfig.cs @@ -2,7 +2,7 @@ using System.Web.Script.Serialization; using TGS.Interface; -namespace TGS.Server.Service +namespace TGS.Server { /// /// Configuration settings for a diff --git a/TGS.Server.Service/MessageType.cs b/TGS.Server/MessageType.cs similarity index 94% rename from TGS.Server.Service/MessageType.cs rename to TGS.Server/MessageType.cs index 803a3fb4a5..72d930bb0e 100644 --- a/TGS.Server.Service/MessageType.cs +++ b/TGS.Server/MessageType.cs @@ -1,6 +1,6 @@ using System; -namespace TGS.Server.Service +namespace TGS.Server { /// /// Type of chat message, these may be OR'd together diff --git a/TGS.Server.Service/ProcessExtension.cs b/TGS.Server/ProcessExtension.cs similarity index 98% rename from TGS.Server.Service/ProcessExtension.cs rename to TGS.Server/ProcessExtension.cs index fab7bebdcc..0d24a8351c 100644 --- a/TGS.Server.Service/ProcessExtension.cs +++ b/TGS.Server/ProcessExtension.cs @@ -2,7 +2,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; -namespace TGS.Server.Service +namespace TGS.Server { /// /// Helpers to ing and a . Lightly massaged code from https://stackoverflow.com/a/13109774. Documentation linked from MSDN on 20/10/2017 diff --git a/TGS.Server/Properties/AssemblyInfo.cs b/TGS.Server/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..5dc00523b0 --- /dev/null +++ b/TGS.Server/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TGStation Server")] +[assembly: AssemblyDescription("Server management suite for running BYOND games")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f32eda25-0855-411c-af5e-f0d042917e2d")] diff --git a/TGS.Server.Service/Properties/Settings.Designer.cs b/TGS.Server/Properties/Settings.Designer.cs similarity index 98% rename from TGS.Server.Service/Properties/Settings.Designer.cs rename to TGS.Server/Properties/Settings.Designer.cs index 9b807e1637..1bbb0d95f0 100644 --- a/TGS.Server.Service/Properties/Settings.Designer.cs +++ b/TGS.Server/Properties/Settings.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace TGS.Server.Service.Properties { +namespace TGServerService.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/TGS.Server.Service/Properties/Settings.settings b/TGS.Server/Properties/Settings.settings similarity index 91% rename from TGS.Server.Service/Properties/Settings.settings rename to TGS.Server/Properties/Settings.settings index 3770ccac32..d3f9248e61 100644 --- a/TGS.Server.Service/Properties/Settings.settings +++ b/TGS.Server/Properties/Settings.settings @@ -1,5 +1,5 @@  - + diff --git a/TGS.Server.Service/RepoConfig.cs b/TGS.Server/RepoConfig.cs similarity index 99% rename from TGS.Server.Service/RepoConfig.cs rename to TGS.Server/RepoConfig.cs index d3b7cf2d5b..91a165171f 100644 --- a/TGS.Server.Service/RepoConfig.cs +++ b/TGS.Server/RepoConfig.cs @@ -4,7 +4,7 @@ using System.IO; using System.Linq; using System.Web.Script.Serialization; -namespace TGS.Server.Service +namespace TGS.Server { /// /// Repository specific information for a diff --git a/TGS.Server.Service/RootAuthorizationManager.cs b/TGS.Server/RootAuthorizationManager.cs similarity index 83% rename from TGS.Server.Service/RootAuthorizationManager.cs rename to TGS.Server/RootAuthorizationManager.cs index 4c62acb8a7..8d80dc48ed 100644 --- a/TGS.Server.Service/RootAuthorizationManager.cs +++ b/TGS.Server/RootAuthorizationManager.cs @@ -1,12 +1,11 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Security.Principal; using System.ServiceModel; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { /// /// A used to determine only if the caller is an admin @@ -33,7 +32,7 @@ namespace TGS.Server.Service if (LastSeenUser != user) { LastSeenUser = user; - Service.WriteEntry(String.Format("Root access from: {0}", user), EventID.Authentication, authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, Service.LoggingID); + Server.Logger.WriteAccess(String.Format("Root access from: {0}", user), authSuccess, Server.LoggingID); } return authSuccess; } diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs new file mode 100644 index 0000000000..71278e7ec8 --- /dev/null +++ b/TGS.Server/Server.cs @@ -0,0 +1,704 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Security.Principal; +using System.ServiceModel; +using TGS.Interface; +using TGS.Interface.Components; + +namespace TGS.Server +{ + /// + /// The windows service the application runs as + /// + [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] + public sealed class Server : ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager, IDisposable + { + /// + /// The logging ID used for events + /// + public const byte LoggingID = 0; + + /// + /// The service version based on the + /// + public static readonly string VersionString = "/tg/station 13 Server Service v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion; + + /// + /// Singleton + /// + public static ILogger Logger { get; private set; } + + /// + /// Cancels WCF's user impersonation to allow clean access to writing log files + /// + public static void CancelImpersonation() + { + WindowsIdentity.Impersonate(IntPtr.Zero); + } + + /// + /// Checks an for illegal characters + /// + /// The name to check + /// if contains no illegal characters, error message otherwise + static string CheckInstanceName(string instanceName) + { + char[] bannedCharacters = { ';', '&', '=', '%' }; + foreach (var I in bannedCharacters) + if (instanceName.Contains(I.ToString())) + return "Instance names may not contain the following characters: ';', '&', '=', or '%'"; + return null; + } + + /// + /// The WCF host that contains connects to + /// + ServiceHost serviceHost; + /// + /// Map of to the respective hosting the + /// + IDictionary hosts; + /// + /// List of s in use + /// + IList UsedLoggingIDs = new List(); + + /// + /// Construct a + /// + /// Command line arguments for the + /// The to use + public Server(string[] args, ILogger logger) + { + Environment.CurrentDirectory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name)).FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png + + SetupConfig(); + + ChangePortFromCommandLine(args); + + SetupService(); + + SetupInstances(); + + OnlineAllHosts(); + } + + /// + /// Migrates the .NET config from to + 1 + /// + /// The version to migrate from + void MigrateSettings(int oldVersion) + { + var Config = TGServerService.Properties.Settings.Default; + switch (oldVersion) + { + case 6: //switch to per-instance configs + var IC = DeprecatedInstanceConfig.CreateFromNETSettings(); + IC.Save(); + Config.InstancePaths.Add(IC.Directory); + break; + } + } + + /// + /// Enumerates configured s. Detaches those that fail to load + /// + /// Each configured + IEnumerable GetInstanceConfigs() + { + var pathsToRemove = new List(); + lock (this) + { + var IPS = TGServerService.Properties.Settings.Default.InstancePaths; + foreach (var I in IPS) + { + IInstanceConfig ic; + try + { + ic = InstanceConfig.Load(I); + } + catch (Exception e) + { + Logger.WriteError(String.Format("Unable load instance config at path {0}. Error: {1} Detaching...", I, e.ToString()), EventID.InstanceInitializationFailure, LoggingID); + pathsToRemove.Add(I); + continue; + } + yield return ic; + } + foreach (var I in pathsToRemove) + IPS.Remove(I); + } + } + + /// + /// Overrides and saves the configured if requested by command line parameters + /// + /// The command line parameters for the + void ChangePortFromCommandLine(string[] args) + { + var Config = TGServerService.Properties.Settings.Default; + + for (var I = 0; I < args.Length - 1; ++I) + if (args[I].ToLower() == "-port") + { + try + { + var res = Convert.ToUInt16(args[I + 1]); + if (res == 0) + throw new Exception("Cannot bind to port 0"); + Config.RemoteAccessPort = res; + } + catch (Exception e) + { + throw new Exception("Invalid argument for \"-port\"", e); + } + Config.Save(); + break; + } + } + + /// + /// Writes some changes to the that always need to be done. + /// + void PrePrepConfig() + { + var Config = TGServerService.Properties.Settings.Default; + + if (Config.InstancePaths == null) + Config.InstancePaths = new StringCollection(); + } + + /// + /// Upgrades up the service configuration + /// + void SetupConfig() + { + var Config = TGServerService.Properties.Settings.Default; + if (Config.UpgradeRequired) + { + var newVersion = Config.SettingsVersion; + Config.Upgrade(); + + PrePrepConfig(); + + for (var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion) + MigrateSettings(oldVersion); + + Config.SettingsVersion = newVersion; + + Config.UpgradeRequired = false; + Config.Save(); + } + else + PrePrepConfig(); + } + + /// + /// Creates the for + /// + void SetupService() + { + serviceHost = CreateHost(this, ServerInterface.MasterInterfaceName); + foreach (var I in ServerInterface.ValidServiceInterfaces) + AddEndpoint(serviceHost, I); + serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us + } + + /// + /// Opens all created s + /// + void OnlineAllHosts() + { + serviceHost.Open(); + foreach (var I in hosts) + I.Value.Open(); + } + + /// + /// Creates a for using the default pipe, CloseTimeout for the , and the configured + /// + /// The + /// The URL to access components on the + /// The created + static ServiceHost CreateHost(object singleton, string endpointPostfix) + { + return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", TGServerService.Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) + { + CloseTimeout = new TimeSpan(0, 0, 5) + }; + } + + /// + /// Creates s for all s as listed in , detaches bad ones + /// + void SetupInstances() + { + hosts = new Dictionary(); + var pathsToRemove = new List(); + var seenNames = new List(); + foreach (var I in GetInstanceConfigs()) + { + if (seenNames.Contains(I.Name)) + { + Logger.WriteError(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, LoggingID); + pathsToRemove.Add(I.Directory); + } + if (I.Enabled && SetupInstance(I) == null) + pathsToRemove.Add(I.Directory); + else + seenNames.Add(I.Name); + } + foreach (var I in pathsToRemove) + TGServerService.Properties.Settings.Default.InstancePaths.Remove(I); + } + + /// + /// Unlocks a acquired with + /// + /// The to unlock + void UnlockLoggingID(byte ID) + { + lock (UsedLoggingIDs) + { + UsedLoggingIDs.Remove(ID); + } + } + + /// + /// Gets and locks a + /// + /// A logging ID for the must be released using + byte LockLoggingID() + { + lock (UsedLoggingIDs) + { + for (byte I = 1; I < 100; ++I) + if (!UsedLoggingIDs.Contains(I)) + { + UsedLoggingIDs.Add(I); + return I; + } + } + throw new Exception("All logging IDs in use!"); + } + + /// + /// Creates and starts a for a at + /// + /// The for the + /// The inactive on success, on failure + ServiceHost SetupInstance(IInstanceConfig config) + { + ServerInstance instance; + string instanceName; + try + { + if (hosts.ContainsKey(config.Directory)) + { + var datInstance = ((ServerInstance)hosts[config.Directory].SingletonInstance); + Logger.WriteError(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, LoggingID); + return null; + } + if (!config.Enabled) + return null; + var ID = LockLoggingID(); + Logger.WriteInfo(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, config.Directory, ID), EventID.InstanceIDAssigned, ID); + instanceName = config.Name; + instance = new ServerInstance(config, ID); + } + catch (Exception e) + { + Logger.WriteError(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", config.Directory, e.ToString()), EventID.InstanceInitializationFailure, LoggingID); + return null; + } + + var host = CreateHost(instance, String.Format("{0}/{1}", ServerInterface.InstanceInterfaceName, instanceName)); + hosts.Add(instanceName, host); + + foreach (var J in ServerInterface.ValidInstanceInterfaces) + AddEndpoint(host, J); + + host.Authorization.ServiceAuthorizationManager = instance; + return host; + } + + /// + /// Adds a WCF endpoint for a component + /// + /// The service host to add the component to + /// The type of the component + void AddEndpoint(ServiceHost host, Type typetype) + { + var bindingName = typetype.Name; + host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = ServerInterface.TransferLimitLocal }, bindingName); + var httpsBinding = new WSHttpBinding() + { + SendTimeout = new TimeSpan(0, 0, 40), + MaxReceivedMessageSize = ServerInterface.TransferLimitRemote + }; + var requireAuth = typetype.Name != typeof(ITGConnectivity).Name; + httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; + httpsBinding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check + httpsBinding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None; + host.AddServiceEndpoint(typetype, httpsBinding, bindingName); + } + + /// + /// Shuts down all active s and calls on it's + /// + void OnStop() + { + lock (this) + { + try + { + foreach (var I in hosts) + { + var host = I.Value; + var instance = (ServerInstance)host.SingletonInstance; + host.Close(); + instance.Dispose(); + UnlockLoggingID(instance.LoggingID); + } + } + catch (Exception e) + { + Logger.WriteError(e.ToString(), EventID.ServiceShutdownFail, LoggingID); + } + serviceHost.Close(); + } + TGServerService.Properties.Settings.Default.Save(); + } + + /// + public void VerifyConnection() { } + + /// + public void PrepareForUpdate() + { + foreach (var I in hosts) + ((ServerInstance)I.Value.SingletonInstance).Reattach(false); + } + + /// + public ushort RemoteAccessPort() + { + return TGServerService.Properties.Settings.Default.RemoteAccessPort; + } + + /// + public string SetRemoteAccessPort(ushort port) + { + if (port == 0) + return "Cannot bind to port 0"; + TGServerService.Properties.Settings.Default.RemoteAccessPort = port; + return null; + } + + /// + public string Version() + { + return VersionString; + } + + /// + public bool SetPythonPath(string path) + { + if (!Directory.Exists(path)) + return false; + TGServerService.Properties.Settings.Default.PythonPath = Path.GetFullPath(path); + return true; + } + + /// + public string PythonPath() + { + return TGServerService.Properties.Settings.Default.PythonPath; + } + + /// + public IList ListInstances() + { + var result = new List(); + lock (this) + foreach (var ic in GetInstanceConfigs()) + result.Add(new InstanceMetadata + { + Name = ic.Name, + Path = ic.Directory, + Enabled = ic.Enabled, + LoggingID = (byte)(ic.Enabled ? ((ServerInstance)hosts[ic.Name].SingletonInstance).LoggingID : 0) + }); + return result; + } + + /// + public string CreateInstance(string Name, string path) + { + path = Helpers.NormalizePath(path); + var res = CheckInstanceName(Name); + if (res != null) + return res; + if (File.Exists(path) || Directory.Exists(path)) + return "Cannot create instance at pre-existing path!"; + var Config = TGServerService.Properties.Settings.Default; + lock (this) + { + if (Config.InstancePaths.Contains(path)) + return String.Format("Instance at {0} already exists!", path); + foreach (var oic in GetInstanceConfigs()) + if (Name == oic.Name) + return String.Format("Instance named {0} already exists!", oic.Name); + IInstanceConfig ic; + try + { + ic = new InstanceConfig(path) + { + Name = Name + }; + Directory.CreateDirectory(path); + ic.Save(); + TGServerService.Properties.Settings.Default.InstancePaths.Add(path); + } + catch (Exception e) + { + return e.ToString(); + } + return SetupOneInstance(ic); + } + } + + /// + /// Starts and onlines an instance located at + /// + /// The for the + /// on success, error message on failure + string SetupOneInstance(IInstanceConfig config) + { + if (!config.Enabled) + return null; + try + { + var host = SetupInstance(config); + if (host != null) + host.Open(); + else + lock (this) + TGServerService.Properties.Settings.Default.InstancePaths.Remove(config.Directory); + return null; + } + catch (Exception e) + { + return "Instance set up but an error occurred while starting it: " + e.ToString(); + } + } + + /// + public string ImportInstance(string path) + { + path = Helpers.NormalizePath(path); + var Config = TGServerService.Properties.Settings.Default; + lock (this) + { + if (Config.InstancePaths.Contains(path)) + return String.Format("Instance at {0} already exists!", path); + if(!Directory.Exists(path)) + return String.Format("There is no instance located at {0}!", path); + IInstanceConfig ic; + try + { + ic = InstanceConfig.Load(path); + foreach(var oic in GetInstanceConfigs()) + if(ic.Name == oic.Name) + return String.Format("Instance named {0} already exists!", oic.Name); + ic.Save(); + TGServerService.Properties.Settings.Default.InstancePaths.Add(path); + } + catch (Exception e) + { + return e.ToString(); + } + return SetupOneInstance(ic); + } + } + + /// + public bool InstanceEnabled(string Name) + { + lock(this) + { + return hosts.ContainsKey(Name); + } + } + + /// + public string SetInstanceEnabled(string Name, bool enabled) + { + return SetInstanceEnabledImpl(Name, enabled, out string path); + } + + + /// + /// Sets a 's enabled status + /// + /// The whom's status should be changed + /// to enable the , to disable it + /// The path to the modified + /// on success, error message on failure + string SetInstanceEnabledImpl(string Name, bool enabled, out string path) + { + path = null; + lock (this) + { + var hostIsOnline = hosts.ContainsKey(Name); + if (enabled) + { + if (hostIsOnline) + return null; + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == Name) + { + path = ic.Directory; + ic.Enabled = true; + ic.Save(); + return SetupOneInstance(ic); + } + return String.Format("Instance {0} does not exist!", Name); + } + else + { + if (!hostIsOnline) + return null; + var host = hosts[Name]; + hosts.Remove(Name); + var inst = (ServerInstance)host.SingletonInstance; + host.Close(); + path = inst.ServerDirectory(); + inst.Offline(); + inst.Dispose(); + UnlockLoggingID(inst.LoggingID); + return null; + } + } + } + + /// + public string RenameInstance(string name, string new_name) + { + if (name == new_name) + return null; + var res = CheckInstanceName(new_name); + if (res != null) + return res; + lock (this) + { + //we have to check em all anyway + IInstanceConfig the_droid_were_looking_for = null; + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == name) + { + the_droid_were_looking_for = ic; + break; + } + else if (ic.Name == new_name) + return String.Format("There is already another instance named {0}!", new_name); + if (the_droid_were_looking_for == null) + return String.Format("There is no instance named {0}!", name); + var ie = InstanceEnabled(name); + if(ie) + SetInstanceEnabled(name, false); + the_droid_were_looking_for.Name = new_name; + string result = ""; + try + { + the_droid_were_looking_for.Save(); + result = null; + } + catch(Exception e) + { + result = "Could not save instance config! Error: " + e.ToString(); + } + finally + { + if (ie) + { + var resRestore = SetInstanceEnabled(new_name, true); + if (resRestore != null) + result = (result + " " + resRestore).Trim(); + } + } + return result; + } + } + + /// + public string DetachInstance(string name) + { + lock (this) + { + var res = SetInstanceEnabledImpl(name, false, out string path); + if (res != null) + return res; + if (path == null) //gotta find it ourselves + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == name) + { + path = ic.Directory; + break; + } + if (path == null) + return String.Format("No instance named {0} exists!", name); + TGServerService.Properties.Settings.Default.InstancePaths.Remove(path); + return null; + } + } + + #region IDisposable Support + /// + /// To detect redundant calls + /// + private bool disposedValue = false; + + /// + /// Implements the pattern. Calls + /// + /// if was called manually, if it was from the finalizer + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + OnStop(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. + // TODO: set large fields to null. + + disposedValue = true; + } + } + + // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. + // ~Server() { + // // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + // Dispose(false); + // } + + /// + /// Implements the pattern + /// + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + // TODO: uncomment the following line if the finalizer is overridden above. + // GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/TGS.Server.Service/ServerInstance/Administration.cs b/TGS.Server/ServerInstance/Administration.cs similarity index 98% rename from TGS.Server.Service/ServerInstance/Administration.cs rename to TGS.Server/ServerInstance/Administration.cs index 03b7caf1c3..eb8a4b3c2e 100644 --- a/TGS.Server.Service/ServerInstance/Administration.cs +++ b/TGS.Server/ServerInstance/Administration.cs @@ -6,7 +6,7 @@ using System.Threading; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { //note this only works with MACHINE LOCAL groups and admins for now //if someone wants AD shit, code it yourself @@ -26,7 +26,7 @@ namespace TGS.Server.Service string LastSeenUser; /// - /// The of the account the is running as + /// The of the account the is running as /// readonly SecurityIdentifier ServiceSID = WindowsIdentity.GetCurrent().User; diff --git a/TGS.Server.Service/ServerInstance/Byond.cs b/TGS.Server/ServerInstance/Byond.cs similarity index 98% rename from TGS.Server.Service/ServerInstance/Byond.cs rename to TGS.Server/ServerInstance/Byond.cs index bd00bfb10f..fa725720ad 100644 --- a/TGS.Server.Service/ServerInstance/Byond.cs +++ b/TGS.Server/ServerInstance/Byond.cs @@ -8,7 +8,7 @@ using System.Threading; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { sealed partial class ServerInstance : ITGByond { @@ -88,7 +88,7 @@ namespace TGS.Server.Service //linger not if (File.Exists(rrdp)) File.Delete(rrdp); - Program.DeleteDirectory(RelativePath(StagingDirectory)); + Helpers.DeleteDirectory(RelativePath(StagingDirectory)); } /// @@ -326,9 +326,9 @@ namespace TGS.Server.Service try { var rbd = RelativePath(ByondDirectory); - Program.DeleteDirectory(rbd); + Helpers.DeleteDirectory(rbd); Directory.Move(RelativePath(StagingDirectoryInner), rbd); - Program.DeleteDirectory(RelativePath(StagingDirectory)); + Helpers.DeleteDirectory(RelativePath(StagingDirectory)); lastError = null; SendMessage("BYOND: Update completed!", MessageType.DeveloperInfo); WriteInfo(String.Format("BYOND update {0} completed!", GetVersion(ByondVersion.Installed)), EventID.BYONDUpdateComplete); diff --git a/TGS.Server.Service/ServerInstance/Chat.cs b/TGS.Server/ServerInstance/Chat.cs similarity index 96% rename from TGS.Server.Service/ServerInstance/Chat.cs rename to TGS.Server/ServerInstance/Chat.cs index 8c6bb66464..396c15a5f2 100644 --- a/TGS.Server.Service/ServerInstance/Chat.cs +++ b/TGS.Server/ServerInstance/Chat.cs @@ -2,12 +2,12 @@ using System.Linq; using System.Collections.Generic; using System.Web.Script.Serialization; -using TGS.Server.Service.ChatCommands; -using TGS.Server.Service.ChatProviders; +using TGS.Server.ChatCommands; +using TGS.Server.ChatProviders; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { sealed partial class ServerInstance : ITGChat { @@ -114,7 +114,7 @@ namespace TGS.Server.Service var rawdata = new JavaScriptSerializer().Serialize(infosList); - Config.ChatProviderData = Helpers.EncryptData(rawdata, out string entrp); + Config.ChatProviderData = Interface.Helpers.EncryptData(rawdata, out string entrp); Config.ChatProviderEntropy = entrp; } @@ -142,7 +142,7 @@ namespace TGS.Server.Service string plaintext; try { - plaintext = Helpers.DecryptData(rawdata, Config.ChatProviderEntropy); + plaintext = Interface.Helpers.DecryptData(rawdata, Config.ChatProviderEntropy); var lists = new JavaScriptSerializer().Deserialize>>(plaintext); var output = new List(lists.Count); diff --git a/TGS.Server.Service/ServerInstance/Compiler.cs b/TGS.Server/ServerInstance/Compiler.cs similarity index 98% rename from TGS.Server.Service/ServerInstance/Compiler.cs rename to TGS.Server/ServerInstance/Compiler.cs index dd5a2867ea..d503e921ff 100644 --- a/TGS.Server.Service/ServerInstance/Compiler.cs +++ b/TGS.Server/ServerInstance/Compiler.cs @@ -9,7 +9,7 @@ using System.Threading; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { sealed partial class ServerInstance : ITGCompiler { @@ -178,7 +178,7 @@ namespace TGS.Server.Service { SendMessage("DM: Setting up symlinks...", MessageType.DeveloperInfo); CleanGameFolder(); - Program.DeleteDirectory(RelativePath(GameDir)); + Helpers.DeleteDirectory(RelativePath(GameDir)); Directory.CreateDirectory(RelativePath(GameDirA)); Directory.CreateDirectory(RelativePath(GameDirB)); @@ -350,7 +350,7 @@ namespace TGS.Server.Service var deleteExcludeList = new List { BridgeDLLName }; deleteExcludeList.AddRange(Config.StaticDirectoryPaths); deleteExcludeList.AddRange(Config.DLLPaths); - Program.DeleteDirectory(resurrectee, true, deleteExcludeList); + Helpers.DeleteDirectory(resurrectee, true, deleteExcludeList); Directory.CreateDirectory(resurrectee + "/.git/logs"); @@ -372,11 +372,11 @@ namespace TGS.Server.Service CreateSymlink(Path.Combine(resurrectee, BridgeDLLName), RelativePath(BridgeDLLName)); deleteExcludeList.Add(".git"); - Program.CopyDirectory(RelativePath(RepoPath), resurrectee, deleteExcludeList); + Helpers.CopyDirectory(RelativePath(RepoPath), resurrectee, deleteExcludeList); CurrentSha = GetHead(false, out string error); //just the tip const string GitLogsDir = "/.git/logs"; - Program.CopyDirectory(RelativePath(RepoPath + GitLogsDir), resurrectee + GitLogsDir); + Helpers.CopyDirectory(RelativePath(RepoPath + GitLogsDir), resurrectee + GitLogsDir); try { File.Copy(RelativePath(PRJobFile), Path.Combine(resurrectee, PRJobFile)); diff --git a/TGS.Server.Service/ServerInstance/Config.cs b/TGS.Server/ServerInstance/Config.cs similarity index 95% rename from TGS.Server.Service/ServerInstance/Config.cs rename to TGS.Server/ServerInstance/Config.cs index af81f094cc..41cad7cfe0 100644 --- a/TGS.Server.Service/ServerInstance/Config.cs +++ b/TGS.Server/ServerInstance/Config.cs @@ -4,7 +4,7 @@ using System.IO; using System.ServiceModel; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { //knobs and such sealed partial class ServerInstance : ITGConfig @@ -75,7 +75,7 @@ namespace TGS.Server.Service } var output = File.ReadAllText(path); - Service.CancelImpersonation(); + Server.CancelImpersonation(); WriteInfo("Read of " + path, EventID.StaticRead); error = null; unauthorized = false; @@ -92,7 +92,7 @@ namespace TGS.Server.Service catch (Exception e) { error = e.ToString(); - Service.CancelImpersonation(); + Server.CancelImpersonation(); WriteWarning(String.Format("Read of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); unauthorized = false; return null; @@ -131,7 +131,7 @@ namespace TGS.Server.Service Directory.CreateDirectory(destdir); File.WriteAllText(path, data); - Service.CancelImpersonation(); + Server.CancelImpersonation(); WriteInfo("Write to " + path, EventID.StaticWrite); unauthorized = false; return null; @@ -146,7 +146,7 @@ namespace TGS.Server.Service catch (Exception e) { unauthorized = false; - Service.CancelImpersonation(); + Server.CancelImpersonation(); WriteWarning(String.Format("Write of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); return e.ToString(); } @@ -184,8 +184,8 @@ namespace TGS.Server.Service if (fi.Exists) File.Delete(path); else if (Directory.Exists(path)) - Program.DeleteDirectory(path); - Service.CancelImpersonation(); + Helpers.DeleteDirectory(path); + Server.CancelImpersonation(); WriteInfo("Delete of " + path, EventID.StaticDelete); unauthorized = false; return null; @@ -200,7 +200,7 @@ namespace TGS.Server.Service catch (Exception e) { unauthorized = false; - Service.CancelImpersonation(); + Server.CancelImpersonation(); WriteWarning(String.Format("Delete of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); return e.ToString(); } diff --git a/TGS.Server.Service/ServerInstance/DreamDaemon.cs b/TGS.Server/ServerInstance/DreamDaemon.cs similarity index 99% rename from TGS.Server.Service/ServerInstance/DreamDaemon.cs rename to TGS.Server/ServerInstance/DreamDaemon.cs index 1682f4b7a5..02290aa7e4 100644 --- a/TGS.Server.Service/ServerInstance/DreamDaemon.cs +++ b/TGS.Server/ServerInstance/DreamDaemon.cs @@ -8,7 +8,7 @@ using System.Timers; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { //manages the dd window. //It's not possible to actually click it while starting it in CL mode, so in order to change visibility, security, etc. It restarts the process when the world reboots @@ -721,7 +721,7 @@ namespace TGS.Server.Service /// public string WorldAnnounce(string message) { - var res = SendCommand(SCWorldAnnounce + ";message=" + Program.SanitizeTopicString(message)); + var res = SendCommand(SCWorldAnnounce + ";message=" + Helpers.SanitizeTopicString(message)); if (res == "SUCCESS") return null; return res; diff --git a/TGS.Server.Service/ServerInstance/Interop.cs b/TGS.Server/ServerInstance/Interop.cs similarity index 99% rename from TGS.Server.Service/ServerInstance/Interop.cs rename to TGS.Server/ServerInstance/Interop.cs index 621b0502cc..96d3f5a5d3 100644 --- a/TGS.Server.Service/ServerInstance/Interop.cs +++ b/TGS.Server/ServerInstance/Interop.cs @@ -6,11 +6,11 @@ using System.Text; using System.Threading; using System.Web.Script.Serialization; using System.Web.Security; -using TGS.Server.Service.ChatCommands; +using TGS.Server.ChatCommands; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { //handles talking between the world and us sealed partial class ServerInstance : ITGInterop diff --git a/TGS.Server.Service/ServerInstance/PreactionHandler.cs b/TGS.Server/ServerInstance/PreactionHandler.cs similarity index 99% rename from TGS.Server.Service/ServerInstance/PreactionHandler.cs rename to TGS.Server/ServerInstance/PreactionHandler.cs index f3991ef8f6..0026c4495e 100644 --- a/TGS.Server.Service/ServerInstance/PreactionHandler.cs +++ b/TGS.Server/ServerInstance/PreactionHandler.cs @@ -2,7 +2,7 @@ using System.Diagnostics; using System.IO; -namespace TGS.Server.Service +namespace TGS.Server { // Some useful functions for triggering pre action events sealed partial class ServerInstance diff --git a/TGS.Server.Service/ServerInstance/Repository.cs b/TGS.Server/ServerInstance/Repository.cs similarity index 99% rename from TGS.Server.Service/ServerInstance/Repository.cs rename to TGS.Server/ServerInstance/Repository.cs index 4ff01a7cb9..70b7bd89a0 100644 --- a/TGS.Server.Service/ServerInstance/Repository.cs +++ b/TGS.Server/ServerInstance/Repository.cs @@ -10,7 +10,7 @@ using System.Web.Script.Serialization; using TGS.Interface; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { sealed partial class ServerInstance : ITGRepository, IDisposable { @@ -231,7 +231,7 @@ namespace TGS.Server.Service try { DisposeRepo(); - Program.DeleteDirectory(RelativePath(RepoPath)); + Helpers.DeleteDirectory(RelativePath(RepoPath)); DeletePRList(); lock (configLock) { @@ -311,9 +311,9 @@ namespace TGS.Server.Service newFullPath = Path.Combine(path, tempDirName); } - Program.CopyDirectory(rsd, newFullPath); + Helpers.CopyDirectory(rsd, newFullPath); } - Program.DeleteDirectory(rsd); + Helpers.DeleteDirectory(rsd); } /// @@ -352,7 +352,7 @@ namespace TGS.Server.Service var source = Path.Combine(RelativePath(RepoPath), I); var dest = Path.Combine(RelativePath(StaticDirs), I); if (Directory.Exists(source)) - Program.CopyDirectory(source, dest); + Helpers.CopyDirectory(source, dest); else Directory.CreateDirectory(dest); } @@ -372,7 +372,7 @@ namespace TGS.Server.Service continue; } var dest = Path.Combine(RelativePath(StaticDirs), I); - Program.CopyFileForceDirectories(source, dest, false); + Helpers.CopyFileForceDirectories(source, dest, false); } catch { @@ -712,7 +712,7 @@ namespace TGS.Server.Service //kill off the modules/ folder in .git and try again try { - Program.DeleteDirectory(String.Format("{0}/.git/modules/{1}", RepoPath, I.Path)); + Helpers.DeleteDirectory(String.Format("{0}/.git/modules/{1}", RepoPath, I.Path)); } catch { @@ -1271,7 +1271,7 @@ namespace TGS.Server.Service return null; } - var Config = Properties.Settings.Default; + var Config = TGServerService.Properties.Settings.Default; var PythonFile = Path.Combine(Config.PythonPath, "python.exe"); if (!File.Exists(PythonFile)) diff --git a/TGS.Server.Service/ServerInstance/ServerInstance.cs b/TGS.Server/ServerInstance/ServerInstance.cs similarity index 91% rename from TGS.Server.Service/ServerInstance/ServerInstance.cs rename to TGS.Server/ServerInstance/ServerInstance.cs index 64ef3506ca..19eed58dc7 100644 --- a/TGS.Server.Service/ServerInstance/ServerInstance.cs +++ b/TGS.Server/ServerInstance/ServerInstance.cs @@ -4,7 +4,7 @@ using System.IO; using System.ServiceModel; using TGS.Interface.Components; -namespace TGS.Server.Service +namespace TGS.Server { //I know the fact that this is one massive partial class is gonna trigger everyone //There really was no other succinct way to do it (<= He's lying through his teeth, don't listen to him) @@ -62,7 +62,7 @@ namespace TGS.Server.Service /// The of the message void WriteInfo(string message, EventID id) { - Service.WriteEntry(message, id, EventLogEntryType.Information, LoggingID); + Server.Logger.WriteInfo(message, id, LoggingID); } /// @@ -72,7 +72,7 @@ namespace TGS.Server.Service /// The of the message void WriteError(string message, EventID id) { - Service.WriteEntry(message, id, EventLogEntryType.Error, LoggingID); + Server.Logger.WriteError(message, id, LoggingID); } /// @@ -82,7 +82,7 @@ namespace TGS.Server.Service /// The of the message void WriteWarning(string message, EventID id) { - Service.WriteEntry(message, id, EventLogEntryType.Warning, LoggingID); + Server.Logger.WriteWarning(message, id, LoggingID); } /// @@ -92,7 +92,7 @@ namespace TGS.Server.Service /// if authenticated sucessfully, otherwise void WriteAccess(string username, bool authSuccess) { - Service.WriteEntry(String.Format("Access from: {0}", username), EventID.Authentication, authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, LoggingID); + Server.Logger.WriteAccess(String.Format("Access from: {0}", username), authSuccess, LoggingID); } /// @@ -107,7 +107,7 @@ namespace TGS.Server.Service /// public string Version() { - return Service.VersionString; + return Server.VersionString; } /// diff --git a/TGS.Server/TGS.Server.csproj b/TGS.Server/TGS.Server.csproj new file mode 100644 index 0000000000..8841b1a5fa --- /dev/null +++ b/TGS.Server/TGS.Server.csproj @@ -0,0 +1,153 @@ + + + + + + Debug + AnyCPU + {F32EDA25-0855-411C-AF5E-F0D042917E2D} + Library + TGS.Server + TGS.Server + v4.5.2 + 512 + true + + + + + + tgs.ico + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\ + TRACE + bin\x86\Release\TGS.Server.xml + true + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + false + + + + + + + ..\packages\Discord.Net.Core.1.0.2\lib\net45\Discord.Net.Core.dll + + + ..\packages\Discord.Net.Rest.1.0.2\lib\net45\Discord.Net.Rest.dll + + + ..\packages\Discord.Net.WebSocket.1.0.2\lib\net45\Discord.Net.WebSocket.dll + + + ..\packages\LibGit2Sharp-SSH.1.0.22\lib\net40\LibGit2Sharp.dll + + + ..\packages\SmartIrc4net.1.1\lib\Meebey.SmartIrc4net.dll + + + ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + + + + ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + + + ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Settings.settings + + + + + + + + + Designer + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} + TGS.Interface + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/TGS.Server.Service/packages.config b/TGS.Server/packages.config similarity index 100% rename from TGS.Server.Service/packages.config rename to TGS.Server/packages.config diff --git a/TGS.Server.Service/tgs.ico b/TGS.Server/tgs.ico similarity index 100% rename from TGS.Server.Service/tgs.ico rename to TGS.Server/tgs.ico diff --git a/TGS.Tests/Service/ServiceAccessor.cs b/TGS.Tests/Service/ServiceAccessor.cs deleted file mode 100644 index adf073c53e..0000000000 --- a/TGS.Tests/Service/ServiceAccessor.cs +++ /dev/null @@ -1,27 +0,0 @@ - - -namespace TGS.Server.Service.Tests -{ - /// - /// For accessing service control methods of - /// - class ServiceAccessor : Service - { - /// - /// Fake a start up - /// - /// Fake commandline parameters passed to - public void FakeStart(string[] args) - { - OnStart(args); - } - - /// - /// Fake a shutdown - /// - public void FakeStop() - { - OnStop(); - } - } -} diff --git a/TGS.Tests/Service/TestInstanceConfig.cs b/TGS.Tests/Service/TestInstanceConfig.cs deleted file mode 100644 index a319a968ef..0000000000 --- a/TGS.Tests/Service/TestInstanceConfig.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.IO; -using TGServiceTests; - -namespace TGS.Server.Service.Tests -{ - /// - /// Tests for - /// - [TestClass] - public class TestInstanceConfig : TempDirectoryRequiredTest - { - /// - /// The path to the JSON at - /// - string InstanceJSONPath { get { return Path.Combine(TempPath, InstanceConfig.JSONFilename); } } - - /// - /// Creates a default at - /// - /// - IInstanceConfig CreateTempConfig() - { - return new InstanceConfig(TempPath); - } - - /// - /// Test that can execute successfully and doesn't automatically save - /// - [TestMethod] - public void TestCreate() - { - var IC = CreateTempConfig(); - Assert.IsFalse(File.Exists(InstanceJSONPath)); - } - - /// - /// Test that works correctly - /// - [TestMethod] - public void TestSave() - { - var IC = CreateTempConfig(); - IC.Save(); - Assert.IsTrue(File.Exists(InstanceJSONPath)); - } - - /// - /// Test that works correctly - /// - [TestMethod] - public void TestLoad() - { - var IC = CreateTempConfig(); - var name = "asdf"; - IC.Name = name; - IC.Save(); - var IC2 = InstanceConfig.Load(TempPath); - Assert.AreEqual(name, IC2.Name); - } - } -} diff --git a/TGS.Tests/Service/TestServerInstance.cs b/TGS.Tests/Service/TestServerInstance.cs deleted file mode 100644 index 7888567999..0000000000 --- a/TGS.Tests/Service/TestServerInstance.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using TGServiceTests; - -namespace TGS.Server.Service.Tests -{ - /// - /// Tests for - /// - [TestClass] - public class TestServerInstance : TempDirectoryRequiredTest - { - /// - /// Test a can be created and destroyed successfully with a basic - /// - [TestMethod] - public void TestBasicInstantiation() - { - new ServerInstance(new InstanceConfig(TempPath), 1).Dispose(); - } - - /// - /// Test the return value of - /// - [TestMethod] - public void TestPushTestMergeCommits() - { - var ic = new InstanceConfig(TempPath) { PushTestmergeCommits = false }; - using (var si = new ServerInstance(ic, 1)) - { - Assert.IsFalse(si.PushTestmergeCommits()); - ic.PushTestmergeCommits = true; - Assert.IsTrue(si.PushTestmergeCommits()); - } - } - - [TestMethod] - public void TestSetPushTestMergeCommits() - { - var ic = new InstanceConfig(TempPath) { PushTestmergeCommits = false }; - using (var si = new ServerInstance(ic, 1)) - { - si.SetPushTestmergeCommits(true); - Assert.IsTrue(ic.PushTestmergeCommits); - si.SetPushTestmergeCommits(false); - Assert.IsFalse(ic.PushTestmergeCommits); - } - } - } -} diff --git a/TGS.Tests/Service/TestService.cs b/TGS.Tests/Service/TestService.cs deleted file mode 100644 index 249517064f..0000000000 --- a/TGS.Tests/Service/TestService.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TGServiceTests; - -namespace TGS.Server.Service.Tests -{ - /// - /// Tests for - /// - [TestClass] - public class TestService : TempDirectoryRequiredTest - { - /// - /// Test can execute successfully - /// - [TestMethod] - public void TestInstantiation() - { - new Service().Dispose(); - } - - /// - /// Starts and stops a - /// - void StartStopServiceBasic() - { - using (var S = new ServiceAccessor()) - { - S.FakeStart(new string[] { }); - S.FakeStop(); - } - } - - /// - /// Test and can execute successfully - /// - [TestMethod] - public void TestStartupAndShutdown() - { - StartStopServiceBasic(); - } - - /// - /// Test and can execute successfully with a commandline port override - /// - [TestMethod] - public void TestCommandLinePortSet() - { - Properties.Settings.Default.RemoteAccessPort = 11111; - using (var S = new ServiceAccessor()) - { - S.FakeStart(new string[] { "-port", "36785" }); - S.FakeStop(); - } - Assert.AreEqual(Properties.Settings.Default.RemoteAccessPort, 36785); - } - - /// - /// Test that the .NET config is always initialized regardless of - /// - [TestMethod] - public void TestNETConfigIsAlwaysPrepped() - { - Properties.Settings.Default.UpgradeRequired = true; - Properties.Settings.Default.InstancePaths = null; - StartStopServiceBasic(); - Assert.IsNotNull(Properties.Settings.Default.InstancePaths); - Properties.Settings.Default.UpgradeRequired = false; - Properties.Settings.Default.InstancePaths = null; - StartStopServiceBasic(); - Assert.IsNotNull(Properties.Settings.Default.InstancePaths); - } - } -} diff --git a/TGS.Tests/TGS.Tests.csproj b/TGS.Tests/TGS.Tests.csproj index ba749c6384..1c470a65a3 100644 --- a/TGS.Tests/TGS.Tests.csproj +++ b/TGS.Tests/TGS.Tests.csproj @@ -68,12 +68,6 @@ - - Component - - - - @@ -94,7 +88,7 @@ {8956d4c3-bfb9-448e-bf5f-ee7e6f9996f9} TGInstallerWrapper - + {f32eda25-0855-411c-af5e-f0d042917e2d} TGServerService diff --git a/TGStationServer3.sln b/TGStationServer3.sln index 8759bbedc0..12df2c84d9 100644 --- a/TGStationServer3.sln +++ b/TGStationServer3.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27004.2006 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Service", "TGS.Server.Service\TGS.Server.Service.csproj", "{F32EDA25-0855-411C-AF5E-F0D042917E2D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server", "TGS.Server\TGS.Server.csproj", "{F32EDA25-0855-411C-AF5E-F0D042917E2D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.ControlPanel", "TGS.ControlPanel\TGS.ControlPanel.csproj", "{394E7643-6B8C-416F-AB18-95AC12648CDC}" EndProject @@ -97,6 +97,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Interface.Bridge", "TGS EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Tests", "TGS.Tests\TGS.Tests.csproj", "{FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Service", "TGS.Server.Service\TGS.Server.Service.csproj", "{3F81E398-B223-4006-B40C-C2800714CE29}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -159,6 +161,14 @@ Global {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971}.Release|Any CPU.ActiveCfg = Release|Any CPU {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971}.Release|Any CPU.Build.0 = Release|Any CPU {FB693FFB-17E3-4E84-8CBF-6FFA9C8FD971}.Release-Client|Any CPU.ActiveCfg = Release|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Debug-Client|Any CPU.ActiveCfg = Debug|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Debug-Client|Any CPU.Build.0 = Debug|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Release|Any CPU.Build.0 = Release|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Release-Client|Any CPU.ActiveCfg = Release|Any CPU + {3F81E398-B223-4006-B40C-C2800714CE29}.Release-Client|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Tools/SignBasics.ps1 b/Tools/SignBasics.ps1 index a87d6920c9..65765abd26 100644 --- a/Tools/SignBasics.ps1 +++ b/Tools/SignBasics.ps1 @@ -11,6 +11,7 @@ if (Test-Path env:snk_passphrase) { CodeSign "$bf/TGS.CommandLine/bin/Release/TGCommandLine.exe" CodeSign "$bf/TGS.ControlPanel/bin/Release/TGControlPanel.exe" + CodeSign "$bf/TGS.Server/bin/Release/TGS.Server.dll" CodeSign "$bf/TGS.Server.Service/bin/Release/TGServerService.exe" CodeSign "$bf/TGS.Interface.Bridge/bin/x86/Release/TGDreamDaemonBridge.dll" CodeSign "$bf/TGS.Interface/bin/Release/TGServiceInterface.dll" diff --git a/appveyor.yml b/appveyor.yml index 476fddd2c7..ba5b51e4b9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -34,7 +34,7 @@ build: after_build: - ps: Tools/PostCIBuild.ps1 - ps: if($env:APPVEYOR_REPO_COMMIT_MESSAGE -match "\[TGSDeploy\]"){$env:TGSDeploy = "Do it."} - - ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/TGS.Server.Service/bin/Release/TGS.Server.Service.exe").FileVersion + - ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/TGS.Server/bin/Release/TGS.Server.dll").FileVersion test_script: - set path=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\TestAgent\Common7\IDE\CommonExtensions\Microsoft\TestWindow;%path% - copy "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\appveyor.*" "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\TestAgent\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions" /y From c9120131aced50da62287a4df6a06e9ad77dedf7 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 00:22:07 -0500 Subject: [PATCH 05/31] Added console server runner --- TGS.Server.Console/App.config | 6 ++ TGS.Server.Console/Program.cs | 60 ++++++++++++++ TGS.Server.Console/Properties/AssemblyInfo.cs | 16 ++++ TGS.Server.Console/TGS.Server.Console.csproj | 82 +++++++++++++++++++ TGS.Server.Console/app.manifest | 76 +++++++++++++++++ TGStationServer3.sln | 10 +++ 6 files changed, 250 insertions(+) create mode 100644 TGS.Server.Console/App.config create mode 100644 TGS.Server.Console/Program.cs create mode 100644 TGS.Server.Console/Properties/AssemblyInfo.cs create mode 100644 TGS.Server.Console/TGS.Server.Console.csproj create mode 100644 TGS.Server.Console/app.manifest diff --git a/TGS.Server.Console/App.config b/TGS.Server.Console/App.config new file mode 100644 index 0000000000..731f6de6c2 --- /dev/null +++ b/TGS.Server.Console/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TGS.Server.Console/Program.cs b/TGS.Server.Console/Program.cs new file mode 100644 index 0000000000..980514ebb1 --- /dev/null +++ b/TGS.Server.Console/Program.cs @@ -0,0 +1,60 @@ +using System; + +namespace TGS.Server.Console +{ + /// + /// Console runner for a + /// + sealed class Program : ILogger + { + /// + /// Entry point to the + /// + /// + static void Main(string[] args) => new Program(args); + + /// + /// Construct and run a + /// + /// Command line arguments + Program(string[] args) + { + System.Console.WriteLine("Starting server..."); + var server = new Server(args, this); //no using to avoid including more references + try + { + System.Console.WriteLine("Server started!"); + System.Console.Write("Press any key to exit..."); + System.Console.ReadKey(); + } + finally + { + server.Dispose(); + } + } + + /// + public void WriteAccess(string username, bool authSuccess, byte loggingID) + { + System.Console.WriteLine(String.Format("[{0}]: {1}: Authentication {3} from {2}", DateTime.UtcNow.ToString(), EventID.Authentication + loggingID, username, authSuccess ? "success" : "fail")); + } + + /// + public void WriteError(string message, EventID id, byte loggingID) + { + System.Console.WriteLine(String.Format("[{0}]: {1}: ERROR: {2}", DateTime.UtcNow.ToString(), id + loggingID, message)); + } + + /// + public void WriteInfo(string message, EventID id, byte loggingID) + { + System.Console.WriteLine(String.Format("[{0}]: {1}: Warning: {2}", DateTime.UtcNow.ToString(), id + loggingID, message)); + } + + /// + public void WriteWarning(string message, EventID id, byte loggingID) + { + System.Console.WriteLine(String.Format("[{0}]: {1}: {2}", DateTime.UtcNow.ToString(), id + loggingID, message)); + } + } +} diff --git a/TGS.Server.Console/Properties/AssemblyInfo.cs b/TGS.Server.Console/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..0ce360e6d0 --- /dev/null +++ b/TGS.Server.Console/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TGStation Server Console")] +[assembly: AssemblyDescription("Console adapter for TGStation Server")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("509433f6-aefb-44ca-bfe3-c782166d2cc3")] diff --git a/TGS.Server.Console/TGS.Server.Console.csproj b/TGS.Server.Console/TGS.Server.Console.csproj new file mode 100644 index 0000000000..d54ef24d2d --- /dev/null +++ b/TGS.Server.Console/TGS.Server.Console.csproj @@ -0,0 +1,82 @@ + + + + + Debug + AnyCPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3} + Exe + TGS.Server.Console + TGS.Server.Console + v4.6.1 + 512 + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + app.manifest + + + + + + + + + + + + + + + {f32eda25-0855-411c-af5e-f0d042917e2d} + TGS.Server + + + + + False + Microsoft .NET Framework 4.6.1 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/TGS.Server.Console/app.manifest b/TGS.Server.Console/app.manifest new file mode 100644 index 0000000000..467015914e --- /dev/null +++ b/TGS.Server.Console/app.manifest @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TGStationServer3.sln b/TGStationServer3.sln index 12df2c84d9..b3a2cb5f16 100644 --- a/TGStationServer3.sln +++ b/TGStationServer3.sln @@ -99,6 +99,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Tests", "TGS.Tests\TGS. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Service", "TGS.Server.Service\TGS.Server.Service.csproj", "{3F81E398-B223-4006-B40C-C2800714CE29}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Console", "TGS.Server.Console\TGS.Server.Console.csproj", "{509433F6-AEFB-44CA-BFE3-C782166D2CC3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -169,6 +171,14 @@ Global {3F81E398-B223-4006-B40C-C2800714CE29}.Release|Any CPU.Build.0 = Release|Any CPU {3F81E398-B223-4006-B40C-C2800714CE29}.Release-Client|Any CPU.ActiveCfg = Release|Any CPU {3F81E398-B223-4006-B40C-C2800714CE29}.Release-Client|Any CPU.Build.0 = Release|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Debug-Client|Any CPU.ActiveCfg = Debug|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Debug-Client|Any CPU.Build.0 = Debug|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Release|Any CPU.Build.0 = Release|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Release-Client|Any CPU.ActiveCfg = Release|Any CPU + {509433F6-AEFB-44CA-BFE3-C782166D2CC3}.Release-Client|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 3d4e3f0872db8c9f3528697ad0a18b2d18621ce0 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 00:22:53 -0500 Subject: [PATCH 06/31] Add missing icons to Console and Service --- TGS.Server.Console/TGS.Server.Console.csproj | 6 ++++++ TGS.Server.Console/tgs.ico | Bin 0 -> 123198 bytes TGS.Server.Service/TGS.Server.Service.csproj | 6 ++++++ TGS.Server.Service/tgs.ico | Bin 0 -> 123198 bytes 4 files changed, 12 insertions(+) create mode 100644 TGS.Server.Console/tgs.ico create mode 100644 TGS.Server.Service/tgs.ico diff --git a/TGS.Server.Console/TGS.Server.Console.csproj b/TGS.Server.Console/TGS.Server.Console.csproj index d54ef24d2d..a3186f56c2 100644 --- a/TGS.Server.Console/TGS.Server.Console.csproj +++ b/TGS.Server.Console/TGS.Server.Console.csproj @@ -49,6 +49,9 @@ app.manifest + + tgs.ico + @@ -78,5 +81,8 @@ false + + + \ No newline at end of file diff --git a/TGS.Server.Console/tgs.ico b/TGS.Server.Console/tgs.ico new file mode 100644 index 0000000000000000000000000000000000000000..6ed69fadfcdf8deb049f66dfffc46d5361332feb GIT binary patch literal 123198 zcmeHQ2b>f|_HG1(QxxyiJH1mu&xnDbAQ>bqf<%dugM>v;q9P!>AR-bJ0TGd8IK_aX z2#5hz#f;%jFx}~`r~lK_Logl)QvdI(nVPNX?V0K7shQnbrhdPk?y0V>diCn-SFc{Z zs&<@mPDSUKV;r2TJ0mJMP7lX%PB zX4{+n+bBCg5VM}LHT8#F$viu1R(UX^)tZ+V_Gx?kJFQ0BSK&->jo zecN3mM)kc^4DH@rEW2%nSTJ*<7}B+=xUyR_F|boZaasN9&s zh;pEBOrtZae1USrH3Qp=F@rjaZ~pUd@%5MgC$2(XU7MdHx?WO4^lDQ}4DZoGG&=Lh zFD||4PhcZ@>PM_~5;_BpuAV zX^pCa&+yq^IW>AHEX@4(t~{e7{E={PkDy%f5YL+>p-V z=E)-kcp&&p&(<|hYH`8w%fY7uqx!a$&pfx`(a`hXe+Tl4!vB8$NsR2%Myy_P3+mTF z@EJY}IzDB+pIEa}CVuv*N1~qpcGuTp@hy|Z^;ca1`kRQ4Klqzi|Hx{#3G47_t6G1! zsotp-53=qI&&7SdsrcY;Z^=6F89v+Q!aokh_5S?vgFT;@k@%7H_iim7dtjNEdEGF< zXZURE+9%vhoDAsHKz#c555)5u!}a&z-`K&O#KM~=$@=jbKHI**sTVapr|MSLXKvm# zV$QUy#o)`E2-SY$(0=b|?Kh%VOVQ}8D&T+Bt-#Vnt!kg(bZTA6OsOvHqVc1Fuzh z{sHB#0?vkYYJA42mz;O3ELZ;l9-N#yCsqPKX5n4?>XP%1U5oP8qOM;7Z?n)|l@O;t z;uKbLLOVhJ*Zn|!G1+-^WT0Wa7P(}^v+^9;2hNn$Ko-4qU>EQ3(;Ne%~DG%`I zYs4+*J*Mf<@YHDoJ2$M-&n4g7W!*M&qEiig1AYcVZtMk?iD#K7+f4nhTRjx7{xdCP z*FZjd>x}X4Y~}xX)5kfLaW$}0gY$utop?te_ZkS)N1)9`>pCY&oZmWQoQxaLv4MPd z`n9ho+Fe|Y*xEUuWBv0FM;^>eg_U>Ac0T^_y>h+V);SeqD&JjGW9&nkMb^QqW?m=#R0PIhM>^pVG+pm|qYkr^7X0JG9XQ?-YgR6j@LeZ@SP_Z4kwIpARtbg^iE>Mf@GIRE3>?eG_yaE9TrVTJoxHwF;CmKcd|l zUD2ktYzDN?7+~Pni>j3uQ?KqTAN}vw#q(Er>Svih+MoU5v@!h!^I%@>Ep=EXdjH~P37$j0w4Mw{S$5U&($PDp=L{=`4< zdHYS*iq~Iy4tbm^`OiGNwKz8idR`0Q^9$9+khfCSke7bnFZP{$Z~8z-RPvU2GVd3k z+i)0k)SOToRHB|JmMxee=H-u}o*=G*?xf_y%Uhoo4Iyv5K?ikO)I8n+*6N~8pLT9?hL{YUitorpr<9lSLdmyJ|Ng$rgE9^Mi>G`;-}7nD zoSJnZ`_NA{mhu5I*4elBf93EV-i^Lm>Z3CzUMY3AJLXIkKmG8%WI1uO`H3}R`h+23 z9CRXGK2ygdO_yA7+}-WBS5Sfd~#}4j@qmx*% zXqLEf;!yN6^(EffztsP8C1QR*^Kk1DETivbb)6xXH#ru38wI|vY<}+VUPYVB_m1x) z56V{_MgJ?3=AXdtSHZ89$a~b_E{%_cE~UsWcE0D%xz6j`o-c>GABE?}W6bdbvBd*z z%ew7X{~Mfs#1Fv9_~AWU9<}MQzm!`zYf`cNVnqN)4#o}@(Kk&;-}(*ut98IxE_AS5 z=vwR0R^NaR)6t(*#P}yxHjbDsoV`vpdF*kjI{DC++(*oZwHpOad51@#Q%N4o^PrO_ z$9vV0t~ri~9)*FFB{pip4h{KIQ7Zai2B0 zIkI;fnH=N3Gogn!zj{FX+IY`S2A*m{p3Z~*`n76LwB>(+uZ4ZuU09Q8n3m7*S!Oc4 zXA6^}Wm@2$xUG)*y@B@Jhqm4YJ*E(4eFJPARAs9(Fm(|9`!`I(w0wro0=LyMMm8#c z(#W39a~szl2Hej>zJfBCvY+p9eICFxuc=S+;C1v7O3P=V56pXJ{lkY{JAzh(#NneI z?>NvUocnY|6wQP0oq$Uv}!TNtW(5;&|z-8cBs^+IIf0l z6yJZh8)L}3#ge%RFTlmi=qGaX#|=9E>i(BSSkb=WY0&Q*4u;%{!WH%9+$&niI@dnQk-GVT{re-` z?E4sdQ~xJz>m);mSK^xRY8{l9J()JwO&S|A`>#f2w_^nLanqdE zw87H(d6FNhe8{Vrs_e<6FUxHgjAoEyB$KXBlH9K-C}yH^}McrcQl z7fa{m$?~ro(L+4_#DjADp~`1jEOf%K%VqyKv|F>YATQoiyeEFpmqqf6RemIa$Hmfl z(<0@+ymb@D9+9?XSeKc@=lZL99RvKXQFZ4#NBbDZWGW<6K6UUtK89)cABkIZ1sJ;E-cz+I`e} z$TC@W$Hu4Mt$0saP8mbnpdJ#H&oK_i&unA7-+0H4kk`v^pNa9wW;_x3Gf0PZ( zQ`M1Wb!`0Sxh(tjm!7TIw(iMm!g~49KbSXcscnHP2lFPfZ1ppJ{168^U3t8h_mTh9 z88}|gy`r@oi&Fp08#^$neD=GX%b;9=&PF@DhyFEH&d-oW=Dp?Vb>*i|xKb4xb%xGE z8*X2`p9iQ*!Oke4tBLv3$4R}C??vG!A$tt0q5u2^_9u?Zsf+6R zCv|t^eSmqhj93A7DB2uPhiv>8vC4Mf!E4qH{kG)A;@Oi0=O$n~mNs5qvrNvJP#4$r zZJmAl93{^pak!8E?|b0!dg%K#t{Kq&xA!l*wfwxi#N|c^&@RAZr+dqDDlh zXn4kv`yoTVM4NmGT_R#zK>YWJ8x0#^1;}+Rr{I^cH*kDV0lNMT$os#L-J3Dq&BYvO zEzDolLRq<&HK@KBH2$|$?LXYmw|%_|u(A6pQ0%S7*%NWlaqhSRF%U<@PH}qjb_!${H(*ZLS$NZR6(C4oqIgZNM(R@ZoSql+hCGtsx_9Y3Yjwcfje|Bn9WrcZe7d4(Rr9GP&%idf z6Sm^h(brj_A9iwQ+w&VL!OpY{xR(4TUF;|ILvIWAmwb0QpNn~Bd9A1Qy5=*iC(FP* z=du@`Szl@8qMMVd!=3Y|Ifb8mSONN8f4rAJlEx5S4W(@bV+6s2J|ndGQWD%SVLezDbgcfLeezKS(qIxO->&MN z1AS#oMd+~&(MPVrm}0lW0DW>^c=k!L0ptFA@0<(T=1Q9i=N&meLfatcYY!g$6 z$I7%Ta&8#77Wah@UPFfv>mFPoUV46mz_?Lxj)Zk!nO$4dSOq<$;r#ru6@g!=OUJ4U zN^)rV!npTn%x5%%Y+D80jJDL4_F0mQLOGlpqr-L8A+g+?0tAO+Smd!r_ zy5^IhF+64}k`s#mihgB#q|QkCy#o18+VwF~NUvkQ>Im_L^wK^@yCm&`x;=$ulcxUd zFMbkOJYm)1;_n6e5GQZkp!1>M?xHTM=+)2U7j19_o7Y8br}5~gZv^#o=0P6Q2E+R6 z2gfH$7w3CTpSGtSy;n4by*R3D&_voW?l^yj$2g@2WF%x3eL;5V&+(dcGjG^drJvi5 zci)K2OUI)>WE%<1F>s#rne`8eH(%Z&-q`kB_;_ACyZ&JTeOl`OYyRUe>&Pr=_BwR4$SGuHjYO>ZT@vmDktsDlu7i* z@Cr{nv=Z%u`4o(aD98A&(+|*%1JZ_fp*CrChoRk?Iq2F};( z^z(WxWP%?2(yu=g@7jz0#~)l?j1JO98cFP`#UYxJuS1^!%;`6W9{8pEouS;Izm*Z0XG1qDjvJ=sJek|>Z<~I~8}<`?e@Xwx@4qYU ztn`s_^OXNdE9C4l=$1!aacP~&=vRJr>+h61^u<&DOR3~P{lG{Uc}@C1+WD?5jy^lI za~Ac*N?$=RedgP58oT~xkY_7>xTCn@9m2^ z*^%oY^i!v%J(l)j(xMKQMSMU%hCkZ}QM9u_(m-0GF(T(fcH^1$tC!5F0>8t}dfj-< zzK^=RuE(niq>la%qv&VfM;fB~VbDhUNHfMBRsIAYY0Nha#2lUUEl~9!-Z*!M@s}by zat=a&Ec|eefV@@sp@3DzR|-d~nY8Wc~}nY4}_-1%72zV5;0&dXai9f|hXs$-1Tw3&Yd zS?mr$=y&I#|Bodfj;VB{-z%2-=o))^5GiHU+mkr*G+yP z`B^LzEkf6y_5O=xlLlROl19=B{h=Q0sZP6kr*Lkj9c*9HS3zNnGL7>@>;v7wHvirF zr{X{TcR5$*?te)uX-41SKqsaCIa!TU75zL@&!C^{=Y^j{RUy^%b3N6+zbKUc=4UVK+{kyeZYA_h{7 zZCe3HJJfymnV6$5{hsjn&oBK!#*eT&iD$4@f_5zT_*c<|G&`VMwj%R)y!)nX1Nfew zj%PLjPrtf#3DiyUWcw>yu|Do?x&Do7>_T?X*!Ca#_L+{~p_56Q1ob#&R|(OLxku1O z8cC~8`?f6`oYu8Zfqv1%AM>DY z=G%UP@gC>3b$LjdpexVC+`w@yv3`p*y93tdIm;K_bOh%Arh-0cgOl_(J_Bv~kYL-A z9v-SKZK&{1J2>o&0_&gT8dK`-Tw};FW~@LTJ=%Ih_8qrBZ|FbU zroFV^PRDwqko{I+hcu8D(zJZxtVHC?`zX&De0k&ZF^4GEP!R*r_at9v^QOIwevn&X zBcP0-ZzsoA?!a}ezy5jvW6-a#PULC1w&%eW3#HAR`4rjDmlw02D}0g$(n6a22Kq_Q zpE0g7^o;c?ANGO7N~oQy$h8)oo17`v@Y1IQeYwDVgB-Kb{={{%^dIFM1#QZIM;ynE zpMUm=^g)GByS(R~zaU;!nLJ}|e*LXCj;}oFs*pdapE|s-d7T6Q8VB9VRxB_K4dF&qdj`r$z0?8 z+QU52XU*$(S=}q4+cW|u|A_giBQC0bxKC;mC&OB0+U&}$Tr{gP_%jT=O1ch^FMBYa z8iu~EGV^8`sSZ6_p6gtVy#R79JQ3@lk8;fyaC{w->y&*w*fw66!W!z`nC~4ntVhek z{QAY%svFmljvdtTFubcnp^xtl%^Ca#x^0zTA@lx?_~#+>Zh`OJE$}&bo<0NU1AgT` z39JjQcSA=Qn%gJmux{8Jp(FzR1oOrYF5jWiX%ir8cLT#O!H;h$`ieU6b3KxH-~m1E zNa(|Lr~`n{FJWB0yM6uY6DE!9QGP(j=shA#>mkJ6YA~S#*L$kUGo6X}zYxwv`ndp( zOZ=Y?eJ>sXe zpj@%_WWa%(FUX$F`7nM+7r`UTJ9FM;c@~^!TpJ(q%@5hEIaZ<1bC##Ud79;2V&2hb zo@29EIyH0$u@U}TSzadQWtK-~Ji4a;WifH*#^dmwt+E)*>UCE1TK21Itm?*Dy#KU$ zV1KzR4zoB6ghTeDoU@9DF+cZUi@`n&i?TS(;?Oq^hjeR}H16EkADl7NcKenv-hm_(@$1walMRFX2Tx5yU`*?+T+ ztSi?-vF_vnc|o3#H{7#^yecd0URvs*{C$Gr1M~cH4OQ3XXUlyj`gf?8HhGtbX6_kB z{gAYAofm0M^h~__oZES4KuauS6|$m#a_UE*Zp2_ z51LHHK}pfgv7noe+5f@xK>F;IR6Ay3xp&ODA&WgrvQNFUv=L?^7D|FFTW&hj3;4plq(5RNVIp0$-gw>6jKLm#w0h=TAbkPo55Q}-Z>oK_6o!&LW1rS61~tE~ zxA7gMWOqc)(#U&1ZB$m%Y{mYJ_y&v-9v;BA(UJ{*G01dl?_V0Y zIQqAyBfRtG%lKZzEdu+P81a(4XB!}t>HgJSKl<(}o!zuAw9%gUeqP*mqD;93--^i8 zK-#${gJ0gVE!ZXqWg3Un(b;GC<%?H39TW6D_j~By=cSJ3l{e$UHd?(HE7$Y^;F``g z*k{i#&0gvFU7IH#T7_?&JRvx4ix*67`D~lAxK@;FZMa8etTs1^*ZFPoTzG#L{c-sX zV&anPDTs|1pIaYwKbb%L_7V1<4y13I)Qf5PjVP}F@CwUroo>u`w$%!J3mGA!|^;5t4rJF_@|3?pKSF9?JgujDfnm^kvya#MX;gD^u z?+;~K?|A8T=Eh6szLyUC@w*%Da!cYrbwBpgdRRRB`oOf&A0!jjEtAG%>;Zn-O6RGc z^eRoN@y9+;l~r2K?m8#?e$cMT@0%l(8hJ?liQnc+7tc#0{y1hySN%=P;dn<6w&Vl9 z;}Etll?WEO7oMrT$&`0q>2+Ru-H#RLmIZn~$y`(4i&bW6i05}f^?>igSf!VC^>puf zxEbHPC@J3RyfmR9Rrs?tt~aTRY1#?Hy6J37N!x9HVhzhki!3b3HMu$?P1+$9_zOC& zG@;v8TAgqD+@P)e)4A68t_3qv@(%goh0aGm=~bFk;E&&aQTdnl^P-!ti?ELNSljfb zb3dhd`D3lq@0TADCgQ^HGfbBX{AJQQm9W2yWZz%6ziQn_hnPS}OaIGn9GSGe&9st% z;UANHZR3wVE+*xdhO|2GZ2O3DT!WAn{F&^-da-o z6mHwHDZ;*>{vWY;PE4c=f81Ls79FXK=lT#mn3QE3f49w;;F||-y7f8)xqji%3RbCv(p2-P(8ir3!zfpZ&02&v@5i z9|BqJrStQBKNl}g{T?z-i~Q5ew0TXPB#}?0WM25kq-@*x8_~0+@AgY2{;nJ0Uk)>^ z3iR(Y;h&$h$UEck$N6yj!v_g|c%ssjRs7vJX_#*u>Gy>h@nVdtsmdl=i>LtRryO<>o0@B?CVrzGd;}jlWsf zk1*n+yAAdKi|0&Xd!`hBCh}gV&Feb6Cv0F0dgU1_E{i{J{4JR~)f)bY#D&KsL3DH9E#(U6aOSL#({L;)w{H1Dd4bFQf8&qBWoU{0g zjlY()es5jAuuZt%a55OAeb`Ui21(PcMU7c?-=-t=<~g27h`o=%Be zR`eww5; zwF{5`VJBt zFPM~FR`F-@-7>HFH=V!lz5SX<<(?u7Z=S^BVq);6EgMsYJz|BvgEm7Je?s~+`{hF- z{IPAg=f2T7qb58s!5`be1luNbFfI4bL2zvP-+0lGtdA*)j1|1f zixpQE@yGp1V%66xp8MvR1d~0!yvj=y$8XQ2()MlozM1fbX%p2?zhBnycgxgKM)fBz z!rziHVl&%N=cCPQV(*SQH>4zg?pc-UV8V;CgukHse+K=&SgK@Hc>RxK@~uR_ZJuiE zF@L|bFkPnOkKY{N`W}9N-K5?sEyokd1eK4ibE7klBsp>n!tWc~%2(yX?>(kEsIvT= zOA>$Ng&!JIm4?2X`u9Ig+a(oagejx@kPL}G&Pmv=dw4%q)2bS!H=+4Z#UJJ6vl|{Y z;;TC`ziDW~Yd>lE&1{5-4Q5cMhStk)*TeRIKlM~;4mJGIe`4O#q| zwSdiiMpZk7<#Sy8{S7{dD!r|yPExy?wbdEVzd(f_j;2V2P zn~MF0!utdJ=0l={vFhs;Uy}GsR1ZJ*>1)bw&e5joRlh`W9LxF%saXFJbUz~7{;ynP zYBMC_xqd&>@u%}`!mwa_(E8bL(e^rEKQ_!Q~0-Z<4@-rm}`V^2ziY(tiB!*WSO> zs>}hIfw9MDP1-n7THEW85|yXlFN^r2PpZk@X@1s2*!IOs27lalQg6d#uE{6c!GxZ& zh(GeP$vH>+ZX-YVW1c2_O_cVn*Ir!Fnu3yuK)^^bIPjp>Y@n^C=%`g6J?m0^TL4-i~Gx^4HqV~Ua=6Kui zGm_0^6@Mno;E6%B+nr_|WRb*6_!DHB%A1>KZF9i$62`+5F}Pv1E$B*;7VZ z!(Xb_0>{FdS9}(KX85zY<~QtnXC(iIb-%qL4Cr{VF$PV_$l@;=e=BaEnf7)jw)|i)6?+i*!3x(YhxcXmg+)Jk zsx(>rl`Q`J>^-DoGo8AD!U)eM-|EtzOLT1;fAp(NRHnKg-gD8{J7tvC?&Kb$&`Q z81!2;C5gY%BL9N=-=|vs5i_yy6eNE9kS;01U{KjqlK3kv@-OK6qg3LLSP6o$M9(al zJ5^%Prf)1UL|&-Cy;7fD|A_h<_gs?rD=qSmeTQE@Odmfu!p~If^-Vg65rm}r+j!3t z8$tJAip3`#fA060zB}9xlX@X}#=ZNwMxP;8eqQlGWvnd7<0tou*1pS6mHubyC!+I! z-y-zlQ_#4k=TsFN*WO1?r3`y|-klnsVU7NH_zTJp_j5Y$J>X;y?w)t1=VuXM3MAulBVar?AH}zkeDue?DvC&u0^BvGU@)SKK$Nw-g4n7v6@T<$^wajGA&tKGY0$mBZQGP>;!foiWZinE z;?MT}#Hqxo6nxmA*S2#0DPA2*;-0(C+y^5l z9jI$Y$Ua3U{ptPIb>YpER8z_`?fZOhx&JTiwwz;+g~wR&?y}u&5mlgtKkvN$Vqp7| zo7QCi(>~{3*QI<%g5(`u80(}h3P z_A3|967-R=?JMNPQ`(ke@h_;YPcJ7Eu}7MFUs^j#HtBVWbxl30Puq(G{jj)S%({nG zM*OW*+h*dKa{I}LS4+KuePiI`uKAKDTQ@zPkS{j&v1c2yEi>`BYrza-{Kdj0fZw)2RWefcDZ07Wkl(tdDjj{OhjeW!xW5y9 z@mNmyyF7uALf@CMgF8vxj`|(185cBA$DmC2d+-~n^tUSM|Y4+nv^;!<_JT2Hxw+$i|-n`;DPW1}3L2}P9 zw|&Pek63a1eh+0@cwI!XVoc|WVwIDs_;leT)#cb+E0PLctN9oD(Q>Zd0v)f z`Kj!})YtqzTN3HQ`%t7sKBXFev`v)+53^-f4$SxPHw(%H{xZc+DT~)4yoSFOUMBEI z`D*ifI$4|);UpEj;P-!1-6y6y|2fmf1nvt`!Q*V6u`x{hb-MA9uJSmpz#z z+HWt}HY)4Smj++MRAV~4S9_V67b|O+O!aphQ;n~9`IiNM(6WX%ulfX8_Y|+)OT)cP z*n7&WEe_Q4``QkziPYP zR6jkcPn$y#d#tk%2lM19>Su4YsK4@0VWr}61?7v!IW*BnhXan&EILMry^d4W9arc$ z#R|!HoN`g=3Mw6R5b_GOvI`i)pvC3O2>fV|t0jXJ2%EM6Syr9w58 z&MR(@N~Q6kuqZCV2d}t-qI8i8=NH9AD(n?klq|vot-9cAh-i&u#|c-YP=7W|pjL$9 zbX0cX45P9OXBd@TxaIW{cnxAS#)s}Uli-O?2?||B$U@3WoCcOqz47Xl_PE067LpBI z;En@)^WAZPuUDKq8NlH}8dKyIg9~JjS6ne@05HW^ig&ZHc)69l;tGnVE1zFHu3Ygb z|1n^TLZ)xn4Z*;=QNbC~&tgWKN+w4!v11VjyFS6^y>8SiyOsIEWDCCPwzk zE@EWw?J8JmMP6|(&QxO=e&bvfX~t*$#Sk8#xO}~p!b(jtaZ$_< zD^6Z7lz`r zA|e1*1j~eBd{hfP75WWR-As=Qw`ZOnhqkMPa-yO@VBSGpqvl TGS.Server.Service.Service + + tgs.ico + @@ -59,5 +62,8 @@ TGS.Server + + + \ No newline at end of file diff --git a/TGS.Server.Service/tgs.ico b/TGS.Server.Service/tgs.ico new file mode 100644 index 0000000000000000000000000000000000000000..6ed69fadfcdf8deb049f66dfffc46d5361332feb GIT binary patch literal 123198 zcmeHQ2b>f|_HG1(QxxyiJH1mu&xnDbAQ>bqf<%dugM>v;q9P!>AR-bJ0TGd8IK_aX z2#5hz#f;%jFx}~`r~lK_Logl)QvdI(nVPNX?V0K7shQnbrhdPk?y0V>diCn-SFc{Z zs&<@mPDSUKV;r2TJ0mJMP7lX%PB zX4{+n+bBCg5VM}LHT8#F$viu1R(UX^)tZ+V_Gx?kJFQ0BSK&->jo zecN3mM)kc^4DH@rEW2%nSTJ*<7}B+=xUyR_F|boZaasN9&s zh;pEBOrtZae1USrH3Qp=F@rjaZ~pUd@%5MgC$2(XU7MdHx?WO4^lDQ}4DZoGG&=Lh zFD||4PhcZ@>PM_~5;_BpuAV zX^pCa&+yq^IW>AHEX@4(t~{e7{E={PkDy%f5YL+>p-V z=E)-kcp&&p&(<|hYH`8w%fY7uqx!a$&pfx`(a`hXe+Tl4!vB8$NsR2%Myy_P3+mTF z@EJY}IzDB+pIEa}CVuv*N1~qpcGuTp@hy|Z^;ca1`kRQ4Klqzi|Hx{#3G47_t6G1! zsotp-53=qI&&7SdsrcY;Z^=6F89v+Q!aokh_5S?vgFT;@k@%7H_iim7dtjNEdEGF< zXZURE+9%vhoDAsHKz#c555)5u!}a&z-`K&O#KM~=$@=jbKHI**sTVapr|MSLXKvm# zV$QUy#o)`E2-SY$(0=b|?Kh%VOVQ}8D&T+Bt-#Vnt!kg(bZTA6OsOvHqVc1Fuzh z{sHB#0?vkYYJA42mz;O3ELZ;l9-N#yCsqPKX5n4?>XP%1U5oP8qOM;7Z?n)|l@O;t z;uKbLLOVhJ*Zn|!G1+-^WT0Wa7P(}^v+^9;2hNn$Ko-4qU>EQ3(;Ne%~DG%`I zYs4+*J*Mf<@YHDoJ2$M-&n4g7W!*M&qEiig1AYcVZtMk?iD#K7+f4nhTRjx7{xdCP z*FZjd>x}X4Y~}xX)5kfLaW$}0gY$utop?te_ZkS)N1)9`>pCY&oZmWQoQxaLv4MPd z`n9ho+Fe|Y*xEUuWBv0FM;^>eg_U>Ac0T^_y>h+V);SeqD&JjGW9&nkMb^QqW?m=#R0PIhM>^pVG+pm|qYkr^7X0JG9XQ?-YgR6j@LeZ@SP_Z4kwIpARtbg^iE>Mf@GIRE3>?eG_yaE9TrVTJoxHwF;CmKcd|l zUD2ktYzDN?7+~Pni>j3uQ?KqTAN}vw#q(Er>Svih+MoU5v@!h!^I%@>Ep=EXdjH~P37$j0w4Mw{S$5U&($PDp=L{=`4< zdHYS*iq~Iy4tbm^`OiGNwKz8idR`0Q^9$9+khfCSke7bnFZP{$Z~8z-RPvU2GVd3k z+i)0k)SOToRHB|JmMxee=H-u}o*=G*?xf_y%Uhoo4Iyv5K?ikO)I8n+*6N~8pLT9?hL{YUitorpr<9lSLdmyJ|Ng$rgE9^Mi>G`;-}7nD zoSJnZ`_NA{mhu5I*4elBf93EV-i^Lm>Z3CzUMY3AJLXIkKmG8%WI1uO`H3}R`h+23 z9CRXGK2ygdO_yA7+}-WBS5Sfd~#}4j@qmx*% zXqLEf;!yN6^(EffztsP8C1QR*^Kk1DETivbb)6xXH#ru38wI|vY<}+VUPYVB_m1x) z56V{_MgJ?3=AXdtSHZ89$a~b_E{%_cE~UsWcE0D%xz6j`o-c>GABE?}W6bdbvBd*z z%ew7X{~Mfs#1Fv9_~AWU9<}MQzm!`zYf`cNVnqN)4#o}@(Kk&;-}(*ut98IxE_AS5 z=vwR0R^NaR)6t(*#P}yxHjbDsoV`vpdF*kjI{DC++(*oZwHpOad51@#Q%N4o^PrO_ z$9vV0t~ri~9)*FFB{pip4h{KIQ7Zai2B0 zIkI;fnH=N3Gogn!zj{FX+IY`S2A*m{p3Z~*`n76LwB>(+uZ4ZuU09Q8n3m7*S!Oc4 zXA6^}Wm@2$xUG)*y@B@Jhqm4YJ*E(4eFJPARAs9(Fm(|9`!`I(w0wro0=LyMMm8#c z(#W39a~szl2Hej>zJfBCvY+p9eICFxuc=S+;C1v7O3P=V56pXJ{lkY{JAzh(#NneI z?>NvUocnY|6wQP0oq$Uv}!TNtW(5;&|z-8cBs^+IIf0l z6yJZh8)L}3#ge%RFTlmi=qGaX#|=9E>i(BSSkb=WY0&Q*4u;%{!WH%9+$&niI@dnQk-GVT{re-` z?E4sdQ~xJz>m);mSK^xRY8{l9J()JwO&S|A`>#f2w_^nLanqdE zw87H(d6FNhe8{Vrs_e<6FUxHgjAoEyB$KXBlH9K-C}yH^}McrcQl z7fa{m$?~ro(L+4_#DjADp~`1jEOf%K%VqyKv|F>YATQoiyeEFpmqqf6RemIa$Hmfl z(<0@+ymb@D9+9?XSeKc@=lZL99RvKXQFZ4#NBbDZWGW<6K6UUtK89)cABkIZ1sJ;E-cz+I`e} z$TC@W$Hu4Mt$0saP8mbnpdJ#H&oK_i&unA7-+0H4kk`v^pNa9wW;_x3Gf0PZ( zQ`M1Wb!`0Sxh(tjm!7TIw(iMm!g~49KbSXcscnHP2lFPfZ1ppJ{168^U3t8h_mTh9 z88}|gy`r@oi&Fp08#^$neD=GX%b;9=&PF@DhyFEH&d-oW=Dp?Vb>*i|xKb4xb%xGE z8*X2`p9iQ*!Oke4tBLv3$4R}C??vG!A$tt0q5u2^_9u?Zsf+6R zCv|t^eSmqhj93A7DB2uPhiv>8vC4Mf!E4qH{kG)A;@Oi0=O$n~mNs5qvrNvJP#4$r zZJmAl93{^pak!8E?|b0!dg%K#t{Kq&xA!l*wfwxi#N|c^&@RAZr+dqDDlh zXn4kv`yoTVM4NmGT_R#zK>YWJ8x0#^1;}+Rr{I^cH*kDV0lNMT$os#L-J3Dq&BYvO zEzDolLRq<&HK@KBH2$|$?LXYmw|%_|u(A6pQ0%S7*%NWlaqhSRF%U<@PH}qjb_!${H(*ZLS$NZR6(C4oqIgZNM(R@ZoSql+hCGtsx_9Y3Yjwcfje|Bn9WrcZe7d4(Rr9GP&%idf z6Sm^h(brj_A9iwQ+w&VL!OpY{xR(4TUF;|ILvIWAmwb0QpNn~Bd9A1Qy5=*iC(FP* z=du@`Szl@8qMMVd!=3Y|Ifb8mSONN8f4rAJlEx5S4W(@bV+6s2J|ndGQWD%SVLezDbgcfLeezKS(qIxO->&MN z1AS#oMd+~&(MPVrm}0lW0DW>^c=k!L0ptFA@0<(T=1Q9i=N&meLfatcYY!g$6 z$I7%Ta&8#77Wah@UPFfv>mFPoUV46mz_?Lxj)Zk!nO$4dSOq<$;r#ru6@g!=OUJ4U zN^)rV!npTn%x5%%Y+D80jJDL4_F0mQLOGlpqr-L8A+g+?0tAO+Smd!r_ zy5^IhF+64}k`s#mihgB#q|QkCy#o18+VwF~NUvkQ>Im_L^wK^@yCm&`x;=$ulcxUd zFMbkOJYm)1;_n6e5GQZkp!1>M?xHTM=+)2U7j19_o7Y8br}5~gZv^#o=0P6Q2E+R6 z2gfH$7w3CTpSGtSy;n4by*R3D&_voW?l^yj$2g@2WF%x3eL;5V&+(dcGjG^drJvi5 zci)K2OUI)>WE%<1F>s#rne`8eH(%Z&-q`kB_;_ACyZ&JTeOl`OYyRUe>&Pr=_BwR4$SGuHjYO>ZT@vmDktsDlu7i* z@Cr{nv=Z%u`4o(aD98A&(+|*%1JZ_fp*CrChoRk?Iq2F};( z^z(WxWP%?2(yu=g@7jz0#~)l?j1JO98cFP`#UYxJuS1^!%;`6W9{8pEouS;Izm*Z0XG1qDjvJ=sJek|>Z<~I~8}<`?e@Xwx@4qYU ztn`s_^OXNdE9C4l=$1!aacP~&=vRJr>+h61^u<&DOR3~P{lG{Uc}@C1+WD?5jy^lI za~Ac*N?$=RedgP58oT~xkY_7>xTCn@9m2^ z*^%oY^i!v%J(l)j(xMKQMSMU%hCkZ}QM9u_(m-0GF(T(fcH^1$tC!5F0>8t}dfj-< zzK^=RuE(niq>la%qv&VfM;fB~VbDhUNHfMBRsIAYY0Nha#2lUUEl~9!-Z*!M@s}by zat=a&Ec|eefV@@sp@3DzR|-d~nY8Wc~}nY4}_-1%72zV5;0&dXai9f|hXs$-1Tw3&Yd zS?mr$=y&I#|Bodfj;VB{-z%2-=o))^5GiHU+mkr*G+yP z`B^LzEkf6y_5O=xlLlROl19=B{h=Q0sZP6kr*Lkj9c*9HS3zNnGL7>@>;v7wHvirF zr{X{TcR5$*?te)uX-41SKqsaCIa!TU75zL@&!C^{=Y^j{RUy^%b3N6+zbKUc=4UVK+{kyeZYA_h{7 zZCe3HJJfymnV6$5{hsjn&oBK!#*eT&iD$4@f_5zT_*c<|G&`VMwj%R)y!)nX1Nfew zj%PLjPrtf#3DiyUWcw>yu|Do?x&Do7>_T?X*!Ca#_L+{~p_56Q1ob#&R|(OLxku1O z8cC~8`?f6`oYu8Zfqv1%AM>DY z=G%UP@gC>3b$LjdpexVC+`w@yv3`p*y93tdIm;K_bOh%Arh-0cgOl_(J_Bv~kYL-A z9v-SKZK&{1J2>o&0_&gT8dK`-Tw};FW~@LTJ=%Ih_8qrBZ|FbU zroFV^PRDwqko{I+hcu8D(zJZxtVHC?`zX&De0k&ZF^4GEP!R*r_at9v^QOIwevn&X zBcP0-ZzsoA?!a}ezy5jvW6-a#PULC1w&%eW3#HAR`4rjDmlw02D}0g$(n6a22Kq_Q zpE0g7^o;c?ANGO7N~oQy$h8)oo17`v@Y1IQeYwDVgB-Kb{={{%^dIFM1#QZIM;ynE zpMUm=^g)GByS(R~zaU;!nLJ}|e*LXCj;}oFs*pdapE|s-d7T6Q8VB9VRxB_K4dF&qdj`r$z0?8 z+QU52XU*$(S=}q4+cW|u|A_giBQC0bxKC;mC&OB0+U&}$Tr{gP_%jT=O1ch^FMBYa z8iu~EGV^8`sSZ6_p6gtVy#R79JQ3@lk8;fyaC{w->y&*w*fw66!W!z`nC~4ntVhek z{QAY%svFmljvdtTFubcnp^xtl%^Ca#x^0zTA@lx?_~#+>Zh`OJE$}&bo<0NU1AgT` z39JjQcSA=Qn%gJmux{8Jp(FzR1oOrYF5jWiX%ir8cLT#O!H;h$`ieU6b3KxH-~m1E zNa(|Lr~`n{FJWB0yM6uY6DE!9QGP(j=shA#>mkJ6YA~S#*L$kUGo6X}zYxwv`ndp( zOZ=Y?eJ>sXe zpj@%_WWa%(FUX$F`7nM+7r`UTJ9FM;c@~^!TpJ(q%@5hEIaZ<1bC##Ud79;2V&2hb zo@29EIyH0$u@U}TSzadQWtK-~Ji4a;WifH*#^dmwt+E)*>UCE1TK21Itm?*Dy#KU$ zV1KzR4zoB6ghTeDoU@9DF+cZUi@`n&i?TS(;?Oq^hjeR}H16EkADl7NcKenv-hm_(@$1walMRFX2Tx5yU`*?+T+ ztSi?-vF_vnc|o3#H{7#^yecd0URvs*{C$Gr1M~cH4OQ3XXUlyj`gf?8HhGtbX6_kB z{gAYAofm0M^h~__oZES4KuauS6|$m#a_UE*Zp2_ z51LHHK}pfgv7noe+5f@xK>F;IR6Ay3xp&ODA&WgrvQNFUv=L?^7D|FFTW&hj3;4plq(5RNVIp0$-gw>6jKLm#w0h=TAbkPo55Q}-Z>oK_6o!&LW1rS61~tE~ zxA7gMWOqc)(#U&1ZB$m%Y{mYJ_y&v-9v;BA(UJ{*G01dl?_V0Y zIQqAyBfRtG%lKZzEdu+P81a(4XB!}t>HgJSKl<(}o!zuAw9%gUeqP*mqD;93--^i8 zK-#${gJ0gVE!ZXqWg3Un(b;GC<%?H39TW6D_j~By=cSJ3l{e$UHd?(HE7$Y^;F``g z*k{i#&0gvFU7IH#T7_?&JRvx4ix*67`D~lAxK@;FZMa8etTs1^*ZFPoTzG#L{c-sX zV&anPDTs|1pIaYwKbb%L_7V1<4y13I)Qf5PjVP}F@CwUroo>u`w$%!J3mGA!|^;5t4rJF_@|3?pKSF9?JgujDfnm^kvya#MX;gD^u z?+;~K?|A8T=Eh6szLyUC@w*%Da!cYrbwBpgdRRRB`oOf&A0!jjEtAG%>;Zn-O6RGc z^eRoN@y9+;l~r2K?m8#?e$cMT@0%l(8hJ?liQnc+7tc#0{y1hySN%=P;dn<6w&Vl9 z;}Etll?WEO7oMrT$&`0q>2+Ru-H#RLmIZn~$y`(4i&bW6i05}f^?>igSf!VC^>puf zxEbHPC@J3RyfmR9Rrs?tt~aTRY1#?Hy6J37N!x9HVhzhki!3b3HMu$?P1+$9_zOC& zG@;v8TAgqD+@P)e)4A68t_3qv@(%goh0aGm=~bFk;E&&aQTdnl^P-!ti?ELNSljfb zb3dhd`D3lq@0TADCgQ^HGfbBX{AJQQm9W2yWZz%6ziQn_hnPS}OaIGn9GSGe&9st% z;UANHZR3wVE+*xdhO|2GZ2O3DT!WAn{F&^-da-o z6mHwHDZ;*>{vWY;PE4c=f81Ls79FXK=lT#mn3QE3f49w;;F||-y7f8)xqji%3RbCv(p2-P(8ir3!zfpZ&02&v@5i z9|BqJrStQBKNl}g{T?z-i~Q5ew0TXPB#}?0WM25kq-@*x8_~0+@AgY2{;nJ0Uk)>^ z3iR(Y;h&$h$UEck$N6yj!v_g|c%ssjRs7vJX_#*u>Gy>h@nVdtsmdl=i>LtRryO<>o0@B?CVrzGd;}jlWsf zk1*n+yAAdKi|0&Xd!`hBCh}gV&Feb6Cv0F0dgU1_E{i{J{4JR~)f)bY#D&KsL3DH9E#(U6aOSL#({L;)w{H1Dd4bFQf8&qBWoU{0g zjlY()es5jAuuZt%a55OAeb`Ui21(PcMU7c?-=-t=<~g27h`o=%Be zR`eww5; zwF{5`VJBt zFPM~FR`F-@-7>HFH=V!lz5SX<<(?u7Z=S^BVq);6EgMsYJz|BvgEm7Je?s~+`{hF- z{IPAg=f2T7qb58s!5`be1luNbFfI4bL2zvP-+0lGtdA*)j1|1f zixpQE@yGp1V%66xp8MvR1d~0!yvj=y$8XQ2()MlozM1fbX%p2?zhBnycgxgKM)fBz z!rziHVl&%N=cCPQV(*SQH>4zg?pc-UV8V;CgukHse+K=&SgK@Hc>RxK@~uR_ZJuiE zF@L|bFkPnOkKY{N`W}9N-K5?sEyokd1eK4ibE7klBsp>n!tWc~%2(yX?>(kEsIvT= zOA>$Ng&!JIm4?2X`u9Ig+a(oagejx@kPL}G&Pmv=dw4%q)2bS!H=+4Z#UJJ6vl|{Y z;;TC`ziDW~Yd>lE&1{5-4Q5cMhStk)*TeRIKlM~;4mJGIe`4O#q| zwSdiiMpZk7<#Sy8{S7{dD!r|yPExy?wbdEVzd(f_j;2V2P zn~MF0!utdJ=0l={vFhs;Uy}GsR1ZJ*>1)bw&e5joRlh`W9LxF%saXFJbUz~7{;ynP zYBMC_xqd&>@u%}`!mwa_(E8bL(e^rEKQ_!Q~0-Z<4@-rm}`V^2ziY(tiB!*WSO> zs>}hIfw9MDP1-n7THEW85|yXlFN^r2PpZk@X@1s2*!IOs27lalQg6d#uE{6c!GxZ& zh(GeP$vH>+ZX-YVW1c2_O_cVn*Ir!Fnu3yuK)^^bIPjp>Y@n^C=%`g6J?m0^TL4-i~Gx^4HqV~Ua=6Kui zGm_0^6@Mno;E6%B+nr_|WRb*6_!DHB%A1>KZF9i$62`+5F}Pv1E$B*;7VZ z!(Xb_0>{FdS9}(KX85zY<~QtnXC(iIb-%qL4Cr{VF$PV_$l@;=e=BaEnf7)jw)|i)6?+i*!3x(YhxcXmg+)Jk zsx(>rl`Q`J>^-DoGo8AD!U)eM-|EtzOLT1;fAp(NRHnKg-gD8{J7tvC?&Kb$&`Q z81!2;C5gY%BL9N=-=|vs5i_yy6eNE9kS;01U{KjqlK3kv@-OK6qg3LLSP6o$M9(al zJ5^%Prf)1UL|&-Cy;7fD|A_h<_gs?rD=qSmeTQE@Odmfu!p~If^-Vg65rm}r+j!3t z8$tJAip3`#fA060zB}9xlX@X}#=ZNwMxP;8eqQlGWvnd7<0tou*1pS6mHubyC!+I! z-y-zlQ_#4k=TsFN*WO1?r3`y|-klnsVU7NH_zTJp_j5Y$J>X;y?w)t1=VuXM3MAulBVar?AH}zkeDue?DvC&u0^BvGU@)SKK$Nw-g4n7v6@T<$^wajGA&tKGY0$mBZQGP>;!foiWZinE z;?MT}#Hqxo6nxmA*S2#0DPA2*;-0(C+y^5l z9jI$Y$Ua3U{ptPIb>YpER8z_`?fZOhx&JTiwwz;+g~wR&?y}u&5mlgtKkvN$Vqp7| zo7QCi(>~{3*QI<%g5(`u80(}h3P z_A3|967-R=?JMNPQ`(ke@h_;YPcJ7Eu}7MFUs^j#HtBVWbxl30Puq(G{jj)S%({nG zM*OW*+h*dKa{I}LS4+KuePiI`uKAKDTQ@zPkS{j&v1c2yEi>`BYrza-{Kdj0fZw)2RWefcDZ07Wkl(tdDjj{OhjeW!xW5y9 z@mNmyyF7uALf@CMgF8vxj`|(185cBA$DmC2d+-~n^tUSM|Y4+nv^;!<_JT2Hxw+$i|-n`;DPW1}3L2}P9 zw|&Pek63a1eh+0@cwI!XVoc|WVwIDs_;leT)#cb+E0PLctN9oD(Q>Zd0v)f z`Kj!})YtqzTN3HQ`%t7sKBXFev`v)+53^-f4$SxPHw(%H{xZc+DT~)4yoSFOUMBEI z`D*ifI$4|);UpEj;P-!1-6y6y|2fmf1nvt`!Q*V6u`x{hb-MA9uJSmpz#z z+HWt}HY)4Smj++MRAV~4S9_V67b|O+O!aphQ;n~9`IiNM(6WX%ulfX8_Y|+)OT)cP z*n7&WEe_Q4``QkziPYP zR6jkcPn$y#d#tk%2lM19>Su4YsK4@0VWr}61?7v!IW*BnhXan&EILMry^d4W9arc$ z#R|!HoN`g=3Mw6R5b_GOvI`i)pvC3O2>fV|t0jXJ2%EM6Syr9w58 z&MR(@N~Q6kuqZCV2d}t-qI8i8=NH9AD(n?klq|vot-9cAh-i&u#|c-YP=7W|pjL$9 zbX0cX45P9OXBd@TxaIW{cnxAS#)s}Uli-O?2?||B$U@3WoCcOqz47Xl_PE067LpBI z;En@)^WAZPuUDKq8NlH}8dKyIg9~JjS6ne@05HW^ig&ZHc)69l;tGnVE1zFHu3Ygb z|1n^TLZ)xn4Z*;=QNbC~&tgWKN+w4!v11VjyFS6^y>8SiyOsIEWDCCPwzk zE@EWw?J8JmMP6|(&QxO=e&bvfX~t*$#Sk8#xO}~p!b(jtaZ$_< zD^6Z7lz`r zA|e1*1j~eBd{hfP75WWR-As=Qw`ZOnhqkMPa-yO@VBSGpqvl Date: Mon, 13 Nov 2017 00:24:23 -0500 Subject: [PATCH 07/31] Fixes server consoles target framework being too high --- TGS.Server.Console/App.config | 6 +++--- TGS.Server.Console/TGS.Server.Console.csproj | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/TGS.Server.Console/App.config b/TGS.Server.Console/App.config index 731f6de6c2..8227adb989 100644 --- a/TGS.Server.Console/App.config +++ b/TGS.Server.Console/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/TGS.Server.Console/TGS.Server.Console.csproj b/TGS.Server.Console/TGS.Server.Console.csproj index a3186f56c2..1fa9654f44 100644 --- a/TGS.Server.Console/TGS.Server.Console.csproj +++ b/TGS.Server.Console/TGS.Server.Console.csproj @@ -8,7 +8,7 @@ Exe TGS.Server.Console TGS.Server.Console - v4.6.1 + v4.5.2 512 true publish\ @@ -26,6 +26,7 @@ false false true + AnyCPU From 84906eaa2e1223032b905e5580632b3ed9befb9a Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 00:27:55 -0500 Subject: [PATCH 08/31] Add Server Console artifact to CI --- Tools/PostCIBuild.ps1 | 17 +++++++++++++++++ appveyor.yml | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/Tools/PostCIBuild.ps1 b/Tools/PostCIBuild.ps1 index 5c76553308..d570ede782 100644 --- a/Tools/PostCIBuild.ps1 +++ b/Tools/PostCIBuild.ps1 @@ -11,6 +11,7 @@ function CodeSign if (Test-Path env:snk_passphrase) { CodeSign "$bf/TGS.Tests/bin/Release/TGS.Tests.dll" + CodeSign "$bf/TGS.Server.Console/bin/Release/TGS.Server.Console.exe" CodeSign "$bf/TGS.Installer.UI/bin/Release/TG Station Server Installer.exe" $env:snk_passphrase = "" } @@ -36,7 +37,23 @@ Copy-Item "$bf\TGS.Interface\bin\Release\TGServiceInterface.dll" "$src2\TGServic $dest2 = "$bf\TGS3-Client-v$version.zip" [io.compression.zipfile]::CreateFromDirectory($src2, $dest2) + +$src3 = "$bf\ServerConsole" +[system.io.directory]::CreateDirectory($src3) +Copy-Item "$bf\TGS.CommandLine\bin\Release\TGCommandLine.exe" "$src3\TGCommandLine.exe" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\TGControlPanel.exe" "$src3\TGControlPanel.exe" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\Octokit.dll" "$src3\Octokit.dll" +Copy-Item "$bf\TGS.Interface\bin\Release\TGServiceInterface.dll" "$src3\TGServiceInterface.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server.Console\bin\Release\TGS.Server.Console.exe" "$src3\TGS.Server.Console.exe" + +$dest3 = "$bf\TGS3-ServerConsole-v$version.zip" + +[io.compression.zipfile]::CreateFromDirectory($src3, $dest3) + $destination_md5sha2 = "$bf\MD5-SHA1-Client-v$version.txt" +$destination_md5sha3 = "$bf\MD5-SHA1-ServerConsole-v$version.txt" & fciv -both $destination > $destination_md5sha & fciv -both $dest2 > $destination_md5sha2 +& fciv -both $dest3 > $destination_md5sha3 diff --git a/appveyor.yml b/appveyor.yml index ba5b51e4b9..dab2d56dab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,10 @@ artifacts: name: TGS3Server - path: MD5-SHA1-Server-v*.txt name: MD5SHA1Server +- path: TGS3-ServerConsole-v*.zip + name: TGS3ServerConsole +- path: MD5-SHA1-ServerConsole-v*.txt + name: MD5SHA1ServerConsole - path: TGS3-Client-v*.zip name: TGS3Client - path: MD5-SHA1-Client-v*.txt From 185e48d138fabb7b1eaa4385ad87839cd4605c51 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 00:40:58 -0500 Subject: [PATCH 09/31] Remove ghetto attempt at preserving the .NET config --- TGS.Server/DeprecatedInstanceConfig.cs | 6 +-- TGS.Server/Properties/Settings.Designer.cs | 2 +- TGS.Server/Server.cs | 44 +++++++++++----------- TGS.Server/ServerInstance/Repository.cs | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/TGS.Server/DeprecatedInstanceConfig.cs b/TGS.Server/DeprecatedInstanceConfig.cs index 3cac746331..33b3b1c8c9 100644 --- a/TGS.Server/DeprecatedInstanceConfig.cs +++ b/TGS.Server/DeprecatedInstanceConfig.cs @@ -19,7 +19,7 @@ namespace TGS.Server /// An based off the old .NET setting file public static IInstanceConfig CreateFromNETSettings() { - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; var result = new DeprecatedInstanceConfig(Helpers.NormalizePath(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3"))); // using nameof for sanity where possible result.ProjectName = LoadPreviousNetPropertyOrDefault(nameof(ProjectName), result.ProjectName); @@ -53,7 +53,7 @@ namespace TGS.Server //try it the simple way first try { - var result = (T)TGServerService.Properties.Settings.Default.GetPreviousVersion(property); + var result = (T)Properties.Settings.Default.GetPreviousVersion(property); return result == null ? defaultValue : result; } catch @@ -65,7 +65,7 @@ namespace TGS.Server //Which means we can never fucking delete config settings //Which is fucking retarded //This hooks into the settings provider and forces it to load it anyway - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; var Provider = Config.Properties[nameof(Config.SettingsVersion)].Provider; //nameof for sanity var sp = new SettingsProperty(property) diff --git a/TGS.Server/Properties/Settings.Designer.cs b/TGS.Server/Properties/Settings.Designer.cs index 1bbb0d95f0..49ea4aae51 100644 --- a/TGS.Server/Properties/Settings.Designer.cs +++ b/TGS.Server/Properties/Settings.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace TGServerService.Properties { +namespace TGS.Server.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 71278e7ec8..2f7351ce31 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -93,7 +93,7 @@ namespace TGS.Server /// The version to migrate from void MigrateSettings(int oldVersion) { - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; switch (oldVersion) { case 6: //switch to per-instance configs @@ -113,7 +113,7 @@ namespace TGS.Server var pathsToRemove = new List(); lock (this) { - var IPS = TGServerService.Properties.Settings.Default.InstancePaths; + var IPS = Properties.Settings.Default.InstancePaths; foreach (var I in IPS) { IInstanceConfig ic; @@ -135,12 +135,12 @@ namespace TGS.Server } /// - /// Overrides and saves the configured if requested by command line parameters + /// Overrides and saves the configured if requested by command line parameters /// /// The command line parameters for the void ChangePortFromCommandLine(string[] args) { - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; for (var I = 0; I < args.Length - 1; ++I) if (args[I].ToLower() == "-port") @@ -162,11 +162,11 @@ namespace TGS.Server } /// - /// Writes some changes to the that always need to be done. + /// Writes some changes to the that always need to be done. /// void PrePrepConfig() { - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; if (Config.InstancePaths == null) Config.InstancePaths = new StringCollection(); @@ -177,7 +177,7 @@ namespace TGS.Server /// void SetupConfig() { - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; if (Config.UpgradeRequired) { var newVersion = Config.SettingsVersion; @@ -219,21 +219,21 @@ namespace TGS.Server } /// - /// Creates a for using the default pipe, CloseTimeout for the , and the configured + /// Creates a for using the default pipe, CloseTimeout for the , and the configured /// /// The /// The URL to access components on the /// The created static ServiceHost CreateHost(object singleton, string endpointPostfix) { - return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", TGServerService.Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) + return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) { CloseTimeout = new TimeSpan(0, 0, 5) }; } /// - /// Creates s for all s as listed in , detaches bad ones + /// Creates s for all s as listed in , detaches bad ones /// void SetupInstances() { @@ -253,7 +253,7 @@ namespace TGS.Server seenNames.Add(I.Name); } foreach (var I in pathsToRemove) - TGServerService.Properties.Settings.Default.InstancePaths.Remove(I); + Properties.Settings.Default.InstancePaths.Remove(I); } /// @@ -371,7 +371,7 @@ namespace TGS.Server } serviceHost.Close(); } - TGServerService.Properties.Settings.Default.Save(); + Properties.Settings.Default.Save(); } /// @@ -387,7 +387,7 @@ namespace TGS.Server /// public ushort RemoteAccessPort() { - return TGServerService.Properties.Settings.Default.RemoteAccessPort; + return Properties.Settings.Default.RemoteAccessPort; } /// @@ -395,7 +395,7 @@ namespace TGS.Server { if (port == 0) return "Cannot bind to port 0"; - TGServerService.Properties.Settings.Default.RemoteAccessPort = port; + Properties.Settings.Default.RemoteAccessPort = port; return null; } @@ -410,14 +410,14 @@ namespace TGS.Server { if (!Directory.Exists(path)) return false; - TGServerService.Properties.Settings.Default.PythonPath = Path.GetFullPath(path); + Properties.Settings.Default.PythonPath = Path.GetFullPath(path); return true; } /// public string PythonPath() { - return TGServerService.Properties.Settings.Default.PythonPath; + return Properties.Settings.Default.PythonPath; } /// @@ -445,7 +445,7 @@ namespace TGS.Server return res; if (File.Exists(path) || Directory.Exists(path)) return "Cannot create instance at pre-existing path!"; - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; lock (this) { if (Config.InstancePaths.Contains(path)) @@ -462,7 +462,7 @@ namespace TGS.Server }; Directory.CreateDirectory(path); ic.Save(); - TGServerService.Properties.Settings.Default.InstancePaths.Add(path); + Properties.Settings.Default.InstancePaths.Add(path); } catch (Exception e) { @@ -488,7 +488,7 @@ namespace TGS.Server host.Open(); else lock (this) - TGServerService.Properties.Settings.Default.InstancePaths.Remove(config.Directory); + Properties.Settings.Default.InstancePaths.Remove(config.Directory); return null; } catch (Exception e) @@ -501,7 +501,7 @@ namespace TGS.Server public string ImportInstance(string path) { path = Helpers.NormalizePath(path); - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; lock (this) { if (Config.InstancePaths.Contains(path)) @@ -516,7 +516,7 @@ namespace TGS.Server if(ic.Name == oic.Name) return String.Format("Instance named {0} already exists!", oic.Name); ic.Save(); - TGServerService.Properties.Settings.Default.InstancePaths.Add(path); + Properties.Settings.Default.InstancePaths.Add(path); } catch (Exception e) { @@ -652,7 +652,7 @@ namespace TGS.Server } if (path == null) return String.Format("No instance named {0} exists!", name); - TGServerService.Properties.Settings.Default.InstancePaths.Remove(path); + Properties.Settings.Default.InstancePaths.Remove(path); return null; } } diff --git a/TGS.Server/ServerInstance/Repository.cs b/TGS.Server/ServerInstance/Repository.cs index 70b7bd89a0..339a7c592c 100644 --- a/TGS.Server/ServerInstance/Repository.cs +++ b/TGS.Server/ServerInstance/Repository.cs @@ -1271,7 +1271,7 @@ namespace TGS.Server return null; } - var Config = TGServerService.Properties.Settings.Default; + var Config = Properties.Settings.Default; var PythonFile = Path.Combine(Config.PythonPath, "python.exe"); if (!File.Exists(PythonFile)) From 680ec3dc62f2a6ed2a46468c6185f310def73b3f Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 00:43:10 -0500 Subject: [PATCH 10/31] Rename ServerInstance to Instance --- TGS.Server/ChatCommands/ChatCommand.cs | 2 +- TGS.Server/ChatCommands/CommandInfo.cs | 4 +- TGS.Server/DeprecatedInstanceConfig.cs | 6 +-- TGS.Server/EventID.cs | 28 +++++------ .../Administration.cs | 8 ++-- .../{ServerInstance => Instance}/Byond.cs | 8 ++-- .../{ServerInstance => Instance}/Chat.cs | 6 +-- .../{ServerInstance => Instance}/Compiler.cs | 2 +- .../{ServerInstance => Instance}/Config.cs | 2 +- .../DreamDaemon.cs | 6 +-- .../Instance.cs} | 10 ++-- .../{ServerInstance => Instance}/Interop.cs | 2 +- .../PreactionHandler.cs | 2 +- .../Repository.cs | 22 ++++----- TGS.Server/InstanceConfig.cs | 34 +++++++------- TGS.Server/RepoConfig.cs | 4 +- TGS.Server/Server.cs | 46 +++++++++---------- TGS.Server/TGS.Server.csproj | 20 ++++---- 18 files changed, 106 insertions(+), 106 deletions(-) rename TGS.Server/{ServerInstance => Instance}/Administration.cs (95%) rename TGS.Server/{ServerInstance => Instance}/Byond.cs (96%) rename TGS.Server/{ServerInstance => Instance}/Chat.cs (98%) rename TGS.Server/{ServerInstance => Instance}/Compiler.cs (99%) rename TGS.Server/{ServerInstance => Instance}/Config.cs (99%) rename TGS.Server/{ServerInstance => Instance}/DreamDaemon.cs (99%) rename TGS.Server/{ServerInstance/ServerInstance.cs => Instance/Instance.cs} (94%) rename TGS.Server/{ServerInstance => Instance}/Interop.cs (99%) rename TGS.Server/{ServerInstance => Instance}/PreactionHandler.cs (98%) rename TGS.Server/{ServerInstance => Instance}/Repository.cs (97%) diff --git a/TGS.Server/ChatCommands/ChatCommand.cs b/TGS.Server/ChatCommands/ChatCommand.cs index f742fadbf6..96d5803ca1 100644 --- a/TGS.Server/ChatCommands/ChatCommand.cs +++ b/TGS.Server/ChatCommands/ChatCommand.cs @@ -20,7 +20,7 @@ namespace TGS.Server.ChatCommands /// /// Shorthand for accessing /// - protected ServerInstance Instance { get { return CommandInfo.Value.Server; } } + protected Instance Instance { get { return CommandInfo.Value.Server; } } /// public override ExitCode DoRun(IList parameters) diff --git a/TGS.Server/ChatCommands/CommandInfo.cs b/TGS.Server/ChatCommands/CommandInfo.cs index 4e650eaf89..4108fd051f 100644 --- a/TGS.Server/ChatCommands/CommandInfo.cs +++ b/TGS.Server/ChatCommands/CommandInfo.cs @@ -18,8 +18,8 @@ /// public string Speaker { get; set; } /// - /// A reference to the that runs the that heard the + /// A reference to the that runs the that heard the /// - public ServerInstance Server { get; set; } + public Instance Server { get; set; } } } diff --git a/TGS.Server/DeprecatedInstanceConfig.cs b/TGS.Server/DeprecatedInstanceConfig.cs index 33b3b1c8c9..091a43f39b 100644 --- a/TGS.Server/DeprecatedInstanceConfig.cs +++ b/TGS.Server/DeprecatedInstanceConfig.cs @@ -9,7 +9,7 @@ namespace TGS.Server class DeprecatedInstanceConfig : InstanceConfig { /// - /// The default directory + /// The default directory /// const string DefaultInstallationPath = "C:\\tgstation-server-3"; @@ -94,9 +94,9 @@ namespace TGS.Server public DeprecatedInstanceConfig() : base(DefaultInstallationPath) { } /// - /// Construct a for a at + /// Construct a for a at /// - /// The path to the + /// The path to the public DeprecatedInstanceConfig(string path) : base(path) { } /// diff --git a/TGS.Server/EventID.cs b/TGS.Server/EventID.cs index 0f7267594b..5fd0a44696 100644 --- a/TGS.Server/EventID.cs +++ b/TGS.Server/EventID.cs @@ -3,7 +3,7 @@ namespace TGS.Server { /// - /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults + /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults /// public enum EventID : int { @@ -33,7 +33,7 @@ namespace TGS.Server /// BYONDUpdateFail = 600, /// - /// Info: When the BYOND updater successfully staged a revision but could not apply it due to the being active + /// Info: When the BYOND updater successfully staged a revision but could not apply it due to the being active /// BYONDUpdateStaged = 700, /// @@ -41,7 +41,7 @@ namespace TGS.Server /// BYONDUpdateComplete = 800, /// - /// Error: Failed to move the with TGS.Interface.Components.ITGAdministration.MoveServer(string) + /// Error: Failed to move the with TGS.Interface.Components.ITGAdministration.MoveServer(string) /// [Obsolete("Not in use anymore", true)] ServerMoveFailed = 900, @@ -143,7 +143,7 @@ namespace TGS.Server [Obsolete("Not in use anymore", true)] TopicFailed = 3100, /// - /// Info: When the has been generated + /// Info: When the has been generated /// CommsKeySet = 3200, /// @@ -225,11 +225,11 @@ namespace TGS.Server /// RepoPRMergeFail = 5100, /// - /// Info: Successfully committed the paths specified in the synchronize_directories field of the 's TGS3.json + /// Info: Successfully committed the paths specified in the synchronize_directories field of the 's TGS3.json /// RepoCommit = 5200, /// - /// Warning: An error occurred while committing the paths specified in the synchronize_directories field of the 's TGS3.json + /// Warning: An error occurred while committing the paths specified in the synchronize_directories field of the 's TGS3.json /// RepoCommitFail = 5300, /// @@ -249,15 +249,15 @@ namespace TGS.Server /// RepoChangelogFail = 5700, /// - /// Info: When the dll is updated for the + /// Info: When the dll is updated for the /// BridgeDLLUpdated = 5800, /// - /// Error: An error occurred while updating the dll for the + /// Error: An error occurred while updating the dll for the /// BridgeDLLUpdateFail = 5900, /// - /// Error: An error occurred while starting the + /// Error: An error occurred while starting the /// InstanceInitializationFailure = 6000, /// @@ -265,15 +265,15 @@ namespace TGS.Server /// ServiceShutdownFail = 6100, /// - /// Info: When the reboots in BYOND + /// Info: When the reboots in BYOND /// WorldReboot = 6200, /// - /// Info: When the output of is applied to the live + /// Info: When the output of is applied to the live /// ServerUpdateApplied = 6300, /// - /// Warning: When an exception occurs during a operation + /// Warning: When an exception occurs during a operation /// ChatBroadcastFail = 6400, /// @@ -287,7 +287,7 @@ namespace TGS.Server /// Submodule = 6600, /// - /// This event is of type or . It occurs when a user different from the previous one tries and either succeeds or fails to access a . DreamDaemon itself successfully accessing will not trigger this + /// This event is of type or . It occurs when a user different from the previous one tries and either succeeds or fails to access a . DreamDaemon itself successfully accessing will not trigger this /// Authentication = 6700, /// @@ -303,7 +303,7 @@ namespace TGS.Server /// InteropCallException = 7000, /// - /// Warning: When the running DreamDaemon code does not have the correct API to talk to the + /// Warning: When the running DreamDaemon code does not have the correct API to talk to the /// APIVersionMismatch = 7100, /// diff --git a/TGS.Server/ServerInstance/Administration.cs b/TGS.Server/Instance/Administration.cs similarity index 95% rename from TGS.Server/ServerInstance/Administration.cs rename to TGS.Server/Instance/Administration.cs index eb8a4b3c2e..7c795857c1 100644 --- a/TGS.Server/ServerInstance/Administration.cs +++ b/TGS.Server/Instance/Administration.cs @@ -10,10 +10,10 @@ namespace TGS.Server { //note this only works with MACHINE LOCAL groups and admins for now //if someone wants AD shit, code it yourself - sealed partial class ServerInstance : ServiceAuthorizationManager, ITGAdministration + sealed partial class Instance : ServiceAuthorizationManager, ITGAdministration { /// - /// The of the Windows group authorized to access the + /// The of the Windows group authorized to access the /// SecurityIdentifier TheDroidsWereLookingFor; /// @@ -21,7 +21,7 @@ namespace TGS.Server /// object authLock = new object(); /// - /// The of the last to attempt to access the + /// The of the last to attempt to access the /// string LastSeenUser; @@ -70,7 +70,7 @@ namespace TGS.Server /// /// The name of the group to search for /// Recursive parameter used to check for the group using instead of - /// The name of the group allowed to access the if it could be found, otherwise + /// 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); diff --git a/TGS.Server/ServerInstance/Byond.cs b/TGS.Server/Instance/Byond.cs similarity index 96% rename from TGS.Server/ServerInstance/Byond.cs rename to TGS.Server/Instance/Byond.cs index fa725720ad..643a896292 100644 --- a/TGS.Server/ServerInstance/Byond.cs +++ b/TGS.Server/Instance/Byond.cs @@ -10,7 +10,7 @@ using TGS.Interface.Components; namespace TGS.Server { - sealed partial class ServerInstance : ITGByond + sealed partial class Instance : ITGByond { /// /// The instance directory to store the BYOND installation @@ -72,7 +72,7 @@ namespace TGS.Server Thread RevisionStaging; /// - /// Called when the is setup. Prepares the BYOND updater + /// Called when the is setup. Prepares the BYOND updater /// void InitByond() { @@ -92,7 +92,7 @@ namespace TGS.Server } /// - /// Called when the is shutdown + /// Called when the is shutdown /// void DisposeByond() { @@ -194,7 +194,7 @@ namespace TGS.Server } /// - /// Downloads and unzips a BYOND revision. Calls afterwards if the isn't running, otherwise, calls . Sets on failure + /// Downloads and unzips a BYOND revision. Calls afterwards if the isn't running, otherwise, calls . Sets on failure /// /// Stringified BYOND revision public void UpdateToVersionImpl(object param) diff --git a/TGS.Server/ServerInstance/Chat.cs b/TGS.Server/Instance/Chat.cs similarity index 98% rename from TGS.Server/ServerInstance/Chat.cs rename to TGS.Server/Instance/Chat.cs index 396c15a5f2..6d1d426ddb 100644 --- a/TGS.Server/ServerInstance/Chat.cs +++ b/TGS.Server/Instance/Chat.cs @@ -9,7 +9,7 @@ using TGS.Interface.Components; namespace TGS.Server { - sealed partial class ServerInstance : ITGChat + sealed partial class Instance : ITGChat { /// /// Used for indicating unintialized encrypted data @@ -17,7 +17,7 @@ namespace TGS.Server public const string UninitializedString = "NEEDS INITIALIZING"; /// - /// List of s for the + /// List of s for the /// IList ChatProviders; /// @@ -26,7 +26,7 @@ namespace TGS.Server object ChatLock = new object(); /// - /// Set up the for the + /// Set up the for the /// public void InitChat() { diff --git a/TGS.Server/ServerInstance/Compiler.cs b/TGS.Server/Instance/Compiler.cs similarity index 99% rename from TGS.Server/ServerInstance/Compiler.cs rename to TGS.Server/Instance/Compiler.cs index d503e921ff..3ce9971504 100644 --- a/TGS.Server/ServerInstance/Compiler.cs +++ b/TGS.Server/Instance/Compiler.cs @@ -11,7 +11,7 @@ using TGS.Interface.Components; namespace TGS.Server { - sealed partial class ServerInstance : ITGCompiler + sealed partial class Instance : ITGCompiler { #region Win32 Shit [DllImport("kernel32.dll", SetLastError = true)] diff --git a/TGS.Server/ServerInstance/Config.cs b/TGS.Server/Instance/Config.cs similarity index 99% rename from TGS.Server/ServerInstance/Config.cs rename to TGS.Server/Instance/Config.cs index 41cad7cfe0..57968b54cd 100644 --- a/TGS.Server/ServerInstance/Config.cs +++ b/TGS.Server/Instance/Config.cs @@ -7,7 +7,7 @@ using TGS.Interface.Components; namespace TGS.Server { //knobs and such - sealed partial class ServerInstance : ITGConfig + sealed partial class Instance : ITGConfig { /// /// Used for multithreading safety diff --git a/TGS.Server/ServerInstance/DreamDaemon.cs b/TGS.Server/Instance/DreamDaemon.cs similarity index 99% rename from TGS.Server/ServerInstance/DreamDaemon.cs rename to TGS.Server/Instance/DreamDaemon.cs index 02290aa7e4..6983e2b585 100644 --- a/TGS.Server/ServerInstance/DreamDaemon.cs +++ b/TGS.Server/Instance/DreamDaemon.cs @@ -12,7 +12,7 @@ namespace TGS.Server { //manages the dd window. //It's not possible to actually click it while starting it in CL mode, so in order to change visibility, security, etc. It restarts the process when the world reboots - sealed partial class ServerInstance : ITGDreamDaemon + sealed partial class Instance : ITGDreamDaemon { enum ShutdownRequestPhase { @@ -519,9 +519,9 @@ namespace TGS.Server } /// - /// Copies from the program directory to the the directory + /// Copies from the program directory to the the directory /// - /// If , overwrites the 's current interface .dll if it exists + /// If , overwrites the 's current interface .dll if it exists void UpdateBridgeDll(bool overwrite) { var rbdlln = RelativePath(BridgeDLLName); diff --git a/TGS.Server/ServerInstance/ServerInstance.cs b/TGS.Server/Instance/Instance.cs similarity index 94% rename from TGS.Server/ServerInstance/ServerInstance.cs rename to TGS.Server/Instance/Instance.cs index 19eed58dc7..aaf98ef39a 100644 --- a/TGS.Server/ServerInstance/ServerInstance.cs +++ b/TGS.Server/Instance/Instance.cs @@ -15,7 +15,7 @@ namespace TGS.Server /// The class which holds all interface components. There are no safeguards for call race conditions so these must be guarded against internally /// [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] - sealed partial class ServerInstance : IDisposable, ITGConnectivity, ITGInstance + sealed partial class Instance : IDisposable, ITGConnectivity, ITGInstance { /// /// Used to assign the instance to event IDs @@ -26,9 +26,9 @@ namespace TGS.Server /// readonly IInstanceConfig Config; /// - /// Constructs and a + /// Constructs and a /// - public ServerInstance(IInstanceConfig config, byte logID) + public Instance(IInstanceConfig config, byte logID) { LoggingID = logID; Config = config; @@ -42,7 +42,7 @@ namespace TGS.Server } /// - /// Cleans up the + /// Cleans up the /// void RunDisposals() { @@ -96,7 +96,7 @@ namespace TGS.Server } /// - /// Converts relative paths to full directory paths + /// Converts relative paths to full directory paths /// /// string RelativePath(string path) diff --git a/TGS.Server/ServerInstance/Interop.cs b/TGS.Server/Instance/Interop.cs similarity index 99% rename from TGS.Server/ServerInstance/Interop.cs rename to TGS.Server/Instance/Interop.cs index 96d3f5a5d3..9365ba04fd 100644 --- a/TGS.Server/ServerInstance/Interop.cs +++ b/TGS.Server/Instance/Interop.cs @@ -13,7 +13,7 @@ using TGS.Interface.Components; namespace TGS.Server { //handles talking between the world and us - sealed partial class ServerInstance : ITGInterop + sealed partial class Instance : ITGInterop { object topicLock = new object(); diff --git a/TGS.Server/ServerInstance/PreactionHandler.cs b/TGS.Server/Instance/PreactionHandler.cs similarity index 98% rename from TGS.Server/ServerInstance/PreactionHandler.cs rename to TGS.Server/Instance/PreactionHandler.cs index 0026c4495e..8fc1d14792 100644 --- a/TGS.Server/ServerInstance/PreactionHandler.cs +++ b/TGS.Server/Instance/PreactionHandler.cs @@ -5,7 +5,7 @@ using System.IO; namespace TGS.Server { // Some useful functions for triggering pre action events - sealed partial class ServerInstance + sealed partial class Instance { /// /// The instance directory for Preaction handlers diff --git a/TGS.Server/ServerInstance/Repository.cs b/TGS.Server/Instance/Repository.cs similarity index 97% rename from TGS.Server/ServerInstance/Repository.cs rename to TGS.Server/Instance/Repository.cs index 339a7c592c..6c2486193d 100644 --- a/TGS.Server/ServerInstance/Repository.cs +++ b/TGS.Server/Instance/Repository.cs @@ -12,10 +12,10 @@ using TGS.Interface.Components; namespace TGS.Server { - sealed partial class ServerInstance : ITGRepository, IDisposable + sealed partial class Instance : ITGRepository, IDisposable { /// - /// The directory for the repository + /// The directory for the repository /// const string RepoPath = "Repository"; /// @@ -27,7 +27,7 @@ namespace TGS.Server /// const string RepoTGS3SettingsPath = RepoPath + "/TGS3.json"; /// - /// Path to the 's json + /// Path to the 's json /// const string CachedTGS3SettingsPath = "TGS3.json"; /// @@ -39,7 +39,7 @@ namespace TGS.Server /// const string SSHPushRemote = "ssh_push_target"; /// - /// The directory for the repository SSH keys + /// The directory for the repository SSH keys /// const string RepoKeyDir = "RepoKey/"; /// @@ -86,7 +86,7 @@ namespace TGS.Server int currentProgress = -1; /// - /// Used for automatically updating the + /// Used for automatically updating the /// System.Timers.Timer autoUpdateTimer = new System.Timers.Timer() { @@ -292,7 +292,7 @@ namespace TGS.Server } /// - /// Copies the Static directory to the first available Static_BACKUP path in the then deleted the old directory + /// Copies the Static directory to the first available Static_BACKUP path in the then deleted the old directory /// void BackupAndDeleteStaticDirectory() { @@ -769,7 +769,7 @@ namespace TGS.Server } /// - /// Lists tags in the repository created by the + /// Lists tags in the repository created by the /// /// on success, error message on failure /// A dictionary of tag title -> commit SHA on success, on failure @@ -826,7 +826,7 @@ namespace TGS.Server } /// - /// Deletes the 's + /// Deletes the 's /// void DeletePRList() { @@ -1193,9 +1193,9 @@ namespace TGS.Server } /// - /// Check if the is configured for SSH pushing + /// Check if the is configured for SSH pushing /// - /// if the see cref="ServerInstance"/> is configured for SSH pushing, otherwise + /// if the see cref="Instance"/> is configured for SSH pushing, otherwise bool SSHAuth() { return File.Exists(RelativePath(PrivateKeyPath)) && File.Exists(RelativePath(PublicKeyPath)); @@ -1365,7 +1365,7 @@ namespace TGS.Server } /// - /// Runs on the configured of and tries to and the + /// Runs on the configured of and tries to and the /// /// A /// The event arguments diff --git a/TGS.Server/InstanceConfig.cs b/TGS.Server/InstanceConfig.cs index 11d2469192..a961f295b8 100644 --- a/TGS.Server/InstanceConfig.cs +++ b/TGS.Server/InstanceConfig.cs @@ -5,12 +5,12 @@ using TGS.Interface; namespace TGS.Server { /// - /// Configuration settings for a + /// Configuration settings for a /// public interface IInstanceConfig { /// - /// The directory this is for + /// The directory this is for /// string Directory { get; } @@ -20,32 +20,32 @@ namespace TGS.Server ulong Version { get; } /// - /// The name of the + /// The name of the /// string Name { get; set; } /// - /// If the is active + /// If the is active /// bool Enabled { get; set; } /// - /// The name of the .dme/.dmb the uses + /// The name of the .dme/.dmb the uses /// string ProjectName { get; set; } /// - /// The port the runs on + /// The port the runs on /// ushort Port { get; set; } /// - /// The level for the + /// The level for the /// DreamDaemonSecurity Security { get; set; } /// - /// Whether or not the should immediately start DreamDaemon when activated + /// Whether or not the should immediately start DreamDaemon when activated /// bool Autostart { get; set; } @@ -74,7 +74,7 @@ namespace TGS.Server string ChatProviderEntropy { get; set; } /// - /// If the should reattach to a running DreamDaemon + /// If the should reattach to a running DreamDaemon /// bool ReattachRequired { get; set; } @@ -99,12 +99,12 @@ namespace TGS.Server string ReattachAPIVersion { get; set; } /// - /// The user group allowed to use the + /// The user group allowed to use the /// string AuthorizedUserGroupSID { get; set; } /// - /// The auto update interval for the + /// The auto update interval for the /// ulong AutoUpdateInterval { get; set; } @@ -114,7 +114,7 @@ namespace TGS.Server bool PushTestmergeCommits { get; set; } /// - /// Saves the to it's + /// Saves the to it's /// void Save(); } @@ -169,7 +169,7 @@ namespace TGS.Server public string CommitterEmail { get; set; } = "tgstation-server@tgstation13.org"; /// - public string ChatProviderData { get; set; } = ServerInstance.UninitializedString; + public string ChatProviderData { get; set; } = Instance.UninitializedString; /// public string ChatProviderEntropy { get; set; } @@ -199,9 +199,9 @@ namespace TGS.Server public bool PushTestmergeCommits { get; set; } = false; /// - /// Construct a for a at + /// Construct a for a at /// - /// The path to the + /// The path to the public InstanceConfig(string path) { Directory = path; @@ -216,9 +216,9 @@ namespace TGS.Server } /// - /// Loads and migrates an from a at + /// Loads and migrates an from a at /// - /// The path to the directory + /// The path to the directory /// The migrated public static IInstanceConfig Load(string path) { diff --git a/TGS.Server/RepoConfig.cs b/TGS.Server/RepoConfig.cs index 91a165171f..c998c131c4 100644 --- a/TGS.Server/RepoConfig.cs +++ b/TGS.Server/RepoConfig.cs @@ -7,7 +7,7 @@ using System.Web.Script.Serialization; namespace TGS.Server { /// - /// Repository specific information for a + /// Repository specific information for a /// sealed class RepoConfig : IEquatable { @@ -32,7 +32,7 @@ namespace TGS.Server /// public readonly IList PathsToStage = new List(); /// - /// Directory's whose contents should not be touched when the updates + /// Directory's whose contents should not be touched when the updates /// public readonly IList StaticDirectoryPaths = new List(); /// diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 2f7351ce31..83980bef48 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -43,7 +43,7 @@ namespace TGS.Server /// /// Checks an for illegal characters /// - /// The name to check + /// The name to check /// if contains no illegal characters, error message otherwise static string CheckInstanceName(string instanceName) { @@ -59,11 +59,11 @@ namespace TGS.Server /// ServiceHost serviceHost; /// - /// Map of to the respective hosting the + /// Map of to the respective hosting the /// IDictionary hosts; /// - /// List of s in use + /// List of s in use /// IList UsedLoggingIDs = new List(); @@ -233,7 +233,7 @@ namespace TGS.Server } /// - /// Creates s for all s as listed in , detaches bad ones + /// Creates s for all s as listed in , detaches bad ones /// void SetupInstances() { @@ -257,9 +257,9 @@ namespace TGS.Server } /// - /// Unlocks a acquired with + /// Unlocks a acquired with /// - /// The to unlock + /// The to unlock void UnlockLoggingID(byte ID) { lock (UsedLoggingIDs) @@ -269,9 +269,9 @@ namespace TGS.Server } /// - /// Gets and locks a + /// Gets and locks a /// - /// A logging ID for the must be released using + /// A logging ID for the must be released using byte LockLoggingID() { lock (UsedLoggingIDs) @@ -287,19 +287,19 @@ namespace TGS.Server } /// - /// Creates and starts a for a at + /// Creates and starts a for a at /// - /// The for the + /// The for the /// The inactive on success, on failure ServiceHost SetupInstance(IInstanceConfig config) { - ServerInstance instance; + Instance instance; string instanceName; try { if (hosts.ContainsKey(config.Directory)) { - var datInstance = ((ServerInstance)hosts[config.Directory].SingletonInstance); + var datInstance = ((Instance)hosts[config.Directory].SingletonInstance); Logger.WriteError(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, LoggingID); return null; } @@ -308,7 +308,7 @@ namespace TGS.Server var ID = LockLoggingID(); Logger.WriteInfo(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, config.Directory, ID), EventID.InstanceIDAssigned, ID); instanceName = config.Name; - instance = new ServerInstance(config, ID); + instance = new Instance(config, ID); } catch (Exception e) { @@ -348,7 +348,7 @@ namespace TGS.Server } /// - /// Shuts down all active s and calls on it's + /// Shuts down all active s and calls on it's /// void OnStop() { @@ -359,7 +359,7 @@ namespace TGS.Server foreach (var I in hosts) { var host = I.Value; - var instance = (ServerInstance)host.SingletonInstance; + var instance = (Instance)host.SingletonInstance; host.Close(); instance.Dispose(); UnlockLoggingID(instance.LoggingID); @@ -381,7 +381,7 @@ namespace TGS.Server public void PrepareForUpdate() { foreach (var I in hosts) - ((ServerInstance)I.Value.SingletonInstance).Reattach(false); + ((Instance)I.Value.SingletonInstance).Reattach(false); } /// @@ -431,7 +431,7 @@ namespace TGS.Server Name = ic.Name, Path = ic.Directory, Enabled = ic.Enabled, - LoggingID = (byte)(ic.Enabled ? ((ServerInstance)hosts[ic.Name].SingletonInstance).LoggingID : 0) + LoggingID = (byte)(ic.Enabled ? ((Instance)hosts[ic.Name].SingletonInstance).LoggingID : 0) }); return result; } @@ -475,7 +475,7 @@ namespace TGS.Server /// /// Starts and onlines an instance located at /// - /// The for the + /// The for the /// on success, error message on failure string SetupOneInstance(IInstanceConfig config) { @@ -543,11 +543,11 @@ namespace TGS.Server /// - /// Sets a 's enabled status + /// Sets a 's enabled status /// - /// The whom's status should be changed - /// to enable the , to disable it - /// The path to the modified + /// The whom's status should be changed + /// to enable the , to disable it + /// The path to the modified /// on success, error message on failure string SetInstanceEnabledImpl(string Name, bool enabled, out string path) { @@ -575,7 +575,7 @@ namespace TGS.Server return null; var host = hosts[Name]; hosts.Remove(Name); - var inst = (ServerInstance)host.SingletonInstance; + var inst = (Instance)host.SingletonInstance; host.Close(); path = inst.ServerDirectory(); inst.Offline(); diff --git a/TGS.Server/TGS.Server.csproj b/TGS.Server/TGS.Server.csproj index 8841b1a5fa..ff1f370ebc 100644 --- a/TGS.Server/TGS.Server.csproj +++ b/TGS.Server/TGS.Server.csproj @@ -97,26 +97,26 @@ - - - + + + - - + + - + - + - - + + True True Settings.settings - + From ce075dcdc709c8496a1fd0868f2baa02ebce3e58 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 01:19:46 -0500 Subject: [PATCH 11/31] Move away from .NET settings in service --- TGS.Server/App.config | 19 ---- TGS.Server/DeprecatedInstanceConfig.cs | 2 +- TGS.Server/Instance/Repository.cs | 7 +- TGS.Server/Properties/Settings.Designer.cs | 59 ----------- TGS.Server/Properties/Settings.settings | 20 +--- TGS.Server/Server.cs | 111 +++++++++------------ TGS.Server/ServerConfig.cs | 65 ++++++++++++ TGS.Server/TGS.Server.csproj | 1 + 8 files changed, 119 insertions(+), 165 deletions(-) create mode 100644 TGS.Server/ServerConfig.cs diff --git a/TGS.Server/App.config b/TGS.Server/App.config index 91aa70ce1c..892916e112 100644 --- a/TGS.Server/App.config +++ b/TGS.Server/App.config @@ -1,27 +1,8 @@  - -
- - - - - C:\Python27 - - - True - - - 7 - - - 38607 - - - diff --git a/TGS.Server/DeprecatedInstanceConfig.cs b/TGS.Server/DeprecatedInstanceConfig.cs index 091a43f39b..3297e7423b 100644 --- a/TGS.Server/DeprecatedInstanceConfig.cs +++ b/TGS.Server/DeprecatedInstanceConfig.cs @@ -66,7 +66,7 @@ namespace TGS.Server //Which is fucking retarded //This hooks into the settings provider and forces it to load it anyway var Config = Properties.Settings.Default; - var Provider = Config.Properties[nameof(Config.SettingsVersion)].Provider; //nameof for sanity + var Provider = Config.Properties["SettingsVersion"].Provider; var sp = new SettingsProperty(property) { diff --git a/TGS.Server/Instance/Repository.cs b/TGS.Server/Instance/Repository.cs index 6c2486193d..277127bc33 100644 --- a/TGS.Server/Instance/Repository.cs +++ b/TGS.Server/Instance/Repository.cs @@ -1271,9 +1271,8 @@ namespace TGS.Server return null; } - var Config = Properties.Settings.Default; - - var PythonFile = Path.Combine(Config.PythonPath, "python.exe"); + var pp = Server.Config.PythonPath; + var PythonFile = Path.Combine(pp, "python.exe"); if (!File.Exists(PythonFile)) { error = "Cannot locate python!"; @@ -1308,7 +1307,7 @@ namespace TGS.Server } //update pip deps and try again - string PipFile = Config.PythonPath + "/scripts/pip.exe"; + string PipFile = Path.Combine(pp, "scripts", "pip.exe"); foreach(var I in RConfig.PipDependancies) using (var pip = new Process()) { diff --git a/TGS.Server/Properties/Settings.Designer.cs b/TGS.Server/Properties/Settings.Designer.cs index 49ea4aae51..c667781590 100644 --- a/TGS.Server/Properties/Settings.Designer.cs +++ b/TGS.Server/Properties/Settings.Designer.cs @@ -22,64 +22,5 @@ namespace TGS.Server.Properties { return defaultInstance; } } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("C:\\Python27")] - public string PythonPath { - get { - return ((string)(this["PythonPath"])); - } - set { - this["PythonPath"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool UpgradeRequired { - get { - return ((bool)(this["UpgradeRequired"])); - } - set { - this["UpgradeRequired"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("7")] - public int SettingsVersion { - get { - return ((int)(this["SettingsVersion"])); - } - set { - this["SettingsVersion"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("38607")] - public ushort RemoteAccessPort { - get { - return ((ushort)(this["RemoteAccessPort"])); - } - set { - this["RemoteAccessPort"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - public global::System.Collections.Specialized.StringCollection InstancePaths { - get { - return ((global::System.Collections.Specialized.StringCollection)(this["InstancePaths"])); - } - set { - this["InstancePaths"] = value; - } - } } } diff --git a/TGS.Server/Properties/Settings.settings b/TGS.Server/Properties/Settings.settings index d3f9248e61..8e615f25fd 100644 --- a/TGS.Server/Properties/Settings.settings +++ b/TGS.Server/Properties/Settings.settings @@ -1,21 +1,5 @@  - + - - - C:\Python27 - - - True - - - 7 - - - 38607 - - - - - + \ No newline at end of file diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 83980bef48..23f8d9d2b1 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -22,6 +22,11 @@ namespace TGS.Server ///
public const byte LoggingID = 0; + /// + /// The directory to use when importing a .NET settings based config + /// + public const string MigrationConfigDirectory = "C:\\TGSSettingUpgradeTempDir"; + /// /// The service version based on the /// @@ -32,6 +37,16 @@ namespace TGS.Server ///
public static ILogger Logger { get; private set; } + /// + /// The for the + /// + public static ServerConfig Config { get; private set; } + + /// + /// The directory to load and save s to + /// + static readonly string DefaultConfigDirectory = Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TGS.Server")).FullName; + /// /// Cancels WCF's user impersonation to allow clean access to writing log files /// @@ -87,23 +102,6 @@ namespace TGS.Server OnlineAllHosts(); } - /// - /// Migrates the .NET config from to + 1 - /// - /// The version to migrate from - void MigrateSettings(int oldVersion) - { - var Config = Properties.Settings.Default; - switch (oldVersion) - { - case 6: //switch to per-instance configs - var IC = DeprecatedInstanceConfig.CreateFromNETSettings(); - IC.Save(); - Config.InstancePaths.Add(IC.Directory); - break; - } - } - /// /// Enumerates configured s. Detaches those that fail to load /// @@ -113,7 +111,7 @@ namespace TGS.Server var pathsToRemove = new List(); lock (this) { - var IPS = Properties.Settings.Default.InstancePaths; + var IPS = Config.InstancePaths; foreach (var I in IPS) { IInstanceConfig ic; @@ -135,13 +133,11 @@ namespace TGS.Server } /// - /// Overrides and saves the configured if requested by command line parameters + /// Overrides and saves the configured if requested by command line parameters /// /// The command line parameters for the void ChangePortFromCommandLine(string[] args) { - var Config = Properties.Settings.Default; - for (var I = 0; I < args.Length - 1; ++I) if (args[I].ToLower() == "-port") { @@ -156,45 +152,34 @@ namespace TGS.Server { throw new Exception("Invalid argument for \"-port\"", e); } - Config.Save(); + Config.Save(DefaultConfigDirectory); break; } } - /// - /// Writes some changes to the that always need to be done. - /// - void PrePrepConfig() - { - var Config = Properties.Settings.Default; - - if (Config.InstancePaths == null) - Config.InstancePaths = new StringCollection(); - } - /// /// Upgrades up the service configuration /// void SetupConfig() { - var Config = Properties.Settings.Default; - if (Config.UpgradeRequired) + try { - var newVersion = Config.SettingsVersion; - Config.Upgrade(); - - PrePrepConfig(); - - for (var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion) - MigrateSettings(oldVersion); - - Config.SettingsVersion = newVersion; - - Config.UpgradeRequired = false; - Config.Save(); + Config = ServerConfig.Load(DefaultConfigDirectory); + } + catch (FileNotFoundException) + { + try + { + //assume we're upgrading + Config = ServerConfig.Load(MigrationConfigDirectory); + Directory.Delete(MigrationConfigDirectory, true); + } + catch(FileNotFoundException) + { + //new baby + Config = new ServerConfig(); + } } - else - PrePrepConfig(); } /// @@ -219,21 +204,21 @@ namespace TGS.Server } /// - /// Creates a for using the default pipe, CloseTimeout for the , and the configured + /// Creates a for using the default pipe, CloseTimeout for the , and the configured /// /// The /// The URL to access components on the /// The created static ServiceHost CreateHost(object singleton, string endpointPostfix) { - return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) }) + return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Config.RemoteAccessPort, endpointPostfix)) }) { CloseTimeout = new TimeSpan(0, 0, 5) }; } /// - /// Creates s for all s as listed in , detaches bad ones + /// Creates s for all s as listed in , detaches bad ones /// void SetupInstances() { @@ -253,7 +238,7 @@ namespace TGS.Server seenNames.Add(I.Name); } foreach (var I in pathsToRemove) - Properties.Settings.Default.InstancePaths.Remove(I); + Config.InstancePaths.Remove(I); } /// @@ -371,7 +356,7 @@ namespace TGS.Server } serviceHost.Close(); } - Properties.Settings.Default.Save(); + Config.Save(DefaultConfigDirectory); } /// @@ -387,7 +372,7 @@ namespace TGS.Server /// public ushort RemoteAccessPort() { - return Properties.Settings.Default.RemoteAccessPort; + return Config.RemoteAccessPort; } /// @@ -395,7 +380,7 @@ namespace TGS.Server { if (port == 0) return "Cannot bind to port 0"; - Properties.Settings.Default.RemoteAccessPort = port; + Config.RemoteAccessPort = port; return null; } @@ -410,14 +395,14 @@ namespace TGS.Server { if (!Directory.Exists(path)) return false; - Properties.Settings.Default.PythonPath = Path.GetFullPath(path); + Config.PythonPath = Path.GetFullPath(path); return true; } /// public string PythonPath() { - return Properties.Settings.Default.PythonPath; + return Config.PythonPath; } /// @@ -445,7 +430,6 @@ namespace TGS.Server return res; if (File.Exists(path) || Directory.Exists(path)) return "Cannot create instance at pre-existing path!"; - var Config = Properties.Settings.Default; lock (this) { if (Config.InstancePaths.Contains(path)) @@ -462,7 +446,7 @@ namespace TGS.Server }; Directory.CreateDirectory(path); ic.Save(); - Properties.Settings.Default.InstancePaths.Add(path); + Config.InstancePaths.Add(path); } catch (Exception e) { @@ -488,7 +472,7 @@ namespace TGS.Server host.Open(); else lock (this) - Properties.Settings.Default.InstancePaths.Remove(config.Directory); + Config.InstancePaths.Remove(config.Directory); return null; } catch (Exception e) @@ -501,7 +485,6 @@ namespace TGS.Server public string ImportInstance(string path) { path = Helpers.NormalizePath(path); - var Config = Properties.Settings.Default; lock (this) { if (Config.InstancePaths.Contains(path)) @@ -516,7 +499,7 @@ namespace TGS.Server if(ic.Name == oic.Name) return String.Format("Instance named {0} already exists!", oic.Name); ic.Save(); - Properties.Settings.Default.InstancePaths.Add(path); + Config.InstancePaths.Add(path); } catch (Exception e) { @@ -652,7 +635,7 @@ namespace TGS.Server } if (path == null) return String.Format("No instance named {0} exists!", name); - Properties.Settings.Default.InstancePaths.Remove(path); + Config.InstancePaths.Remove(path); return null; } } diff --git a/TGS.Server/ServerConfig.cs b/TGS.Server/ServerConfig.cs new file mode 100644 index 0000000000..b294a85767 --- /dev/null +++ b/TGS.Server/ServerConfig.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.IO; +using System.Web.Script.Serialization; + +namespace TGS.Server +{ + /// + /// Class for storing server wide settings + /// + public sealed class ServerConfig + { + /// + /// The filename to save the as + /// + [ScriptIgnore] + const string JSONFilename = "ServerConfig.json"; + /// + /// The most recent version of the config file + /// + [ScriptIgnore] + const ulong CurrentVersion = 8; + + /// + /// The version of the + /// + public ulong Version { get; private set; } = CurrentVersion; + + /// + /// List of paths that contain s + /// + public List InstancePaths { get; private set; } = new List(); + + /// + /// Port used to access the remotely + /// + public ushort RemoteAccessPort { get; set; } = 38607; + + /// + /// Path to the directory containing the Python2.7 installation + /// + public string PythonPath { get; set; } = "C:\\Python27"; + + /// + /// Saves the to a target + /// + /// The directory in which to save the + public void Save(string directory) + { + var data = new JavaScriptSerializer().Serialize(this); + var path = Path.Combine(directory, JSONFilename); + File.WriteAllText(path, data); + } + + /// + /// Load a from a given + /// + /// The directory containing the + /// The loaded + public static ServerConfig Load(string directory) + { + var configtext = File.ReadAllText(Path.Combine(directory, JSONFilename)); + return new JavaScriptSerializer().Deserialize(configtext); + } + } +} diff --git a/TGS.Server/TGS.Server.csproj b/TGS.Server/TGS.Server.csproj index ff1f370ebc..570fbb8cf0 100644 --- a/TGS.Server/TGS.Server.csproj +++ b/TGS.Server/TGS.Server.csproj @@ -120,6 +120,7 @@ + From 511c18ee85dc26ac8e5f41ecad45725915f252f5 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 01:24:04 -0500 Subject: [PATCH 12/31] Server no longer mentions service in it's version --- TGS.Server/Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 23f8d9d2b1..fe29d4a352 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -30,7 +30,7 @@ namespace TGS.Server /// /// The service version based on the /// - public static readonly string VersionString = "/tg/station 13 Server Service v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion; + public static readonly string VersionString = "/tg/station 13 Server v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion; /// /// Singleton From 5fabace83357c2b19ee941f31b334d17372ee59a Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 01:35:20 -0500 Subject: [PATCH 13/31] Renames Server.Console.Program to Server.Console.Console --- TGS.Server.Console/{Program.cs => Console.cs} | 10 +++++----- TGS.Server.Console/TGS.Server.Console.csproj | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename TGS.Server.Console/{Program.cs => Console.cs} (88%) diff --git a/TGS.Server.Console/Program.cs b/TGS.Server.Console/Console.cs similarity index 88% rename from TGS.Server.Console/Program.cs rename to TGS.Server.Console/Console.cs index 980514ebb1..2a065dab9b 100644 --- a/TGS.Server.Console/Program.cs +++ b/TGS.Server.Console/Console.cs @@ -5,19 +5,19 @@ namespace TGS.Server.Console /// /// Console runner for a /// - sealed class Program : ILogger + sealed class Console : ILogger { /// - /// Entry point to the + /// Entry point to the /// /// - static void Main(string[] args) => new Program(args); + static void Main(string[] args) => new Console(args); /// - /// Construct and run a + /// Construct and run a /// /// Command line arguments - Program(string[] args) + Console(string[] args) { System.Console.WriteLine("Starting server..."); var server = new Server(args, this); //no using to avoid including more references diff --git a/TGS.Server.Console/TGS.Server.Console.csproj b/TGS.Server.Console/TGS.Server.Console.csproj index 1fa9654f44..37d49bf3a8 100644 --- a/TGS.Server.Console/TGS.Server.Console.csproj +++ b/TGS.Server.Console/TGS.Server.Console.csproj @@ -57,7 +57,7 @@ - + From 40e8406e74c6a3c5cd9fad90cee5f5c0791c3a87 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 01:36:21 -0500 Subject: [PATCH 14/31] Installer will migrate .NET settings to ServerConfigs --- TGS.Installer.UI/Main.cs | 53 +++++++++++++++++++++++- TGS.Installer.UI/TGS.Installer.UI.csproj | 4 ++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/TGS.Installer.UI/Main.cs b/TGS.Installer.UI/Main.cs index 745db41727..8abcdca084 100644 --- a/TGS.Installer.UI/Main.cs +++ b/TGS.Installer.UI/Main.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using TGS.Interface; using TGS.Interface.Components; +using TGS.Server; namespace TGS.Installer.UI { @@ -19,6 +20,15 @@ namespace TGS.Installer.UI bool installing = false; bool cancelled = false; bool pathIsDefault = true; + /// + /// If we should attempt to make a for the new install + /// + bool attemptNetSettingsMigration = false; + /// + /// If the service we are upgrading is confirmed to be less than version 3.2 + /// + bool isUnderV2 = false; + IServerInterface Interface; @@ -74,12 +84,16 @@ namespace TGS.Installer.UI try { VersionLabel.Text = Interface.GetServiceComponent().Version(); - var isV0 = VersionLabel.Text.Contains("v3.0"); + var splits = VersionLabel.Text.Split(' '); + var realVersion = new Version(splits[splits.Length - 1].Substring(1)); + var isV0 = realVersion < new Version(3, 1, 0, 0); if (isV0) //OH GOD!!!! MessageBox.Show("Upgrading from version 3.0 may trigger a bug that can delete /config and /data. IT IS STRONGLY RECCOMMENDED THAT YOU BACKUP THESE FOLDERS BEFORE UPDATING!", "Warning"); - if (isV0 || VersionLabel.Text.Contains("v3.1")) + isUnderV2 = isV0 || realVersion < new Version(3, 2, 0, 0); + if (isUnderV2) //Friendly reminger MessageBox.Show("Upgrading to service version 3.2 will break the 3.1 DMAPI. It is recommended you update your game to the 3.2 API before updating the servive to avoid having to trigger hard restarts.", "Note"); + attemptNetSettingsMigration = realVersion < new Version(3, 2, 1, 0); } catch { @@ -142,6 +156,39 @@ namespace TGS.Installer.UI return PKillType.NoneFound; } + /// + /// Migrate to the new since the won't know about it until it's upgraded + /// + void AttemptMigrationOfNetSettings() + { + if (!attemptNetSettingsMigration) + return; + var sc = new ServerConfig(); + try + { + sc.PythonPath = Interface.GetServiceComponent().PythonPath(); + } + catch { } + try + { + sc.RemoteAccessPort = Interface.GetServiceComponent().RemoteAccessPort(); + } + catch { } + try + { + foreach (var I in Interface.GetServiceComponent().ListInstances()) + sc.InstancePaths.Add(I.Path); + } + catch { } + + + if (sc.InstancePaths.Count == 0 && isUnderV2) + //add the default ip as a last resort + sc.InstancePaths.Add("C:\\TGSTATION-SERVER-3"); //normalized + + sc.Save(Server.Server.MigrationConfigDirectory); + } + async void DoInstall() { string logfile = null; @@ -183,6 +230,8 @@ namespace TGS.Installer.UI ShowLogCheckbox.Enabled = false; InstallButton.Text = "Installing..."; + AttemptMigrationOfNetSettings(); + var msipath = Path.Combine(tempDir, "TGS.Installer.msi"); File.WriteAllBytes(msipath, Properties.Resources.TGSInstaller); File.WriteAllBytes(Path.Combine(tempDir, "cab1.cab"), Properties.Resources.cab1); diff --git a/TGS.Installer.UI/TGS.Installer.UI.csproj b/TGS.Installer.UI/TGS.Installer.UI.csproj index 3329911b4a..fc0fcb0870 100644 --- a/TGS.Installer.UI/TGS.Installer.UI.csproj +++ b/TGS.Installer.UI/TGS.Installer.UI.csproj @@ -93,6 +93,10 @@ {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} TGS.Interface + + {f32eda25-0855-411c-af5e-f0d042917e2d} + TGS.Server + From 1f6de3da628aafa020bc3e21da0efc60a3be1a2f Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 01:44:37 -0500 Subject: [PATCH 15/31] Fixes bridge dll reflection --- TGS.Server/Instance/DreamDaemon.cs | 2 +- TGS.Server/Instance/Interop.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TGS.Server/Instance/DreamDaemon.cs b/TGS.Server/Instance/DreamDaemon.cs index 6983e2b585..a6846ab2ac 100644 --- a/TGS.Server/Instance/DreamDaemon.cs +++ b/TGS.Server/Instance/DreamDaemon.cs @@ -542,7 +542,7 @@ namespace TGS.Server try { //Use reflection to ensure these are the droids we're looking for - Assembly.ReflectionOnlyLoadFrom(BridgePath).GetType(DreamDaemonBridgeType, true); + Assembly.ReflectionOnlyLoadFrom(BridgePath).GetType(String.Format("{0}.{1}.{2}.{3}", nameof(TGS), nameof(Interface), DreamDaemonBridgeNamespace, DreamDaemonBridgeType), true); } catch (Exception e) { diff --git a/TGS.Server/Instance/Interop.cs b/TGS.Server/Instance/Interop.cs index 9365ba04fd..9bae1cecf6 100644 --- a/TGS.Server/Instance/Interop.cs +++ b/TGS.Server/Instance/Interop.cs @@ -56,11 +56,11 @@ namespace TGS.Server /// /// The namespace that contains the bridge class. Used for reflection /// - const string DreamDaemonBridgeNamespace = "TGDreamDaemonBridge"; + const string DreamDaemonBridgeNamespace = "Bridge"; /// /// The bridge class. Used for reflection /// - const string DreamDaemonBridgeType = DreamDaemonBridgeNamespace + ".DreamDaemonBridge"; + const string DreamDaemonBridgeType = "DreamDaemonBridge"; List ServerChatCommands; From 4fd2face81c75c22472b02a538a108ddcb7ec86f Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 10:28:56 -0500 Subject: [PATCH 16/31] Fixes InstanceMetadata incompatibility with older server versions --- TGS.Interface/InstanceMetadata.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TGS.Interface/InstanceMetadata.cs b/TGS.Interface/InstanceMetadata.cs index d98677bbe6..8b3e73fa6e 100644 --- a/TGS.Interface/InstanceMetadata.cs +++ b/TGS.Interface/InstanceMetadata.cs @@ -5,7 +5,8 @@ namespace TGS.Interface /// /// Metadata about an /// - [DataContract] + //Namespace required for compatibility reasons + [DataContract(Namespace = "http://schemas.datacontract.org/2004/07/TGServiceInterface")] public sealed class InstanceMetadata { /// From 21d0313277fb2660349a3570b16eea556eb115b0 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 10:57:55 -0500 Subject: [PATCH 17/31] Replace JSON usage in TGS.Server with JSON.NET --- TGS.Server/Instance/Chat.cs | 8 ++++---- TGS.Server/Instance/Interop.cs | 6 +++--- TGS.Server/Instance/Repository.cs | 11 ++++------- TGS.Server/InstanceConfig.cs | 14 +++++++------- TGS.Server/RepoConfig.cs | 9 ++++----- TGS.Server/ServerConfig.cs | 12 ++++++------ TGS.Server/TGS.Server.csproj | 1 - 7 files changed, 28 insertions(+), 33 deletions(-) diff --git a/TGS.Server/Instance/Chat.cs b/TGS.Server/Instance/Chat.cs index 6d1d426ddb..7c37b4ec35 100644 --- a/TGS.Server/Instance/Chat.cs +++ b/TGS.Server/Instance/Chat.cs @@ -1,7 +1,7 @@ -using System; +using Newtonsoft.Json; +using System; using System.Linq; using System.Collections.Generic; -using System.Web.Script.Serialization; using TGS.Server.ChatCommands; using TGS.Server.ChatProviders; using TGS.Interface; @@ -112,7 +112,7 @@ namespace TGS.Server } ChatProviders = null; - var rawdata = new JavaScriptSerializer().Serialize(infosList); + var rawdata = JsonConvert.SerializeObject(infosList); Config.ChatProviderData = Interface.Helpers.EncryptData(rawdata, out string entrp); Config.ChatProviderEntropy = entrp; @@ -144,7 +144,7 @@ namespace TGS.Server { plaintext = Interface.Helpers.DecryptData(rawdata, Config.ChatProviderEntropy); - var lists = new JavaScriptSerializer().Deserialize>>(plaintext); + var lists = JsonConvert.DeserializeObject>>(plaintext); var output = new List(lists.Count); var foundirc = 0; var founddiscord = 0; diff --git a/TGS.Server/Instance/Interop.cs b/TGS.Server/Instance/Interop.cs index 9bae1cecf6..3d934d4322 100644 --- a/TGS.Server/Instance/Interop.cs +++ b/TGS.Server/Instance/Interop.cs @@ -1,10 +1,10 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; -using System.Web.Script.Serialization; using System.Web.Security; using TGS.Server.ChatCommands; using TGS.Interface; @@ -74,7 +74,7 @@ namespace TGS.Server List tmp = new List(); try { - foreach(var I in new JavaScriptSerializer().Deserialize>>(json)) + foreach(var I in JsonConvert.DeserializeObject>>(json)) tmp.Add(new ServerChatCommand(I.Key, (string)I.Value[CCPHelpText], ((int)I.Value[CCPAdminOnly]) == 1, (int)I.Value[CCPRequiredParameters])); ServerChatCommands = tmp; } diff --git a/TGS.Server/Instance/Repository.cs b/TGS.Server/Instance/Repository.cs index 277127bc33..1bcaca13b2 100644 --- a/TGS.Server/Instance/Repository.cs +++ b/TGS.Server/Instance/Repository.cs @@ -1,4 +1,5 @@ using LibGit2Sharp; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -6,7 +7,6 @@ using System.IO; using System.Linq; using System.Net; using System.Threading; -using System.Web.Script.Serialization; using TGS.Interface; using TGS.Interface.Components; @@ -850,8 +850,7 @@ namespace TGS.Server if (!File.Exists(RelativePath(PRJobFile))) return new Dictionary>(); var rawdata = File.ReadAllText(RelativePath(PRJobFile)); - var Deserializer = new JavaScriptSerializer(); - return Deserializer.Deserialize>>(rawdata); + return JsonConvert.DeserializeObject>>(rawdata); } /// @@ -860,8 +859,7 @@ namespace TGS.Server /// void SetCurrentPRList(IDictionary> list) { - var Serializer = new JavaScriptSerializer(); - var rawdata = Serializer.Serialize(list); + var rawdata = JsonConvert.SerializeObject(list); File.WriteAllText(RelativePath(PRJobFile), rawdata); } @@ -963,8 +961,7 @@ namespace TGS.Server json = wc.DownloadString(prAPI); } - var Deserializer = new JavaScriptSerializer(); - var dick = Deserializer.DeserializeObject(json) as IDictionary; + var dick = JsonConvert.DeserializeObject>(json); var user = dick["user"] as IDictionary; newPR.Add("commit", atSHA ?? branch.Tip.Sha); diff --git a/TGS.Server/InstanceConfig.cs b/TGS.Server/InstanceConfig.cs index a961f295b8..6714e9052f 100644 --- a/TGS.Server/InstanceConfig.cs +++ b/TGS.Server/InstanceConfig.cs @@ -1,5 +1,5 @@ -using System.IO; -using System.Web.Script.Serialization; +using Newtonsoft.Json; +using System.IO; using TGS.Interface; namespace TGS.Server @@ -125,17 +125,17 @@ namespace TGS.Server /// /// The name the file is saved as in the /// - [ScriptIgnore] + [JsonIgnore] public const string JSONFilename = "Instance.json"; /// /// The current version of the config /// - [ScriptIgnore] + [JsonIgnore] protected const ulong CurrentVersion = 0; //Literally any time you add/deprecated a field, this number needs to be bumped /// - [ScriptIgnore] + [JsonIgnore] public string Directory { get; private set; } /// @@ -210,7 +210,7 @@ namespace TGS.Server /// public void Save() { - var data = new JavaScriptSerializer().Serialize(this); + var data = JsonConvert.SerializeObject(this); var path = Path.Combine(Directory, JSONFilename); File.WriteAllText(path, data); } @@ -223,7 +223,7 @@ namespace TGS.Server public static IInstanceConfig Load(string path) { var configtext = File.ReadAllText(Path.Combine(path, JSONFilename)); - var res = new JavaScriptSerializer().Deserialize(configtext); + var res = JsonConvert.DeserializeObject(configtext); res.Directory = path; res.MigrateToCurrentVersion(); return res; diff --git a/TGS.Server/RepoConfig.cs b/TGS.Server/RepoConfig.cs index c998c131c4..1e5f917aaf 100644 --- a/TGS.Server/RepoConfig.cs +++ b/TGS.Server/RepoConfig.cs @@ -1,8 +1,8 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Web.Script.Serialization; namespace TGS.Server { @@ -49,11 +49,10 @@ namespace TGS.Server if (!File.Exists(path)) return; var rawdata = File.ReadAllText(path); - var Deserializer = new JavaScriptSerializer(); - var json = Deserializer.Deserialize>(rawdata); + var json = JsonConvert.DeserializeObject>(rawdata); try { - var details = (IDictionary)json["changelog"]; + var details = json["changelog"] as IDictionary; PathToChangelogPy = (string)details["script"]; ChangelogPyArguments = (string)details["arguments"]; ChangelogSupport = true; diff --git a/TGS.Server/ServerConfig.cs b/TGS.Server/ServerConfig.cs index b294a85767..40f1b4b995 100644 --- a/TGS.Server/ServerConfig.cs +++ b/TGS.Server/ServerConfig.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; +using Newtonsoft.Json; +using System.Collections.Generic; using System.IO; -using System.Web.Script.Serialization; namespace TGS.Server { @@ -12,12 +12,12 @@ namespace TGS.Server /// /// The filename to save the as /// - [ScriptIgnore] + [JsonIgnore] const string JSONFilename = "ServerConfig.json"; /// /// The most recent version of the config file /// - [ScriptIgnore] + [JsonIgnore] const ulong CurrentVersion = 8; /// @@ -46,7 +46,7 @@ namespace TGS.Server /// The directory in which to save the public void Save(string directory) { - var data = new JavaScriptSerializer().Serialize(this); + var data = JsonConvert.SerializeObject(this); var path = Path.Combine(directory, JSONFilename); File.WriteAllText(path, data); } @@ -59,7 +59,7 @@ namespace TGS.Server public static ServerConfig Load(string directory) { var configtext = File.ReadAllText(Path.Combine(directory, JSONFilename)); - return new JavaScriptSerializer().Deserialize(configtext); + return JsonConvert.DeserializeObject(configtext); } } } diff --git a/TGS.Server/TGS.Server.csproj b/TGS.Server/TGS.Server.csproj index 570fbb8cf0..9eebed48f1 100644 --- a/TGS.Server/TGS.Server.csproj +++ b/TGS.Server/TGS.Server.csproj @@ -78,7 +78,6 @@ - From 168384135f90c9552c0242497736ecc786f06381 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:02:13 -0500 Subject: [PATCH 18/31] Update TGS.Server github api user-agent --- TGS.Server/Instance/Repository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TGS.Server/Instance/Repository.cs b/TGS.Server/Instance/Repository.cs index 1bcaca13b2..58cea755f5 100644 --- a/TGS.Server/Instance/Repository.cs +++ b/TGS.Server/Instance/Repository.cs @@ -957,7 +957,7 @@ namespace TGS.Server string json; using (var wc = new WebClient()) { - wc.Headers.Add("user-agent", "TGStationServerService"); + wc.Headers.Add("user-agent", "TGS.Server"); json = wc.DownloadString(prAPI); } From 06dc7105d6dd6fc7f568ecfcdc37d46d503f2e43 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:04:33 -0500 Subject: [PATCH 19/31] Remove bad config exception filtering --- TGS.Server/Server.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index fe29d4a352..9017d65ed7 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -166,7 +166,7 @@ namespace TGS.Server { Config = ServerConfig.Load(DefaultConfigDirectory); } - catch (FileNotFoundException) + catch { try { @@ -174,7 +174,7 @@ namespace TGS.Server Config = ServerConfig.Load(MigrationConfigDirectory); Directory.Delete(MigrationConfigDirectory, true); } - catch(FileNotFoundException) + catch { //new baby Config = new ServerConfig(); From d4e157c7d297a056792ca5e85a1b018c26bd6fab Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:07:37 -0500 Subject: [PATCH 20/31] Fixes Server not setting Logger --- TGS.Server/Server.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 9017d65ed7..d9bed51a06 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -89,6 +89,8 @@ namespace TGS.Server /// The to use public Server(string[] args, ILogger logger) { + Logger = logger; + Environment.CurrentDirectory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name)).FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png SetupConfig(); From abb99577ead4b63c97ec36328e95eaec59f94dc9 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:08:48 -0500 Subject: [PATCH 21/31] Improve handling of migrated ServerConfigs --- TGS.Server/Server.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index d9bed51a06..5098a590d7 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -174,7 +174,8 @@ namespace TGS.Server { //assume we're upgrading Config = ServerConfig.Load(MigrationConfigDirectory); - Directory.Delete(MigrationConfigDirectory, true); + Config.Save(DefaultConfigDirectory); + Helpers.DeleteDirectory(MigrationConfigDirectory); } catch { From 7fa6719fbcc71912cad05a52abd66a8f7bf26c18 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:11:01 -0500 Subject: [PATCH 22/31] Exception handling for server console --- TGS.Server.Console/Console.cs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/TGS.Server.Console/Console.cs b/TGS.Server.Console/Console.cs index 2a065dab9b..3a1173be47 100644 --- a/TGS.Server.Console/Console.cs +++ b/TGS.Server.Console/Console.cs @@ -19,20 +19,33 @@ namespace TGS.Server.Console /// Command line arguments Console(string[] args) { - System.Console.WriteLine("Starting server..."); - var server = new Server(args, this); //no using to avoid including more references try { - System.Console.WriteLine("Server started!"); - System.Console.Write("Press any key to exit..."); - System.Console.ReadKey(); + System.Console.WriteLine("Starting server..."); + var server = new Server(args, this); //no using to avoid including more references + try + { + System.Console.WriteLine("Server started!"); + ExitPrompt(); + } + finally + { + server.Dispose(); + } } - finally + catch (Exception e) { - server.Dispose(); + System.Console.WriteLine(String.Format("Unhandled exception: {0}", e.ToString())); + ExitPrompt(); } } + void ExitPrompt() + { + System.Console.Write("Press any key to exit..."); + System.Console.ReadKey(); + } + /// public void WriteAccess(string username, bool authSuccess, byte loggingID) { From 6cae8ee2fccddc1427677643493fcc53de545741 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:13:50 -0500 Subject: [PATCH 23/31] Fixes console displaying wrong event IDs --- TGS.Server.Console/Console.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TGS.Server.Console/Console.cs b/TGS.Server.Console/Console.cs index 3a1173be47..9efb81bbb5 100644 --- a/TGS.Server.Console/Console.cs +++ b/TGS.Server.Console/Console.cs @@ -49,25 +49,25 @@ namespace TGS.Server.Console /// public void WriteAccess(string username, bool authSuccess, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}: Authentication {3} from {2}", DateTime.UtcNow.ToString(), EventID.Authentication + loggingID, username, authSuccess ? "success" : "fail")); + System.Console.WriteLine(String.Format("[{0}]: {1}-{4}: Authentication {3} from {2}", DateTime.UtcNow.ToString(), EventID.Authentication, username, authSuccess ? "success" : "fail", loggingID)); } /// public void WriteError(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}: ERROR: {2}", DateTime.UtcNow.ToString(), id + loggingID, message)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: ERROR: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); } /// public void WriteInfo(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}: Warning: {2}", DateTime.UtcNow.ToString(), id + loggingID, message)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: Warning: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); } /// public void WriteWarning(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}: {2}", DateTime.UtcNow.ToString(), id + loggingID, message)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); } } } From ab2e75781b13e5eb1f171c1e4ed3a0e7f5e14a2e Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:15:30 -0500 Subject: [PATCH 24/31] Removes obsolete instructions about debugging the server --- .github/CONTRIBUTING.md | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b404563eeb..930b4465b8 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -30,27 +30,9 @@ Visual Studio comes with the nuget package manager. To install the dependencies, The [WiX Toolset](http://wixtoolset.org/) is used for creating the installer .msi (Not the .exe, which is a standard C# program wrapper to the .msi). Building and modifying this is not required for debugging and development of the service but necessary if you want to debug tweaks to the installer configuration. You can download the Wix Toolset and Visual studio extension [here](http://wixtoolset.org/releases/). This will allow you to build `TGS.Installer.wixproj` just like all the other projects. -#### Debugging +##### Debugging -So you've built the project and everything's good, right? Now you have to debug it. Debugging the command line and control panel are easy enough, just launch them like any other process. Debugging the TGS.Server itself though requires a bit of finagling due to how Windows services work. - -1. Uninstall any release versions of TG Station Server 3 you may have on your machine -1. Open an administrative Windows cmd prompt -1. Run `sc delete "TG Station Server"` for sanity -1. Build the service in debug mode -1. Navigate to `C:\Windows\Microsoft.NET\Framework\v4.0.30319` -1. Run `InstallUtil.exe` with the path to your debug `TGServerService.exe` as an argument. This will register your debug build as a Windows service. - -If the command runs successfully you're all set up. Now, here is the debugging process. - -1. BEFORE BUILDING. Stop `TG Station Server` from the Windows Services control panel -1. Build your new Debug version -1. Set your breakpoints -1. Start the service -1. Use your environment to attach to `TGServerService.exe` for debugging -1. If you need to debug startup, you'll have to add `System.Diagnostics.Debugger.Start()` where you want the service to wait for you. Do not write a constructor for the Service classas Windows will not let you debug it properly - -Now be careful while debugging. The service runs with root level privileges and you wouldn't want any [accidents](http://i.imgur.com/zvGEpJD.png) to happen, would you? +Be careful while debugging. The service runs with root level privileges and you wouldn't want any [accidents](http://i.imgur.com/zvGEpJD.png) to happen, would you? ## Meet the Team From a0e2bca1cd4d1dc23c9541ed0b0da3b48c83b658 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:21:00 -0500 Subject: [PATCH 25/31] Press any key now makes a newline --- TGS.Server.Console/Console.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TGS.Server.Console/Console.cs b/TGS.Server.Console/Console.cs index 9efb81bbb5..aac7cb8a78 100644 --- a/TGS.Server.Console/Console.cs +++ b/TGS.Server.Console/Console.cs @@ -42,7 +42,7 @@ namespace TGS.Server.Console void ExitPrompt() { - System.Console.Write("Press any key to exit..."); + System.Console.WriteLine("Press any key to exit..."); System.Console.ReadKey(); } From 56ba2b3ba2bfdfd8f177ffd43da609aff3a07c5d Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:53:20 -0500 Subject: [PATCH 26/31] Fixes Console.WriteInfo/Warning being swapped --- TGS.Server.Console/Console.cs | 4 ++-- TGS.Server/ILogger.cs | 1 + Tools/PostCIBuild.ps1 | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/TGS.Server.Console/Console.cs b/TGS.Server.Console/Console.cs index aac7cb8a78..37f5297efe 100644 --- a/TGS.Server.Console/Console.cs +++ b/TGS.Server.Console/Console.cs @@ -61,13 +61,13 @@ namespace TGS.Server.Console /// public void WriteInfo(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: Warning: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); } /// public void WriteWarning(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: Warning: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); } } } diff --git a/TGS.Server/ILogger.cs b/TGS.Server/ILogger.cs index b63246f06a..9615b133b7 100644 --- a/TGS.Server/ILogger.cs +++ b/TGS.Server/ILogger.cs @@ -28,6 +28,7 @@ /// The of the message /// The 0-99 ID of the log source void WriteWarning(string message, EventID id, byte loggingID); + /// /// Writes an access event to the log /// diff --git a/Tools/PostCIBuild.ps1 b/Tools/PostCIBuild.ps1 index d570ede782..82cd07a563 100644 --- a/Tools/PostCIBuild.ps1 +++ b/Tools/PostCIBuild.ps1 @@ -45,6 +45,13 @@ Copy-Item "$bf\TGS.ControlPanel\bin\Release\TGControlPanel.exe" "$src3\TGControl Copy-Item "$bf\TGS.ControlPanel\bin\Release\Octokit.dll" "$src3\Octokit.dll" Copy-Item "$bf\TGS.Interface\bin\Release\TGServiceInterface.dll" "$src3\TGServiceInterface.dll" Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" Copy-Item "$bf\TGS.Server.Console\bin\Release\TGS.Server.Console.exe" "$src3\TGS.Server.Console.exe" $dest3 = "$bf\TGS3-ServerConsole-v$version.zip" From 3a5b44e5e9c45b4eaf993ec36ae6cba096f20af5 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 11:59:26 -0500 Subject: [PATCH 27/31] Add missing dependencies to server console zip --- Tools/PostCIBuild.ps1 | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Tools/PostCIBuild.ps1 b/Tools/PostCIBuild.ps1 index 82cd07a563..6a0ae81b57 100644 --- a/Tools/PostCIBuild.ps1 +++ b/Tools/PostCIBuild.ps1 @@ -45,13 +45,23 @@ Copy-Item "$bf\TGS.ControlPanel\bin\Release\TGControlPanel.exe" "$src3\TGControl Copy-Item "$bf\TGS.ControlPanel\bin\Release\Octokit.dll" "$src3\Octokit.dll" Copy-Item "$bf\TGS.Interface\bin\Release\TGServiceInterface.dll" "$src3\TGServiceInterface.dll" Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" -Copy-Item "$bf\TGS.Server\bin\Release\TGS.Server.dll" "$src3\TGS.Server.dll" +Copy-Item "$bf\TGS.Server\bin\Release\Discord.Net.Core.dll" "$src3\Discord.Net.Core.dll" +Copy-Item "$bf\TGS.Server\bin\Release\Discord.Net.Rest.dll" "$src3\Discord.Net.Rest.dll" +Copy-Item "$bf\TGS.Server\bin\Release\Discord.Net.WebSocket.dll" "$src3\Discord.Net.WebSocket.dll" +Copy-Item "$bf\TGS.Server\bin\Release\LibGit2Sharp.dll" "$src3\LibGit2Sharp.dll" +Copy-Item "$bf\TGS.Server\bin\Release\Meebey.SmartIrc4net.dll" "$src3\Meebey.SmartIrc4net.dll" +Copy-Item "$bf\TGS.Server\bin\Release\Newtonsoft.Json.dll" "$src3\Newtonsoft.Json.dll" +Copy-Item "$bf\TGS.Server\bin\Release\System.Collections.Immutable.dll" "$src3\System.Collections.Immutable.dll" +Copy-Item "$bf\TGS.Server\bin\Release\System.Interactive.Async.dll" "$src3\System.Interactive.Async.dll" +Copy-Item "$bf\TGS.Interface.Bridge\bin\Release\TGS.Interface.Bridge.dll" "$src3\TGS.Interface.Bridge.dll" +[system.io.directory]::CreateDirectory("$src3\lib\win32\x86") +Copy-Item "$bf\TGS.ControlPanel\bin\Release\lib\win32\x86\git2-ssh-baa87df.dll" "$src3\lib\win32\x86\git2-ssh-baa87df.dll" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\lib\win32\x86\libssh2.dll" "$src3\lib\win32\x86\libssh2.dll" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\lib\win32\x86\zlib.dll" "$src3\lib\win32\x86\zlib.dll" +[system.io.directory]::CreateDirectory("$src3\lib\win32\x64") +Copy-Item "$bf\TGS.ControlPanel\bin\Release\lib\win32\x64\git2-ssh-baa87df.dll" "$src3\lib\win32\x64\git2-ssh-baa87df.dll" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\lib\win32\x64\libssh2.dll" "$src3\lib\win32\x64\libssh2.dll" +Copy-Item "$bf\TGS.ControlPanel\bin\Release\lib\win32\x64\zlib.dll" "$src3\lib\win32\x86\zlib.dll" Copy-Item "$bf\TGS.Server.Console\bin\Release\TGS.Server.Console.exe" "$src3\TGS.Server.Console.exe" $dest3 = "$bf\TGS3-ServerConsole-v$version.zip" From 22a16eba1f37292696057ed743b1311aca3e1b36 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 12:11:47 -0500 Subject: [PATCH 28/31] Changes server console logging to local time from UTC --- TGS.Server.Console/Console.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TGS.Server.Console/Console.cs b/TGS.Server.Console/Console.cs index 37f5297efe..9641e5d625 100644 --- a/TGS.Server.Console/Console.cs +++ b/TGS.Server.Console/Console.cs @@ -55,19 +55,19 @@ namespace TGS.Server.Console /// public void WriteError(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: ERROR: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: ERROR: {2}", DateTime.Now.ToString(), id, message, loggingID)); } /// public void WriteInfo(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: {2}", DateTime.Now.ToString(), id, message, loggingID)); } /// public void WriteWarning(string message, EventID id, byte loggingID) { - System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: Warning: {2}", DateTime.UtcNow.ToString(), id, message, loggingID)); + System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: Warning: {2}", DateTime.Now.ToString(), id, message, loggingID)); } } } From 667a7a772e529b42ac0ff51d3bf359d0efe2b70c Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 12:20:54 -0500 Subject: [PATCH 29/31] Corrects JSON.NET dictionary deserialization --- TGS.Server/Instance/Repository.cs | 2 +- TGS.Server/RepoConfig.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TGS.Server/Instance/Repository.cs b/TGS.Server/Instance/Repository.cs index 58cea755f5..a34ffc0cbd 100644 --- a/TGS.Server/Instance/Repository.cs +++ b/TGS.Server/Instance/Repository.cs @@ -962,7 +962,7 @@ namespace TGS.Server } var dick = JsonConvert.DeserializeObject>(json); - var user = dick["user"] as IDictionary; + var user = JsonConvert.DeserializeObject>((string)dick["user"]); newPR.Add("commit", atSHA ?? branch.Tip.Sha); newPR.Add("author", (string)user["login"]); diff --git a/TGS.Server/RepoConfig.cs b/TGS.Server/RepoConfig.cs index 1e5f917aaf..9f115d7955 100644 --- a/TGS.Server/RepoConfig.cs +++ b/TGS.Server/RepoConfig.cs @@ -52,7 +52,7 @@ namespace TGS.Server var json = JsonConvert.DeserializeObject>(rawdata); try { - var details = json["changelog"] as IDictionary; + var details = JsonConvert.DeserializeObject>((string)json["changelog"]); PathToChangelogPy = (string)details["script"]; ChangelogPyArguments = (string)details["arguments"]; ChangelogSupport = true; From 5c83131ff8d6bea7aca15ac96dd1b4c1e083265d Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 12:39:22 -0500 Subject: [PATCH 30/31] Add ServerConsole to release artifacts --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index dab2d56dab..7ad7e7b60c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -52,7 +52,7 @@ deploy: description: 'The /tg/station server suite' auth_token: secure: lJNGAXwiB5HlWdthz3K4PetqpTG5IEAyRgKaiKxFMQ8HW8CcOjRtB97B05op7BsK - artifact: TGS3Server,MD5SHA1Server,TGS3Client,MD5SHA1Client + artifact: TGS3Server,MD5SHA1Server,TGS3Client,MD5SHA1Client,TGS3ServerConsole,MD5SHA1ServerConsole draft: false on: TGSDeploy: "Do it." From b55402c527376f7fc78e6a19dc07a2b47c542c3f Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 13 Nov 2017 13:55:02 -0500 Subject: [PATCH 31/31] More JSON.NET fixes --- TGS.Server/Instance/Repository.cs | 3 ++- TGS.Server/RepoConfig.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/TGS.Server/Instance/Repository.cs b/TGS.Server/Instance/Repository.cs index 7ef2b2215e..1b19efaec2 100644 --- a/TGS.Server/Instance/Repository.cs +++ b/TGS.Server/Instance/Repository.cs @@ -1,5 +1,6 @@ using LibGit2Sharp; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; @@ -962,7 +963,7 @@ namespace TGS.Server } var dick = JsonConvert.DeserializeObject>(json); - var user = JsonConvert.DeserializeObject>((string)dick["user"]); + var user = ((JObject)dick["user"]).ToObject>(); newPR.Add("commit", atSHA ?? branch.Tip.Sha); newPR.Add("author", (string)user["login"]); diff --git a/TGS.Server/RepoConfig.cs b/TGS.Server/RepoConfig.cs index 9f115d7955..8096c6783f 100644 --- a/TGS.Server/RepoConfig.cs +++ b/TGS.Server/RepoConfig.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; @@ -52,7 +53,7 @@ namespace TGS.Server var json = JsonConvert.DeserializeObject>(rawdata); try { - var details = JsonConvert.DeserializeObject>((string)json["changelog"]); + var details = ((JObject)json["changelog"]).ToObject>(); PathToChangelogPy = (string)details["script"]; ChangelogPyArguments = (string)details["arguments"]; ChangelogSupport = true;