diff --git a/TGS.CommandLine/AdminCommands.cs b/TGS.CommandLine/AdminCommands.cs index 953c002b07..41addc7b7b 100644 --- a/TGS.CommandLine/AdminCommands.cs +++ b/TGS.CommandLine/AdminCommands.cs @@ -1,10 +1,9 @@ using System.Collections.Generic; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { - class AdminCommand : InstanceRootCommand + sealed class AdminCommand : RootCommand { public AdminCommand() { @@ -26,7 +25,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().RecreateStaticFolder(); + var res = Instance.Administration.RecreateStaticFolder(); OutputProc(res ?? "Success"); return res == null ? ExitCode.Normal : ExitCode.ServerError; } @@ -50,7 +49,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var group = Interface.GetComponent().GetCurrentAuthorizedGroup(); + var group = Instance.Administration.GetCurrentAuthorizedGroup(); OutputProc(group ?? "ERROR"); return group != null ? ExitCode.Normal : ExitCode.ServerError; } @@ -75,7 +74,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var result = Interface.GetComponent().SetAuthorizedGroup(parameters[0]); + var result = Instance.Administration.SetAuthorizedGroup(parameters[0]); if(result != null) { OutputProc("Group set to: " + result); @@ -103,7 +102,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().SetAuthorizedGroup(null); + var res = Instance.Administration.SetAuthorizedGroup(null); if(res != "ADMIN") { OutputProc("Failed to clear the group??? We are currently set to: " + res); diff --git a/TGS.CommandLine/BYONDCommands.cs b/TGS.CommandLine/BYONDCommands.cs index 869c1ccfd3..84e1209781 100644 --- a/TGS.CommandLine/BYONDCommands.cs +++ b/TGS.CommandLine/BYONDCommands.cs @@ -2,11 +2,10 @@ using System.Collections.Generic; using System.Threading; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { - class BYONDCommand : InstanceRootCommand + class BYONDCommand : RootCommand { public BYONDCommand() { @@ -33,7 +32,7 @@ namespace TGS.CommandLine type = ByondVersion.Staged; else if (parameters[0].ToLower() == "--latest") type = ByondVersion.Latest; - OutputProc(Interface.GetComponent().GetVersion(type) ?? "Unistalled"); + OutputProc(Instance.Byond.GetVersion(type) ?? "Unistalled"); return ExitCode.Normal; } public override string GetArgumentString() @@ -56,7 +55,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - switch (Interface.GetComponent().CurrentStatus()) + switch (Instance.Byond.CurrentStatus()) { case ByondStatus.Downloading: OutputProc("Downloading update..."); @@ -109,7 +108,7 @@ namespace TGS.CommandLine return ExitCode.BadCommand; } - var BYOND = Interface.GetComponent(); + var BYOND = Instance.Byond; if (!BYOND.UpdateToVersion(Major, Minor)) { diff --git a/TGS.CommandLine/ChatCommands.cs b/TGS.CommandLine/ChatCommands.cs index bf5fd5d3aa..6e87e34944 100644 --- a/TGS.CommandLine/ChatCommands.cs +++ b/TGS.CommandLine/ChatCommands.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { - class IRCCommand : InstanceRootCommand + class IRCCommand : RootCommand { public IRCCommand() { @@ -17,7 +16,7 @@ namespace TGS.CommandLine return "Manages the IRC bot"; } } - class DiscordCommand : InstanceRootCommand + class DiscordCommand : RootCommand { public DiscordCommand() { @@ -48,7 +47,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; Chat.SetProviderInfo(new IRCSetupInfo(Chat.ProviderInfos()[(int)ChatProvider.IRC]) { Nickname = parameters[0], @@ -78,7 +77,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[providerIndex]; List channels; @@ -156,7 +155,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[providerIndex]; List channels; @@ -222,7 +221,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var info = Interface.GetComponent().ProviderInfos()[providerIndex]; + var info = Instance.Chat.ProviderInfos()[providerIndex]; string authType; switch ((ChatProvider)providerIndex) { @@ -281,7 +280,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().Reconnect(providerIndex); + var res = Instance.Chat.Reconnect(providerIndex); if (res != null) { OutputProc("Error: " + res); @@ -310,7 +309,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[providerIndex]; var newmin = parameters[0].ToLower(); @@ -355,7 +354,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[(int)ChatProvider.IRC]; var lowerparam = parameters[0].ToLower(); if (lowerparam == "channel-mode") @@ -394,7 +393,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[(int)ChatProvider.Discord]; var lowerparam = parameters[0].ToLower(); if (lowerparam == "role-id") @@ -433,7 +432,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = new IRCSetupInfo(IRC.ProviderInfos()[(int)ChatProvider.IRC]); switch (parameters[0]) { @@ -482,7 +481,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[providerIndex]; var newmin = parameters[0].ToLower(); @@ -529,7 +528,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; IRC.SetProviderInfo(new IRCSetupInfo(IRC.ProviderInfos()[(int)ChatProvider.IRC]) { AuthTarget = parameters[0], @@ -551,7 +550,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; IRC.SetProviderInfo(new IRCSetupInfo(IRC.ProviderInfos()[(int)ChatProvider.IRC]) { AuthTarget = null, @@ -575,7 +574,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var IRC = Interface.GetComponent(); + var IRC = Instance.Chat; var info = IRC.ProviderInfos()[providerIndex]; OutputProc("Currently configured channels:"); OutputProc("Admin:"); @@ -610,7 +609,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; var info = Chat.ProviderInfos()[providerIndex]; info.Enabled = true; var res = Chat.SetProviderInfo(info); @@ -638,7 +637,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; var info = Chat.ProviderInfos()[providerIndex]; info.Enabled = false; var res = Chat.SetProviderInfo(info); @@ -675,7 +674,7 @@ namespace TGS.CommandLine OutputProc("Invalid parameter!"); return ExitCode.BadCommand; } - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; var PI = new IRCSetupInfo(Chat.ProviderInfos()[(int)ChatProvider.IRC]) { URL = splits[0] @@ -713,7 +712,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; var res = Chat.SetProviderInfo(new DiscordSetupInfo(Chat.ProviderInfos()[(int)ChatProvider.Discord]) { BotToken = parameters[0] }); OutputProc(res ?? "Success"); return res == null ? ExitCode.Normal : ExitCode.ServerError; diff --git a/TGS.CommandLine/ConfigCommands.cs b/TGS.CommandLine/ConfigCommands.cs index ab4191a5d6..c047d6c3dd 100644 --- a/TGS.CommandLine/ConfigCommands.cs +++ b/TGS.CommandLine/ConfigCommands.cs @@ -2,11 +2,10 @@ using System.Collections.Generic; using System.IO; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { - class ConfigCommand : InstanceRootCommand + class ConfigCommand : RootCommand { public ConfigCommand() { @@ -28,7 +27,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().DeleteFile(parameters[0], out bool unauthorized); + var res = Instance.Config.DeleteFile(parameters[0], out bool unauthorized); if (res != null) { OutputProc(res); @@ -64,7 +63,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var list = Interface.GetComponent().ListStaticDirectory(parameters.Count > 0 ? parameters[0] : null, out string error, out bool unauthorized); + var list = Instance.Config.ListStaticDirectory(parameters.Count > 0 ? parameters[0] : null, out string error, out bool unauthorized); if(list == null) { OutputProc(error); @@ -88,7 +87,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - OutputProc(Interface.GetComponent().ServerDirectory()); + OutputProc(Instance.ServerDirectory()); return ExitCode.Normal; } @@ -108,7 +107,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var bytes = Interface.GetComponent().ReadText(parameters[0], parameters.Count > 2 && parameters[2].ToLower() == "--repo", out string error, out bool unauthorized); + var bytes = Instance.Config.ReadText(parameters[0], parameters.Count > 2 && parameters[2].ToLower() == "--repo", out string error, out bool unauthorized); if(bytes == null) { OutputProc("Error: " + error); @@ -148,7 +147,7 @@ namespace TGS.CommandLine { try { - var res = Interface.GetComponent().WriteText(parameters[0], File.ReadAllText(parameters[1]), out bool unauthorized); + var res = Instance.Config.WriteText(parameters[0], File.ReadAllText(parameters[1]), out bool unauthorized); if (res != null) { OutputProc("Error: " + res); diff --git a/TGS.CommandLine/ConsoleCommand.cs b/TGS.CommandLine/ConsoleCommand.cs index 1aa0e3f773..56b0381ee1 100644 --- a/TGS.CommandLine/ConsoleCommand.cs +++ b/TGS.CommandLine/ConsoleCommand.cs @@ -5,8 +5,12 @@ namespace TGS.CommandLine abstract class ConsoleCommand : Command { /// - /// The currently in use by the + /// The currently in use by the /// - public static IServerInterface Interface; + public static IServer Server; + /// + /// The currently in use by the + /// + public static IInstance Instance; } } diff --git a/TGS.CommandLine/DDCommands.cs b/TGS.CommandLine/DDCommands.cs index 9681589cf8..41ad8fe94d 100644 --- a/TGS.CommandLine/DDCommands.cs +++ b/TGS.CommandLine/DDCommands.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { - class DDCommand : InstanceRootCommand + class DDCommand : RootCommand { public DDCommand() { @@ -38,7 +37,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().WorldAnnounce(String.Join(" ", parameters)); + var res = Instance.DreamDaemon.WorldAnnounce(String.Join(" ", parameters)); OutputProc(res ?? "Success!"); return res == null ? ExitCode.Normal : ExitCode.ServerError; } @@ -58,7 +57,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().Start(); + var res = Instance.DreamDaemon.Start(); OutputProc(res ?? "Success!"); return res == null ? ExitCode.Normal : ExitCode.ServerError; } @@ -82,7 +81,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var DD = Interface.GetComponent(); + var DD = Instance.DreamDaemon; if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful") { if (DD.DaemonStatus() != DreamDaemonStatus.Online) @@ -111,7 +110,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var DD = Interface.GetComponent(); + var DD = Instance.DreamDaemon; if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful") { if (DD.DaemonStatus() != DreamDaemonStatus.Online) @@ -146,7 +145,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var DD = Interface.GetComponent(); + var DD = Instance.DreamDaemon; OutputProc(DD.StatusString(true)); if (DD.ShutdownInProgress()) OutputProc("The server will shutdown once the current round completes."); @@ -167,7 +166,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var DD = Interface.GetComponent(); + var DD = Instance.DreamDaemon; switch (parameters[0].ToLower()) { case "on": @@ -205,7 +204,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var DD = Interface.GetComponent(); + var DD = Instance.DreamDaemon; switch (parameters[0].ToLower()) { case "on": @@ -255,7 +254,7 @@ namespace TGS.CommandLine return ExitCode.BadCommand; } - Interface.GetComponent().SetPort(port); + Instance.DreamDaemon.SetPort(port); return ExitCode.Normal; } @@ -298,7 +297,7 @@ namespace TGS.CommandLine OutputProc("Invalid security word!"); return ExitCode.BadCommand; } - Interface.GetComponent().SetSecurityLevel(sec); + Instance.DreamDaemon.SetSecurityLevel(sec); return ExitCode.Normal; } diff --git a/TGS.CommandLine/DMCommands.cs b/TGS.CommandLine/DMCommands.cs index 380f2307e7..47d9959e4f 100644 --- a/TGS.CommandLine/DMCommands.cs +++ b/TGS.CommandLine/DMCommands.cs @@ -2,11 +2,10 @@ using System.Collections.Generic; using System.Threading; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { - class DMCommand : InstanceRootCommand + class DMCommand : RootCommand { public DMCommand() { @@ -28,7 +27,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var DM = Interface.GetComponent(); + var DM = Instance.Compiler; var stat = DM.GetStatus(); if (stat != CompilerStatus.Initialized) { @@ -36,7 +35,7 @@ namespace TGS.CommandLine return ExitCode.ServerError; } - if (Interface.GetComponent().GetVersion(ByondVersion.Installed) == null) + if (Instance.Byond.GetVersion(ByondVersion.Installed) == null) { Console.Write("Error: BYOND is not installed!"); return ExitCode.ServerError; @@ -84,14 +83,14 @@ namespace TGS.CommandLine void ShowError() { - var error = Interface.GetComponent().CompileError(); + var error = Instance.Compiler.CompileError(); if (error != null) OutputProc("Last error: " + error); } protected override ExitCode Run(IList parameters) { - var DM = Interface.GetComponent(); + var DM = Instance.Compiler; OutputProc(String.Format("Target Project: /{0}.dme", DM.ProjectName())); Console.Write("Compilier is currently: "); switch (DM.GetStatus()) @@ -142,7 +141,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - Interface.GetComponent().SetProjectName(parameters[0]); + Instance.Compiler.SetProjectName(parameters[0]); return ExitCode.Normal; } } @@ -166,7 +165,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var DM = Interface.GetComponent(); + var DM = Instance.Compiler; var stat = DM.GetStatus(); if (stat == CompilerStatus.Compiling || stat == CompilerStatus.Initializing) { @@ -206,7 +205,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().Cancel(); + var res = Instance.Compiler.Cancel(); OutputProc(res ?? "Success!"); return ExitCode.Normal; //because failing cancellation implys it's already cancelled } diff --git a/TGS.CommandLine/InstanceRootCommand.cs b/TGS.CommandLine/InstanceRootCommand.cs deleted file mode 100644 index 107fe20689..0000000000 --- a/TGS.CommandLine/InstanceRootCommand.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.Generic; -using TGS.Interface; - -namespace TGS.CommandLine -{ - abstract class InstanceRootCommand : RootCommand - { - public static IServerInterface currentInterface; - public override ExitCode DoRun(IList parameters) - { - if (currentInterface.InstanceName == null) - { - OutputProc("Missing instance!"); - return ExitCode.BadCommand; - } - else - { - var res = currentInterface.ConnectToInstance(); - if (!res.HasFlag(ConnectivityLevel.Connected)) - { - OutputProc("Unable to connect to instance!"); - return ExitCode.ConnectionError; - } - else if (!res.HasFlag(ConnectivityLevel.Authenticated)) - { - OutputProc("The current user is not authorized to use this instance!"); - return ExitCode.ConnectionError; - } - } - return base.DoRun(parameters); - } - } -} diff --git a/TGS.CommandLine/Program.cs b/TGS.CommandLine/Program.cs index 0e2986d944..369652de33 100644 --- a/TGS.CommandLine/Program.cs +++ b/TGS.CommandLine/Program.cs @@ -9,7 +9,7 @@ namespace TGS.CommandLine class Program { static bool interactive = false, saidSrvVersion = false; - static IServerInterface currentInterface; + static IClient currentInterface; static Command.ExitCode RunCommandLine(IList argsAsList) { //first lookup the connection string @@ -52,7 +52,7 @@ namespace TGS.CommandLine } argsAsList.RemoveAt(I); argsAsList.RemoveAt(I); - ReplaceInterface(new ServerInterface(new RemoteLoginInfo(address, port, username, password))); + ReplaceInterface(new Client(new RemoteLoginInfo(address, port, username, password))); break; } } @@ -84,7 +84,7 @@ namespace TGS.CommandLine } else if (interactive && !saidSrvVersion) { - Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent().Version()); + Console.WriteLine("Connectd to service version: " + currentInterface.Server.Version); saidSrvVersion = true; } @@ -99,11 +99,11 @@ namespace TGS.CommandLine }; } - static void ReplaceInterface(IServerInterface I) + static void ReplaceInterface(IClient I) { currentInterface = I; - ConsoleCommand.Interface = I; - InstanceRootCommand.currentInterface = I; + ConsoleCommand.Server = I.Server; + ConsoleCommand.Instance = null; saidSrvVersion = false; } @@ -156,26 +156,24 @@ namespace TGS.CommandLine /// /// The name of the to test /// If , does not output on success - /// if a was achieved with , otherwise + /// if the connection was made, 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 + var res = currentInterface.Server.Instances.Where(x => x.Metadata.Name == instanceName).FirstOrDefault(); + if (res != null) { - if(!silentSuccess) + ConsoleCommand.Instance = res; + if (!silentSuccess) Console.WriteLine("Successfully conected to instance!"); return true; } + Console.WriteLine("Unable to connect to instance! Does it exist?"); return false; } static int Main(string[] args) { - ReplaceInterface(new ServerInterface()); + ReplaceInterface(new Client()); Command.OutputProcVar.Value = Console.WriteLine; if (args.Length != 0) { @@ -193,13 +191,13 @@ namespace TGS.CommandLine { argsAsList.RemoveAt(I); --I; - ServerInterface.SetBadCertificateHandler(_ => false); + Client.SetBadCertificateHandler(_ => false); } } return (int)RunCommandLine(argsAsList); } //interactive mode - ServerInterface.SetBadCertificateHandler(BadCertificateInteractive); + Client.SetBadCertificateHandler(BadCertificateInteractive); Console.WriteLine("Type 'instance' to connect to a server instance"); Console.WriteLine("Type 'remote' to connect to a remote service"); while (true) @@ -230,17 +228,17 @@ namespace TGS.CommandLine var username = Console.ReadLine(); Console.Write("Enter password: "); var password = ReadLineSecure(); - ReplaceInterface(new ServerInterface(new RemoteLoginInfo(address, port, username, password))); + ReplaceInterface(new Client(new RemoteLoginInfo(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()); + ReplaceInterface(new Client()); } else if (!res.HasFlag(ConnectivityLevel.Authenticated)) { Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode..."); - ReplaceInterface(new ServerInterface()); + ReplaceInterface(new Client()); } else { @@ -255,14 +253,14 @@ namespace TGS.CommandLine break; case "disconnect": SentVMMWarning = false; - ReplaceInterface(new ServerInterface()); + ReplaceInterface(new Client()); Console.WriteLine("Switch to local mode"); break; case "quit": case "exit": return (int)Command.ExitCode.Normal; case "debug-upgrade": - currentInterface.GetServiceComponent().PrepareForUpdate(); + currentInterface.Server.Management.PrepareForUpdate(); return (int)Command.ExitCode.Normal; default: //linq voodoo to get quoted strings diff --git a/TGS.CommandLine/RepoCommands.cs b/TGS.CommandLine/RepoCommands.cs index a24a26d68f..30a7a0613d 100644 --- a/TGS.CommandLine/RepoCommands.cs +++ b/TGS.CommandLine/RepoCommands.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { @@ -40,10 +39,10 @@ namespace TGS.CommandLine switch (parameters[0].ToLower()) { case "on": - Interface.GetComponent().SetPushTestmergeCommits(true); + Instance.Repository.SetPushTestmergeCommits(true); break; case "off": - Interface.GetComponent().SetPushTestmergeCommits(false); + Instance.Repository.SetPushTestmergeCommits(false); break; default: OutputProc("Invalid option!"); @@ -67,7 +66,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().UpdateTGS3Json(); + var res = Instance.Repository.UpdateTGS3Json(); if (res != null) { OutputProc(res); @@ -86,7 +85,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().Setup(parameters[0], parameters.Count > 1 ? parameters[1] : "master"); + var res = Instance.Repository.Setup(parameters[0], parameters.Count > 1 ? parameters[1] : "master"); if (res != null) { OutputProc("Error: " + res); @@ -113,7 +112,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var Repo = Interface.GetComponent(); + var Repo = Instance.Repository; var busy = Repo.OperationInProgress(); if (!busy) { @@ -167,7 +166,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var result = Interface.GetComponent().Reset(parameters.Count > 0 && parameters[0].ToLower() == "--origin"); + var result = Instance.Repository.Reset(parameters.Count > 0 && parameters[0].ToLower() == "--origin"); OutputProc(result ?? "Success!"); return result == null ? ExitCode.Normal : ExitCode.ServerError; } @@ -203,7 +202,7 @@ namespace TGS.CommandLine OutputProc("Invalid parameter: " + parameters[0]); return ExitCode.BadCommand; } - var res = Interface.GetComponent().Update(hard); + var res = Instance.Repository.Update(hard); OutputProc(res ?? "Success"); return res == null ? ExitCode.Normal : ExitCode.ServerError; } @@ -224,7 +223,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var result = Interface.GetComponent().GenerateChangelog(out string error); + var result = Instance.Repository.GenerateChangelog(out string error); OutputProc(error ?? "Success!"); if (result != null) OutputProc(result); @@ -244,7 +243,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var result = Interface.GetComponent().SynchronizePush(); + var result = Instance.Repository.SynchronizePush(); if(result != null) OutputProc(result); return result == null ? ExitCode.Normal : ExitCode.ServerError; @@ -264,7 +263,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - Interface.GetComponent().SetCommitterEmail(parameters[0]); + Instance.Repository.SetCommitterEmail(parameters[0]); return ExitCode.Normal; } @@ -286,7 +285,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - Interface.GetComponent().SetCommitterName(parameters[0]); + Instance.Repository.SetCommitterName(parameters[0]); return ExitCode.Normal; } public override string GetArgumentString() @@ -319,7 +318,7 @@ namespace TGS.CommandLine OutputProc("Invalid PR Number!"); return ExitCode.BadCommand; } - var res = Interface.GetComponent().MergePullRequest(PR); + var res = Instance.Repository.MergePullRequest(PR); OutputProc(res ?? "Success"); return res == null ? ExitCode.Normal : ExitCode.ServerError; } @@ -346,7 +345,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var data = Interface.GetComponent().MergedPullRequests(out string error); + var data = Instance.Repository.MergedPullRequests(out string error); if (data == null) { OutputProc(error); @@ -373,7 +372,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var data = Interface.GetComponent().ListBackups(out string error); + var data = Instance.Repository.ListBackups(out string error); if (data == null) { OutputProc(error); @@ -400,7 +399,7 @@ namespace TGS.CommandLine } protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().Checkout(parameters[0]); + var res = Instance.Repository.Checkout(parameters[0]); OutputProc(res ?? "Success"); return res == null ? ExitCode.Normal : ExitCode.ServerError; } diff --git a/TGS.CommandLine/RootCommands.cs b/TGS.CommandLine/RootCommands.cs index de6edae4ac..0de21674cd 100644 --- a/TGS.CommandLine/RootCommands.cs +++ b/TGS.CommandLine/RootCommands.cs @@ -1,18 +1,17 @@ using System; using System.Collections.Generic; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.CommandLine { class CLICommand : RootCommand { - public CLICommand(IServerInterface I) + public CLICommand(IClient 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)) + if (ConsoleCommand.Instance.Administration != null) tmp.Add(new AdminCommand()); - if (I.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator)) + if (ConsoleCommand.Server.Management != null) tmp.Add(new ServiceCommand()); Children = tmp.ToArray(); } @@ -37,7 +36,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { - var res = Interface.GetComponent().AutoUpdateInterval(); + var res = Instance.Repository.AutoUpdateInterval(); OutputProc(res == 0 ? "OFF" : String.Format("Auto updating every {0} minutes", res)); return ExitCode.Normal; } @@ -76,7 +75,7 @@ namespace TGS.CommandLine return ExitCode.BadCommand; } - Interface.GetComponent().SetAutoUpdateInterval(NewInterval); + Instance.Repository.SetAutoUpdateInterval(NewInterval); return ExitCode.Normal; } @@ -91,7 +90,7 @@ namespace TGS.CommandLine protected override ExitCode Run(IList parameters) { var gen_cl = parameters.Count > 1 && parameters[1].ToLower() == "--cl"; - var Repo = Interface.GetComponent(); + var Repo = Instance.Repository; switch (parameters[0].ToLower()) { case "hard": @@ -126,7 +125,7 @@ namespace TGS.CommandLine OutputProc(res); } } - var resu = Interface.GetComponent().Compile(true); + var resu = Instance.Compiler.Compile(true); OutputProc(resu ? "Compilation started!" : "Compilation could not be started!"); return resu ? ExitCode.Normal : ExitCode.ServerError; } @@ -163,7 +162,7 @@ namespace TGS.CommandLine OutputProc("Invalid tesmerge #: " + parameters[0]); return ExitCode.BadCommand; } - var Repo = Interface.GetComponent(); + var Repo = Instance.Repository; var res = Repo.MergePullRequest(tm); if (res != null) { @@ -176,7 +175,7 @@ namespace TGS.CommandLine OutputProc(res); return ExitCode.ServerError; } - var resu = Interface.GetComponent().Compile(true); + var resu = Instance.Compiler.Compile(true); OutputProc(resu ? "Compilation started!" : "Compilation could not be started!"); return resu ? ExitCode.Normal : ExitCode.ServerError; } diff --git a/TGS.CommandLine/ServiceCommands.cs b/TGS.CommandLine/ServiceCommands.cs index 833469d0c8..d1a3274d60 100644 --- a/TGS.CommandLine/ServiceCommands.cs +++ b/TGS.CommandLine/ServiceCommands.cs @@ -55,7 +55,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().CreateInstance(parameters[0], parameters[1]); + var res = Server.InstanceManager.CreateInstance(parameters[0], parameters[1]); if (res != null) { OutputProc(res); @@ -87,8 +87,8 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - foreach (var I in Interface.GetServiceComponent().ListInstances()) - OutputProc(String.Format("{0} ({1}):\t{2}{3}", I.Name, I.Path, I.Enabled ? "Online" : "Offline", I.Enabled ? String.Format(" ({0})", I.LoggingID) : "")); + foreach (var I in Server.Instances) + OutputProc(I.ToString()); return ExitCode.Normal; } } @@ -122,7 +122,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().DetachInstance(parameters[0]); + var res = Server.InstanceManager.DetachInstance(parameters[0]); if (res != null) { OutputProc(res); @@ -161,7 +161,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().ImportInstance(parameters[0]); + var res = Server.InstanceManager.ImportInstance(parameters[0]); if (res != null) { OutputProc(res); @@ -193,7 +193,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().PythonPath(); + var res = Server.Management.PythonPath(); if (res != null) { OutputProc(res); @@ -232,7 +232,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - Interface.GetServiceComponent().SetPythonPath(parameters[0]); + Server.Management.SetPythonPath(parameters[0]); return ExitCode.Normal; } } @@ -266,7 +266,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().SetInstanceEnabled(parameters[0], true); + var res = Server.InstanceManager.SetInstanceEnabled(parameters[0], true); if (res != null) { OutputProc(res); @@ -305,7 +305,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().SetInstanceEnabled(parameters[0], false); + var res = Server.InstanceManager.SetInstanceEnabled(parameters[0], false); if (res != null) { OutputProc(res); @@ -316,7 +316,7 @@ namespace TGS.CommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceRemoteAccessPortCommand : ConsoleCommand { @@ -337,7 +337,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - OutputProc(Interface.GetServiceComponent().RemoteAccessPort().ToString()); + OutputProc(Server.Management.RemoteAccessPort().ToString()); return ExitCode.Normal; } } @@ -382,7 +382,7 @@ namespace TGS.CommandLine return ExitCode.BadCommand; } - var res = Interface.GetServiceComponent().SetRemoteAccessPort(port); + var res = Server.Management.SetRemoteAccessPort(port); if (res != null) { OutputProc(res); @@ -422,7 +422,7 @@ namespace TGS.CommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetServiceComponent().RenameInstance(parameters[0], parameters[1]); + var res = Server.InstanceManager.RenameInstance(parameters[0], parameters[1]); if (res != null) { OutputProc(res); diff --git a/TGS.CommandLine/TGS.CommandLine.csproj b/TGS.CommandLine/TGS.CommandLine.csproj index a4086c5979..d0369c4c5d 100644 --- a/TGS.CommandLine/TGS.CommandLine.csproj +++ b/TGS.CommandLine/TGS.CommandLine.csproj @@ -51,7 +51,6 @@ - diff --git a/TGS.ControlPanel/ControlPanel/ByondPage.cs b/TGS.ControlPanel/ControlPanel/ByondPage.cs index 4935b7b3e4..f5ec5546d7 100644 --- a/TGS.ControlPanel/ControlPanel/ByondPage.cs +++ b/TGS.ControlPanel/ControlPanel/ByondPage.cs @@ -10,7 +10,7 @@ namespace TGS.ControlPanel string lastReadError = null; void InitBYONDPage() { - var BYOND = Interface.GetComponent(); + var BYOND = Instance.Byond; var CV = BYOND.GetVersion(ByondVersion.Installed); if (CV == null) CV = BYOND.GetVersion(ByondVersion.Staged); @@ -45,7 +45,7 @@ namespace TGS.ControlPanel private void UpdateButton_Click(object sender, EventArgs e) { UpdateBYONDButtons(); - if (!Interface.GetComponent().UpdateToVersion((int)MajorVersionNumeric.Value, (int)MinorVersionNumeric.Value)) + if (!Instance.Byond.UpdateToVersion((int)MajorVersionNumeric.Value, (int)MinorVersionNumeric.Value)) MessageBox.Show("Unable to begin update, there is another operation in progress."); } @@ -55,7 +55,7 @@ namespace TGS.ControlPanel } void UpdateBYONDButtons() { - var BYOND = Interface.GetComponent(); + var BYOND = Instance.Byond; VersionLabel.Text = BYOND.GetVersion(ByondVersion.Installed) ?? "Not Installed"; @@ -88,7 +88,7 @@ namespace TGS.ControlPanel UpdateButton.Enabled = false; break; } - var error = Interface.GetComponent().GetError(); + var error = Instance.Byond.GetError(); if (error != lastReadError) { lastReadError = error; diff --git a/TGS.ControlPanel/ControlPanel/ChatPage.cs b/TGS.ControlPanel/ControlPanel/ChatPage.cs index 96a666d5c6..d512d0d6ef 100644 --- a/TGS.ControlPanel/ControlPanel/ChatPage.cs +++ b/TGS.ControlPanel/ControlPanel/ChatPage.cs @@ -19,7 +19,7 @@ namespace TGS.ControlPanel void LoadChatPage() { updatingChat = true; - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; var PI = Chat.ProviderInfos()[(int)ModifyingProvider]; ChatAdminsTextBox.Visible = true; IRCModesComboBox.Visible = false; @@ -112,7 +112,7 @@ namespace TGS.ControlPanel private void ChatReconnectButton_Click(object sender, EventArgs e) { - Interface.GetComponent().Reconnect(ModifyingProvider); + Instance.Chat.Reconnect(ModifyingProvider); LoadChatPage(); } @@ -149,7 +149,7 @@ namespace TGS.ControlPanel } void SetAdminsAreSpecial(bool value) { - var Chat = Interface.GetComponent(); + var Chat = Instance.Chat; var PI = Chat.ProviderInfos()[(int)ModifyingProvider]; PI.AdminsAreSpecial = value; var res = Chat.SetProviderInfo(PI); @@ -208,7 +208,7 @@ namespace TGS.ControlPanel wip.Enabled = ChatEnabledCheckbox.Checked; wip.AdminsAreSpecial = AdminModeSpecial.Checked; - res = Interface.GetComponent().SetProviderInfo(wip); + res = Instance.Chat.SetProviderInfo(wip); } if (res != null) MessageBox.Show(res); diff --git a/TGS.ControlPanel/ControlPanel/ControlPanel.cs b/TGS.ControlPanel/ControlPanel/ControlPanel.cs index 5ebbf73f1b..8f9368a096 100644 --- a/TGS.ControlPanel/ControlPanel/ControlPanel.cs +++ b/TGS.ControlPanel/ControlPanel/ControlPanel.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.ControlPanel { @@ -18,29 +17,34 @@ namespace TGS.ControlPanel public static IDictionary InstancesInUse { get; private set; } = new Dictionary(); /// - /// The instance for this + /// The for this /// - readonly IServerInterface Interface; + readonly IInstance Instance; /// /// Constructs a /// - /// The for the - public ControlPanel(IServerInterface I) + /// The to use + /// The to use + public ControlPanel(IServer server, IInstance instance) { InitializeComponent(); + FormClosed += ControlPanel_FormClosed; - Interface = I; - if (Interface.IsRemoteConnection) - Text = String.Format("TGS {0}: {1}:{2}", Interface.ServerVersion, Interface.LoginInfo.IP, Interface.LoginInfo.Port); - Text = String.Format("{0} Instance: {1}", Text, I.InstanceName); Panels.SelectedIndexChanged += Panels_SelectedIndexChanged; Panels.SelectedIndex += Math.Min(Properties.Settings.Default.LastPageIndex, Panels.TabCount - 1); + + Instance = instance; + + InstancesInUse.Add(Instance.Metadata.Name, this); + + Text = String.Format("TGS {0} Instance: {1}", server.Version, Instance.Metadata.Name); + InitRepoPage(); InitBYONDPage(); InitServerPage(); + UpdateSelectedPanel(); - InstancesInUse.Add(I.InstanceName, this); } /// @@ -50,7 +54,7 @@ namespace TGS.ControlPanel /// The void ControlPanel_FormClosed(object sender, FormClosedEventArgs e) { - InstancesInUse.Remove(Interface.InstanceName); + InstancesInUse.Remove(Instance.Metadata.Name); } /// @@ -58,8 +62,7 @@ namespace TGS.ControlPanel /// void Cleanup() { - InstancesInUse.Remove(Interface.InstanceName); - Interface.Dispose(); + InstancesInUse.Remove(Instance.Metadata.Name); } private void Main_Resize(object sender, EventArgs e) @@ -102,7 +105,7 @@ namespace TGS.ControlPanel bool CheckAdminWithWarning() { - if (!Interface.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator)) + if (Instance.Administration != null) { MessageBox.Show("Only system administrators may use this command!"); return false; diff --git a/TGS.ControlPanel/ControlPanel/RepoPage.cs b/TGS.ControlPanel/ControlPanel/RepoPage.cs index c6b5658e9d..5743cc5d17 100644 --- a/TGS.ControlPanel/ControlPanel/RepoPage.cs +++ b/TGS.ControlPanel/ControlPanel/RepoPage.cs @@ -76,7 +76,7 @@ namespace TGS.ControlPanel if (RepoBusyCheck()) return; - var Repo = Interface.GetComponent(); + var Repo = Instance.Repository; RepoProgressBar.Style = ProgressBarStyle.Marquee; RepoProgressBar.Visible = false; @@ -148,7 +148,7 @@ namespace TGS.ControlPanel bool RepoBusyCheck() { - if (Interface.GetComponent().OperationInProgress()) + if (Instance.Repository.OperationInProgress()) { DoAsyncOp(RepoAction.Wait, "Waiting for repository to finish another action..."); return true; @@ -170,7 +170,7 @@ namespace TGS.ControlPanel private void RepoBGW_DoWork(object sender, DoWorkEventArgs e) { //Only for clones - var Repo = Interface.GetComponent(); + var Repo = Instance.Repository; switch (action) { case RepoAction.Clone: @@ -273,7 +273,7 @@ namespace TGS.ControlPanel } private void RepoApplyButton_Click(object sender, EventArgs e) { - var Repo = Interface.GetComponent(); + var Repo = Instance.Repository; if (RepoBusyCheck()) return; @@ -344,7 +344,7 @@ namespace TGS.ControlPanel { if (MessageBox.Show("This will update the cached TGS3.json to the current repository version, potentially redefining symlinks. Proceed?", "Json Update", MessageBoxButtons.YesNo) != DialogResult.Yes) return; - var res = Interface.GetComponent().UpdateTGS3Json(); + var res = Instance.Repository.UpdateTGS3Json(); if (res != null) MessageBox.Show(res); } diff --git a/TGS.ControlPanel/ControlPanel/ServerPage.cs b/TGS.ControlPanel/ControlPanel/ServerPage.cs index 50a459c943..dee3c04e36 100644 --- a/TGS.ControlPanel/ControlPanel/ServerPage.cs +++ b/TGS.ControlPanel/ControlPanel/ServerPage.cs @@ -46,7 +46,7 @@ namespace TGS.ControlPanel private void CompileCancelButton_Click(object sender, EventArgs e) { - var res = Interface.GetComponent().Cancel(); + var res = Instance.Compiler.Cancel(); if (res != null) MessageBox.Show(res); LoadServerPage(); @@ -54,7 +54,7 @@ namespace TGS.ControlPanel void LoadServerPage() { - var RepoExists = Interface.GetComponent().Exists(); + var RepoExists = Instance.Repository.Exists(); compileButton.Visible = RepoExists; AutoUpdateCheckbox.Visible = RepoExists; initializeButton.Visible = RepoExists; @@ -83,16 +83,16 @@ namespace TGS.ControlPanel if (updatingFields) return; - var DM = Interface.GetComponent(); - var DD = Interface.GetComponent(); - var Config = Interface.GetComponent(); - var Repo = Interface.GetComponent(); + var DM = Instance.Compiler; + var DD = Instance.DreamDaemon; + var Config = Instance.Config; + var Repo = Instance.Repository; try { updatingFields = true; - ServerPathLabel.Text = "Server Path: " + Interface.GetComponent().ServerDirectory(); + ServerPathLabel.Text = "Server Path: " + Instance.ServerDirectory(); SecuritySelector.SelectedIndex = (int)DD.SecurityLevel(); @@ -197,13 +197,13 @@ namespace TGS.ControlPanel void UpdateProjectName() { if (!updatingFields) - Interface.GetComponent().SetProjectName(projectNameText.Text); + Instance.Compiler.SetProjectName(projectNameText.Text); } private void PortSelector_ValueChanged(object sender, EventArgs e) { if (!updatingFields) - Interface.GetComponent().SetPort((ushort)PortSelector.Value); + Instance.DreamDaemon.SetPort((ushort)PortSelector.Value); } private void ServerPageRefreshButton_Click(object sender, EventArgs e) @@ -213,13 +213,13 @@ namespace TGS.ControlPanel private void InitializeButton_Click(object sender, EventArgs e) { - if (!Interface.GetComponent().Initialize()) + if (!Instance.Compiler.Initialize()) MessageBox.Show("Unable to start initialization!"); LoadServerPage(); } private void CompileButton_Click(object sender, EventArgs e) { - if (!Interface.GetComponent().Compile()) + if (!Instance.Compiler.Compile()) MessageBox.Show("Unable to start compilation!"); LoadServerPage(); } @@ -227,7 +227,7 @@ namespace TGS.ControlPanel private void AutostartCheckbox_CheckedChanged(object sender, System.EventArgs e) { if (!updatingFields) - Interface.GetComponent().SetAutostart(AutostartCheckbox.Checked); + Instance.DreamDaemon.SetAutostart(AutostartCheckbox.Checked); } private void ServerStartButton_Click(object sender, System.EventArgs e) { @@ -239,7 +239,7 @@ namespace TGS.ControlPanel { try { - e.Result = Interface.GetComponent().Start(); + e.Result = Instance.DreamDaemon.Start(); } catch (Exception ex) { @@ -252,7 +252,7 @@ namespace TGS.ControlPanel var DialogResult = MessageBox.Show("This will immediately shut down the server. Continue?", "Confim", MessageBoxButtons.YesNo); if (DialogResult == DialogResult.No) return; - var res = Interface.GetComponent().Stop(); + var res = Instance.DreamDaemon.Stop(); if (res != null) MessageBox.Show(res); } @@ -262,7 +262,7 @@ namespace TGS.ControlPanel var DialogResult = MessageBox.Show("This will immediately restart the server. Continue?", "Confim", MessageBoxButtons.YesNo); if (DialogResult == DialogResult.No) return; - var res = Interface.GetComponent().Restart(); + var res = Instance.DreamDaemon.Restart(); if (res != null) MessageBox.Show(res); } @@ -274,7 +274,7 @@ namespace TGS.ControlPanel var DialogResult = MessageBox.Show("This will shut down the server when the current round ends. Continue?", "Confim", MessageBoxButtons.YesNo); if (DialogResult == DialogResult.No) return; - Interface.GetComponent().RequestStop(); + Instance.DreamDaemon.RequestStop(); LoadServerPage(); } @@ -283,7 +283,7 @@ namespace TGS.ControlPanel var DialogResult = MessageBox.Show("This will restart the server when the current round ends. Continue?", "Confim", MessageBoxButtons.YesNo); if (DialogResult == DialogResult.No) return; - Interface.GetComponent().RequestRestart(); + Instance.DreamDaemon.RequestRestart(); } /// @@ -293,7 +293,7 @@ namespace TGS.ControlPanel /// The void TestMergeManagerButton_Click(object sender, System.EventArgs e) { - using (var TMM = new TestMergeManager(Interface, ghclient)) + using (var TMM = new TestMergeManager(Instance, ghclient)) TMM.ShowDialog(); LoadServerPage(); } @@ -320,7 +320,7 @@ namespace TGS.ControlPanel try { string res = null; - var repo = Interface.GetComponent(); + var repo = Instance.Repository; var pulls = await Task.Run(() => repo.MergedPullRequests(out res)); if (pulls == null) @@ -364,7 +364,7 @@ namespace TGS.ControlPanel pulls.RemoveAll(x => x.Number == I.Result.Number); var mergeResults = await Task.Run(() => repo.MergePullRequests(pulls, true)); - var compileStartResult = await Task.Run(() => Interface.GetComponent().Compile(true)); + var compileStartResult = await Task.Run(() => Instance.Compiler.Compile(true)); //Show any errors for (var I = 0; I < mergeResults.Count(); ++I) @@ -410,7 +410,7 @@ namespace TGS.ControlPanel Enabled = false; try { - var repo = Interface.GetComponent(); + var repo = Instance.Repository; var res = await Task.Run(() => repo.Reset(true)); @@ -425,7 +425,7 @@ namespace TGS.ControlPanel if (res != null) MessageBox.Show(res, "Error generating changelog"); - await Task.Run(() => Interface.GetComponent().Compile(false)); + await Task.Run(() => Instance.Compiler.Compile(false)); if (res != null) MessageBox.Show(res, "Error starting compile!"); } @@ -452,7 +452,7 @@ namespace TGS.ControlPanel private void SecuritySelector_SelectedIndexChanged(object sender, EventArgs e) { if (!updatingFields) - if (!Interface.GetComponent().SetSecurityLevel((DreamDaemonSecurity)SecuritySelector.SelectedIndex)) + if (!Instance.DreamDaemon.SetSecurityLevel((DreamDaemonSecurity)SecuritySelector.SelectedIndex)) MessageBox.Show("Security change will be applied after next server reboot."); } @@ -461,7 +461,7 @@ namespace TGS.ControlPanel var msg = WorldAnnounceField.Text; if (!String.IsNullOrWhiteSpace(msg)) { - var res = Interface.GetComponent().WorldAnnounce(msg); + var res = Instance.DreamDaemon.WorldAnnounce(msg); if (res != null) { MessageBox.Show(res); @@ -474,13 +474,13 @@ namespace TGS.ControlPanel private void WebclientCheckBox_CheckedChanged(object sender, EventArgs e) { if (!updatingFields) - Interface.GetComponent().SetWebclient(WebclientCheckBox.Checked); + Instance.DreamDaemon.SetWebclient(WebclientCheckBox.Checked); } private void AutoUpdateInterval_ValueChanged(object sender, EventArgs e) { if (!updatingFields) - Interface.GetComponent().SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value); + Instance.Repository.SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value); } private void AutoUpdateCheckbox_CheckedChanged(object sender, EventArgs e) @@ -491,9 +491,9 @@ namespace TGS.ControlPanel AutoUpdateInterval.Visible = on; AutoUpdateMLabel.Visible = on; if (!on) - Interface.GetComponent().SetAutoUpdateInterval(0); + Instance.Repository.SetAutoUpdateInterval(0); else - Interface.GetComponent().SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value); + Instance.Repository.SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value); } } } diff --git a/TGS.ControlPanel/ControlPanel/StaticPage.cs b/TGS.ControlPanel/ControlPanel/StaticPage.cs index 0d53e7b680..76ad9b6943 100644 --- a/TGS.ControlPanel/ControlPanel/StaticPage.cs +++ b/TGS.ControlPanel/ControlPanel/StaticPage.cs @@ -29,7 +29,7 @@ namespace TGS.ControlPanel { if (initializedStaticPage) return; - if(!Interface.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator)) + if(Instance.Administration != null) RecreateStaticButton.Visible = false; BuildFileList(); initializedStaticPage = true; @@ -41,7 +41,7 @@ namespace TGS.ControlPanel IndexesToPaths.Clear(); StaticFileListBox.Items.Clear(); IndexesToPaths.Add(StaticFileListBox.Items.Add("/"), "/"); - if (EnumeratePath("", Interface.GetComponent(), 1) == EnumResult.Unauthorized) + if (EnumeratePath("", Instance.Config, 1) == EnumResult.Unauthorized) { StaticFileListBox.Items[0] += " (UNAUTHORIZED)"; IndexesToPaths[0] = null; @@ -147,7 +147,7 @@ namespace TGS.ControlPanel if (error == null) try { - error = Interface.GetComponent().WriteText(FileName, fileContents, out bool unauthorized); + error = Instance.Config.WriteText(FileName, fileContents, out bool unauthorized); } catch (Exception ex) { @@ -171,7 +171,7 @@ namespace TGS.ControlPanel string text, error; try { - text = Interface.GetComponent().ReadText(remotePath, false, out error, out bool unauthorized); + text = Instance.Config.ReadText(remotePath, false, out error, out bool unauthorized); } catch (Exception ex) { @@ -213,7 +213,7 @@ namespace TGS.ControlPanel { if (MessageBox.Show("Are you sure you want to delete " + ((string)StaticFileListBox.SelectedItem).Trim() + "?", "Confirm", MessageBoxButtons.YesNo) != DialogResult.Yes) return; - var res = Interface.GetComponent().DeleteFile(IndexesToPaths[StaticFileListBox.SelectedIndex], out bool unauthorized); + var res = Instance.Config.DeleteFile(IndexesToPaths[StaticFileListBox.SelectedIndex], out bool unauthorized); if (res != null) MessageBox.Show(res); BuildFileList(); @@ -236,7 +236,7 @@ namespace TGS.ControlPanel var FullFileName = Path.Combine(IndexesToPaths[StaticFileListBox.SelectedIndex], FileName); if (resu == DialogResult.Yes) FullFileName = Path.Combine(FullFileName, "__TGS3_CP_DIRECTORY_CREATOR__"); - var config = Interface.GetComponent(); + var config = Instance.Config; var res = config.WriteText(FullFileName, "", out bool unauthorized); if (res != null) MessageBox.Show(res); @@ -255,7 +255,7 @@ namespace TGS.ControlPanel bool unauthorized; try { - res = Interface.GetComponent().WriteText(IndexesToPaths[index], StaticFileEditTextbox.Text, out unauthorized); + res = Instance.Config.WriteText(IndexesToPaths[index], StaticFileEditTextbox.Text, out unauthorized); } catch (Exception ex) { @@ -307,7 +307,7 @@ namespace TGS.ControlPanel bool unauthorized; try { - entry = Interface.GetComponent().ReadText(path, false, out error, out unauthorized); + entry = Instance.Config.ReadText(path, false, out error, out unauthorized); } catch(Exception e) { @@ -344,7 +344,7 @@ namespace TGS.ControlPanel RecreateStaticButton.Visible = false; return; } - var res = Interface.GetComponent().RecreateStaticFolder(); + var res = Instance.Administration.RecreateStaticFolder(); if (res != null) MessageBox.Show(res); BuildFileList(); diff --git a/TGS.ControlPanel/InstanceSelector.Designer.cs b/TGS.ControlPanel/InstanceSelector.Designer.cs index 87ce1038b7..f9a745d34e 100644 --- a/TGS.ControlPanel/InstanceSelector.Designer.cs +++ b/TGS.ControlPanel/InstanceSelector.Designer.cs @@ -15,7 +15,6 @@ { if (disposing && (components != null)) { - Cleanup(); components.Dispose(); } base.Dispose(disposing); diff --git a/TGS.ControlPanel/InstanceSelector.cs b/TGS.ControlPanel/InstanceSelector.cs index 066fb9c6a9..6794995db2 100644 --- a/TGS.ControlPanel/InstanceSelector.cs +++ b/TGS.ControlPanel/InstanceSelector.cs @@ -3,23 +3,18 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Windows.Forms; using TGS.Interface; -using TGS.Interface.Components; namespace TGS.ControlPanel { /// - /// Form used for managing manipulation functions + /// Form used for managing s /// sealed partial class InstanceSelector : CountedForm { /// - /// The we build instance connections from + /// The we build instance connections from /// - readonly IServerInterface masterInterface; - /// - /// List of from - /// - IList InstanceData; + readonly IServer server; /// /// Used for modifying without invoking its side effects /// @@ -28,17 +23,17 @@ namespace TGS.ControlPanel /// /// Construct an /// - /// An connected a the - public InstanceSelector(IServerInterface I) + /// The value of + public InstanceSelector(IServer _server) { InitializeComponent(); InstanceListBox.MouseDoubleClick += InstanceListBox_MouseDoubleClick; - masterInterface = I; + server = _server; RefreshInstances(); } /// - /// Connects to a if it is double clicked in + /// Connects to a if it is double clicked in /// /// The sender of the event /// The @@ -53,36 +48,25 @@ namespace TGS.ControlPanel /// The associated with 's current selected index if it exists, otherwise InstanceMetadata GetSelectedInstanceMetadata() { - var index = InstanceListBox.SelectedIndex; - return index != ListBox.NoMatches ? InstanceData[index] : null; + var index = (IInstance)InstanceListBox.SelectedItem; + return index?.Metadata; } /// - /// Called by + /// Loads the using /// - void Cleanup() - { - masterInterface.Dispose(); - } - - /// - /// Loads the using - /// - async void RefreshInstances() + void RefreshInstances() { InstanceListBox.Items.Clear(); - await WrapServerOp(() => { - InstanceData = masterInterface.GetServiceComponent().ListInstances(); - }); - foreach(var I in InstanceData) - InstanceListBox.Items.Add(String.Format("{0}: {1} - {2} - {3}", I.LoggingID, I.Name, I.Path, I.Enabled ? "ONLINE" : "OFFLINE")); - var HasServerAdmin = masterInterface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator); + foreach(var I in server.Instances) + InstanceListBox.Items.Add(I); + var HasServerAdmin = server.InstanceManager != null; CreateInstanceButton.Enabled = HasServerAdmin; ImportInstanceButton.Enabled = HasServerAdmin; RenameInstanceButton.Enabled = HasServerAdmin; DetachInstanceButton.Enabled = HasServerAdmin; EnabledCheckBox.Enabled = HasServerAdmin; - if(InstanceData.Count > 0) + if(InstanceListBox.Items.Count > 0) InstanceListBox.SelectedIndex = 0; } @@ -90,40 +74,22 @@ namespace TGS.ControlPanel /// Tries to start a for a given /// /// The of to connect to - async void TryConnectToIndexInstance(int index) + void TryConnectToIndexInstance(int index) { if (index == ListBox.NoMatches) return; - var instanceName = InstanceData[index].Name; - if (ControlPanel.InstancesInUse.TryGetValue(instanceName, out ControlPanel activeCP)) + var instance = (IInstance)InstanceListBox.Items[index]; + if (ControlPanel.InstancesInUse.TryGetValue(instance.Metadata.Name, out ControlPanel activeCP)) { activeCP.BringToFront(); return; } - var InstanceAccessor = masterInterface.IsRemoteConnection ? new ServerInterface(masterInterface.LoginInfo) : new ServerInterface(); - try - { - ConnectivityLevel res = ConnectivityLevel.None; - await WrapServerOp(() => { res = InstanceAccessor.ConnectToInstance(instanceName); }); - if (!res.HasFlag(ConnectivityLevel.Connected)) - { - MessageBox.Show("Unable to connect to instance! Does it exist?"); - RefreshInstances(); - } - else if (!res.HasFlag(ConnectivityLevel.Authenticated)) - MessageBox.Show("The current user is not authorized to access this instance!"); - else - new ControlPanel(InstanceAccessor).Show(); - } - catch - { - InstanceAccessor.Dispose(); - throw; - } + + new ControlPanel(server, instance).Show(); } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -135,7 +101,7 @@ namespace TGS.ControlPanel if (MessageBox.Show(String.Format("This will dissociate the server instance at \"{0}\"! Are you sure?", imd.Path), "Instance Detach", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().DetachInstance(imd.Name)); + await WrapServerOp(() => res = server.InstanceManager.DetachInstance(imd.Name)); if (res != null) MessageBox.Show(res); RefreshInstances(); @@ -152,7 +118,7 @@ namespace TGS.ControlPanel } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -167,14 +133,14 @@ namespace TGS.ControlPanel if (imd.Enabled && MessageBox.Show(String.Format("This will temporarily offline the server instance! Are you sure?", imd.Path), "Instance Restart", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().RenameInstance(imd.Name, new_name)); + await WrapServerOp(() => res = server.InstanceManager.RenameInstance(imd.Name, new_name)); if (res != null) MessageBox.Show(res); RefreshInstances(); } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -184,14 +150,14 @@ namespace TGS.ControlPanel if (instance_path == null) return; string res = null; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().ImportInstance(instance_path)); + await WrapServerOp(() => res = server.InstanceManager.ImportInstance(instance_path)); if (res != null) MessageBox.Show(res); RefreshInstances(); } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -204,14 +170,14 @@ namespace TGS.ControlPanel if (instance_path == null) return; string res = null; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().CreateInstance(instance_name, instance_path)); + await WrapServerOp(() => res = server.InstanceManager.CreateInstance(instance_name, instance_path)); if (res != null) MessageBox.Show(res); RefreshInstances(); } /// - /// Attempts to connect the user to an based on the of + /// Attempts to connect the user to an based on the of /// /// The sender of the event /// The @@ -221,7 +187,7 @@ namespace TGS.ControlPanel } /// - /// Prompts the user if they want to call to either online or offline an based on its current state + /// Prompts the user if they want to call to either online or offline an based on its current state /// /// The sender of the event /// The @@ -235,8 +201,7 @@ namespace TGS.ControlPanel if (MessageBox.Show(String.Format("Are you sure you want to {0} this instance?", enabling ? "online" : "offline"), "Instance Status Change", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - var index = InstanceListBox.SelectedIndex; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().SetInstanceEnabled(InstanceData[index].Name, enabling)); + await WrapServerOp(() => res = server.InstanceManager.SetInstanceEnabled(GetSelectedInstanceMetadata().Name, enabling)); if (res != null) MessageBox.Show(res); } @@ -247,17 +212,16 @@ namespace TGS.ControlPanel } /// - /// Update based on the selected 's property + /// Update based on the selected 's property /// /// The sender of the event /// The void InstanceListBox_SelectedIndexChanged(object sender, EventArgs e) { - var index = InstanceListBox.SelectedIndex; - if (index != ListBox.NoMatches) + if (InstanceListBox.SelectedIndex != ListBox.NoMatches) { UpdatingEnabledCheckbox = true; - EnabledCheckBox.Checked = InstanceData[index].Enabled; + EnabledCheckBox.Checked = GetSelectedInstanceMetadata().Enabled; UpdatingEnabledCheckbox = false; } } diff --git a/TGS.ControlPanel/Login.cs b/TGS.ControlPanel/Login.cs index 1a1328cbda..070ed683d5 100644 --- a/TGS.ControlPanel/Login.cs +++ b/TGS.ControlPanel/Login.cs @@ -5,7 +5,7 @@ using TGS.Interface; namespace TGS.ControlPanel { - sealed partial class Login : CountedForm + sealed partial class Login : Form { /// /// Currently selected saved @@ -92,39 +92,37 @@ namespace TGS.ControlPanel loginInfo.Password = PasswordTextBox.Text; } - using (var I = new ServerInterface(loginInfo)) + var I = new Client(loginInfo); + var Config = Properties.Settings.Default; + //This needs to be read here because V&C Closing us will corrupt the data + var savePassword = SavePasswordCheckBox.Checked; + if (VerifyAndConnect(I)) { - var Config = Properties.Settings.Default; - //This needs to be read here because V&C Closing us will corrupt the data - var savePassword = SavePasswordCheckBox.Checked; - if (VerifyAndConnect(I)) - { - Config.RemoteDefault = true; + Config.RemoteDefault = true; - if (!savePassword) - loginInfo.Password = null; - - Config.RemoteLoginInfo = new StringCollection { loginInfo.ToJSON() }; - - foreach (RemoteLoginInfo info in IPComboBox.Items) - if (!info.Equals(loginInfo)) - Config.RemoteLoginInfo.Add(info.ToJSON()); - } + if (!savePassword) + loginInfo.Password = null; + + Config.RemoteLoginInfo = new StringCollection { loginInfo.ToJSON() }; + + foreach (RemoteLoginInfo info in IPComboBox.Items) + if (!info.Equals(loginInfo)) + Config.RemoteLoginInfo.Add(info.ToJSON()); } } void LocalLoginButton_Click(object sender, EventArgs e) { Properties.Settings.Default.RemoteDefault = false; - VerifyAndConnect(new ServerInterface()); + VerifyAndConnect(new Client()); } /// - /// Attempts a connection on a given + /// Attempts a connection on a given /// - /// The to attempt a connection on + /// The to attempt a connection on /// if the connection was made and authenticated, otherwise - bool VerifyAndConnect(IServerInterface I) + bool VerifyAndConnect(IClient I) { try { @@ -143,8 +141,8 @@ namespace TGS.ControlPanel if (I.VersionMismatch(out error) && MessageBox.Show(error, "Warning", MessageBoxButtons.OKCancel) == DialogResult.Cancel) return true; - new InstanceSelector(I).Show(); Close(); + Program.ServerInterface = I; return true; } catch diff --git a/TGS.ControlPanel/Program.cs b/TGS.ControlPanel/Program.cs index b72f48eb78..50768d847a 100644 --- a/TGS.ControlPanel/Program.cs +++ b/TGS.ControlPanel/Program.cs @@ -7,6 +7,7 @@ namespace TGS.ControlPanel { static class Program { + public static IClient ServerInterface; [STAThread] static void Main(string[] args) { @@ -20,13 +21,18 @@ namespace TGS.ControlPanel } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - ServerInterface.SetBadCertificateHandler(BadCertificateHandler); - var login = new Login(); - login.Show(); - Application.Run(); + Interface.Client.SetBadCertificateHandler(BadCertificateHandler); + Application.Run(new Login()); + if(ServerInterface != null) + { + new InstanceSelector(ServerInterface.Server).Show(); + Application.Run(); + } } catch (Exception e) { + if (ServerInterface != null) + ServerInterface.Dispose(); ServiceDisconnectException(e); } finally diff --git a/TGS.ControlPanel/ServerOpForm.cs b/TGS.ControlPanel/ServerOpForm.cs index 19c083b0a5..5188cd2b31 100644 --- a/TGS.ControlPanel/ServerOpForm.cs +++ b/TGS.ControlPanel/ServerOpForm.cs @@ -5,7 +5,7 @@ using System.Windows.Forms; 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 @@ -13,9 +13,9 @@ namespace TGS.ControlPanel class ServerOpForm : Form { /// - /// 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/TGS.ControlPanel/TestMergeManager.cs b/TGS.ControlPanel/TestMergeManager.cs index a7bcb7d6f5..6df18e1793 100644 --- a/TGS.ControlPanel/TestMergeManager.cs +++ b/TGS.ControlPanel/TestMergeManager.cs @@ -17,9 +17,9 @@ namespace TGS.ControlPanel const string MergedPullsError = "Error retrieving currently merged pull requests: {0}"; /// - /// The connected to an to handle the pull requests for + /// The to handle pull requests for /// - readonly IServerInterface currentInterface; + readonly IInstance currentInterface; /// /// The to use to read PR lists @@ -38,9 +38,9 @@ namespace TGS.ControlPanel /// /// Construct a /// - /// The to use for managing the + /// The to manage pull requests for /// The to use for getting pull request information - public TestMergeManager(IServerInterface interfaceToUse, GitHubClient clientToUse) + public TestMergeManager(IInstance interfaceToUse, GitHubClient clientToUse) { InitializeComponent(); DialogResult = DialogResult.Cancel; @@ -88,7 +88,7 @@ namespace TGS.ControlPanel { PullRequestListBox.Items.Clear(); - var repo = currentInterface.GetComponent(); + var repo = currentInterface.Repository; string error = null; List pulls = null; @@ -197,7 +197,7 @@ namespace TGS.ControlPanel void PullRequestManager_Load(object sender, EventArgs e) { Enabled = false; - var repo = currentInterface.GetComponent(); + var repo = currentInterface.Repository; if(!Program.GetRepositoryRemote(repo, out repoOwner, out repoName)) { Close(); @@ -256,7 +256,7 @@ namespace TGS.ControlPanel } } - var repo = currentInterface.GetComponent(); + var repo = currentInterface.Repository; string error = null; //Do standard repo updates @@ -297,7 +297,7 @@ namespace TGS.ControlPanel GenerateChangelog(repo); //Start the compile - var compileStarted = await Task.Run(() => currentInterface.GetComponent().Compile(pulls.Count == 1)); + var compileStarted = await Task.Run(() => currentInterface.Compiler.Compile(pulls.Count == 1)); if (error != null) MessageBox.Show(String.Format("Error sychronizing repo: {0}", error)); @@ -341,7 +341,7 @@ namespace TGS.ControlPanel { IList pulls = null; string error = null; - var mergedPullsTask = WrapServerOp(() => pulls = currentInterface.GetComponent().MergedPullRequests(out error)); + var mergedPullsTask = WrapServerOp(() => pulls = currentInterface.Repository.MergedPullRequests(out error)); int PRNumber; try diff --git a/TGS.Installer.UI/Main.cs b/TGS.Installer.UI/Main.cs index 57e33887d4..955283ed10 100644 --- a/TGS.Installer.UI/Main.cs +++ b/TGS.Installer.UI/Main.cs @@ -26,7 +26,7 @@ namespace TGS.Installer.UI /// bool attemptNetSettingsMigration = false; - IServerInterface Interface; + IClient Interface; /// /// Construct an installer form @@ -75,11 +75,11 @@ namespace TGS.Installer.UI } void CheckForExistingVersion() { - Interface = new ServerInterface(); + Interface = new Client(); var verifiedConnection = Interface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator); try { - var realVersion = Interface.ServerVersion; + var realVersion = Interface.Server.Version; 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"); @@ -106,7 +106,7 @@ namespace TGS.Installer.UI var connectionVerified = Interface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator); try { - Interface.GetServiceComponent().PrepareForUpdate(); + Interface.Server.Management.PrepareForUpdate(); Thread.Sleep(3000); //chat messages return true; } @@ -194,18 +194,18 @@ namespace TGS.Installer.UI var sc = new ServerConfig(); try { - sc.PythonPath = Interface.GetServiceComponent().PythonPath(); + sc.PythonPath = Interface.Server.Management.PythonPath(); } catch { } try { - sc.RemoteAccessPort = Interface.GetServiceComponent().RemoteAccessPort(); + sc.RemoteAccessPort = Interface.Server.Management.RemoteAccessPort(); } catch { } try { - foreach (var I in Interface.GetServiceComponent().ListInstances()) - sc.InstancePaths.Add(I.Path); + foreach (var I in Interface.Server.Instances) + sc.InstancePaths.Add(I.Metadata.Path); } catch { } diff --git a/TGS.Interface.Bridge/DreamDaemonBridge.cs b/TGS.Interface.Bridge/DreamDaemonBridge.cs index 7a6795c39a..8465beb682 100644 --- a/TGS.Interface.Bridge/DreamDaemonBridge.cs +++ b/TGS.Interface.Bridge/DreamDaemonBridge.cs @@ -2,8 +2,6 @@ using RGiesecke.DllExport; using System; using System.Collections.Generic; using System.Runtime.InteropServices; -using TGS.Interface; -using TGS.Interface.Components; namespace TGS.Interface.Bridge { @@ -27,9 +25,8 @@ namespace TGS.Interface.Bridge parsedArgs.AddRange(args); var instance = parsedArgs[0]; parsedArgs.RemoveAt(0); - using (var I = new ServerInterface()) - if(I.ConnectToInstance(instance, true).HasFlag(ConnectivityLevel.Connected)) - I.GetComponent().InteropMessage(String.Join(" ", parsedArgs)); + using (var I = new Client()) + I.Server.GetInstance(instance).Interop.InteropMessage(String.Join(" ", parsedArgs)); } catch { } return 0; diff --git a/TGS.Interface/Client.cs b/TGS.Interface/Client.cs new file mode 100644 index 0000000000..4d36381950 --- /dev/null +++ b/TGS.Interface/Client.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Principal; +using System.ServiceModel; +using System.ServiceModel.Description; +using TGS.Interface.Components; + +namespace TGS.Interface +{ + /// + sealed public class Client : IClient + { + /// + /// Version of the + /// + public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version; + + /// + public IServer Server => server; + + /// + public Version ServerVersion { get + { + lock (this) + if (_serverVersion == null) + { + string rawVersion; + //check ITGSService first for compatiblity reasons + try + { + rawVersion = GetComponent(null).Version(); + } + catch + { + rawVersion = GetComponent(null).Version(); + } + var splits = rawVersion.Split(' '); + _serverVersion = new Version(splits[splits.Length - 1].Substring(1)); + } + return _serverVersion; + } } + + /// + public string InstanceName { get; private set; } + + /// + public RemoteLoginInfo LoginInfo { get { return _loginInfo; } } + + /// + /// Backing field for + /// + readonly IServer server; + + /// + /// Backing field for + /// + readonly RemoteLoginInfo _loginInfo; + + /// + /// The + /// + Version _serverVersion; + + /// + /// 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; + + /// + /// 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 Client() + { + ChannelFactoryCache = new Dictionary(); + server = new Server(this); + } + + /// + /// Construct an for a remote connection + /// + /// The for a remote connection + public Client(RemoteLoginInfo loginInfo) : this() + { + if (!loginInfo.HasPassword) + throw new InvalidOperationException("password must be set on loginInfo!"); + _loginInfo = loginInfo; + } + + /// + public bool IsRemoteConnection { get { return LoginInfo != null; } } + + /// + /// Closes all s stored in and it + /// + public void Dispose() + { + lock (this) + { + if (ChannelFactoryCache == null) + return; + foreach (var I in ChannelFactoryCache) + { + var cf = I.Value; + try + { + cf.Close(); + } + catch + { + cf.Abort(); + } + } + ChannelFactoryCache = null; + } + } + + /// + public bool VersionMismatch(out string errorMessage) + { + if (ServerVersion.Major != Version.Major || ServerVersion.Minor != Version.Minor || ServerVersion.Build != Version.Build) //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.", Version, ServerVersion); + return true; + } + errorMessage = null; + return false; + } + + /// + /// 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 + /// The name of the to use + /// The correct component + internal T GetComponent(string instanceName) + { + var actualToT = typeof(T); + var tot = actualToT.Name; + if (instanceName != null) + tot = instanceName + tot; + ChannelFactory cf; + + lock (this) + { + if (ChannelFactoryCache == null) + throw new ObjectDisposedException(GetType().Name); + 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(instanceName); + ChannelFactoryCache[tot] = cf; + } + return cf.CreateChannel(); + } + + /// + /// Directly creates a for without caching. This should be eventually closed by the caller + /// + /// The component of the channel to be created + /// The instance to connect to, if any + /// The correct + ChannelFactory CreateChannel(string instanceName) + { + var accessPath = instanceName == null ? Definitions.MasterInterfaceName : String.Format("{0}/{1}", Definitions.InstanceInterfaceName, instanceName); + if (!IsRemoteConnection) + return CreateLocalChannel(instanceName, accessPath); + return CreateRemoteChannel(instanceName, accessPath); + } + + //NOTE: This needs to be kept seperate from CreateRemoteChannel because not all our client implementations have NetNamedPipeBinding and attempting to call this function on those platforms will throw an exception + + /// + /// Directly creates a for on a local connection without caching. This should be eventually closed by the caller + /// + /// The component of the channel to be created + /// The instance to connect to, if any + /// The URL of the interface to connect to + /// The correct + ChannelFactory CreateLocalChannel(string instanceName, string accessPath) + { + var interfaceName = typeof(T).Name; + var res2 = new ChannelFactory( + new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = Definitions.TransferLimitLocal }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", accessPath, interfaceName))); //10 megs + res2.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; + return res2; + } + + /// + /// Directly creates a for on a remote connection without caching. This should be eventually closed by the caller + /// + /// The component of the channel to be created + /// The instance to connect to, if any + /// The URL of the interface to connect to + /// The correct + ChannelFactory CreateRemoteChannel(string instanceName, string accessPath) + { + //okay we're going over + var binding = new BasicHttpsBinding() + { + SendTimeout = new TimeSpan(0, 0, 40), + MaxReceivedMessageSize = Definitions.TransferLimitRemote + }; + + var interfaceName = typeof(T).Name; + var requireAuth = interfaceName != typeof(ITGConnectivity).Name; + var url = String.Format("https://{0}:{1}/{2}/{3}", LoginInfo.IP, LoginInfo.Port, accessPath, interfaceName); + var address = new EndpointAddress(url); + var res = new ChannelFactory(binding, address); + if (requireAuth) + { + var applicator = new AuthenticationHeaderApplicator(LoginInfo); + var t = Type.GetType("Mono.Runtime"); + KeyedCollection behaviours; + if (t != null) + { + var prop = res.Endpoint.GetType() + .GetTypeInfo() + .GetDeclaredProperty("Behaviors"); + behaviours = (KeyedCollection)prop + .GetValue(res.Endpoint); + } + else + behaviours = res.Endpoint.EndpointBehaviors; + behaviours.Add(applicator); + } + return res; + } + + /// + public ConnectivityLevel ConnectionStatus() + { + return ConnectionStatus(out string unused); + } + + /// + public ConnectivityLevel ConnectionStatus(out string error) + { + try + { + GetComponent(null).VerifyConnection(); + } + catch (Exception e) + { + error = e.ToString(); + return ConnectivityLevel.None; + } + + try + { + GetComponent(null).Version(); + } + catch(Exception e) + { + error = e.ToString(); + return ConnectivityLevel.Connected; + } + + try + { + GetComponent(null).Version(); + error = null; + return ConnectivityLevel.Administrator; + } + catch(Exception e) + { + error = e.ToString(); + return ConnectivityLevel.Authenticated; + } + } + } +} diff --git a/TGS.Interface/Definitions.cs b/TGS.Interface/Definitions.cs new file mode 100644 index 0000000000..05cc952c33 --- /dev/null +++ b/TGS.Interface/Definitions.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using TGS.Interface.Components; + +namespace TGS.Interface +{ + /// + /// Contains constants for the interface + /// + public static class Definitions + { + /// + /// 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"; + } +} diff --git a/TGS.Interface/IClient.cs b/TGS.Interface/IClient.cs new file mode 100644 index 0000000000..02394200fa --- /dev/null +++ b/TGS.Interface/IClient.cs @@ -0,0 +1,44 @@ +using System; + +namespace TGS.Interface +{ + /// + /// Main for communicating the + /// + public interface IClient : IDisposable + { + /// + /// The the connects to + /// + IServer Server { get; } + + /// + /// The for the . Is for local connections + /// + RemoteLoginInfo LoginInfo { get; } + + /// + /// Checks if the is setup for a remote connection + /// + bool IsRemoteConnection { get; } + + /// + /// 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); + + /// + /// See without the error argument + /// + 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); + } +} diff --git a/TGS.Interface/IInstance.cs b/TGS.Interface/IInstance.cs new file mode 100644 index 0000000000..66ca33e94f --- /dev/null +++ b/TGS.Interface/IInstance.cs @@ -0,0 +1,55 @@ +using TGS.Interface.Components; + +namespace TGS.Interface +{ + /// + /// Wrapper for components + /// + public interface IInstance : ITGInstance + { + /// + /// Get the for the + /// + InstanceMetadata Metadata { get; } + + /// + /// The component. Will be if the connected user is not an administrator of the + /// + ITGAdministration Administration { get; } + + /// + /// The component + /// + ITGByond Byond { get; } + + /// + /// The component + /// + ITGChat Chat { get; } + + /// + /// The component + /// + ITGCompiler Compiler { get; } + + /// + /// The component + /// + ITGConfig Config { get; } + + /// + /// The component + /// + ITGDreamDaemon DreamDaemon { get; } + + /// + /// The component + /// + ITGInterop Interop { get; } + + /// + /// The component + /// + ITGRepository Repository { get; } + } +} diff --git a/TGS.Interface/IServer.cs b/TGS.Interface/IServer.cs new file mode 100644 index 0000000000..a81c6de744 --- /dev/null +++ b/TGS.Interface/IServer.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using TGS.Interface.Components; + +namespace TGS.Interface +{ + /// + /// Wrapper representing a + /// + public interface IServer + { + /// + /// The of the + /// + Version Version { get; } + + /// + /// Get the s the contains that the current user can access and connect to + /// + IEnumerable Instances { get; } + + /// + /// The component. Will be if the connected user is not an administrator of the + /// + ITGInstanceManager InstanceManager { get; } + + /// + /// The component. Will be if the connected user is not an administrator of the + /// + ITGSService Management { get; } + + /// + /// Gets the specified without connectivity checks + /// + /// The name of the to get + /// The named on success, on failure + IInstance GetInstance(string name); + } +} diff --git a/TGS.Interface/Instance.cs b/TGS.Interface/Instance.cs new file mode 100644 index 0000000000..31d2c31a44 --- /dev/null +++ b/TGS.Interface/Instance.cs @@ -0,0 +1,119 @@ +using System; +using System.Linq; +using TGS.Interface.Components; + +namespace TGS.Interface +{ + /// + sealed class Instance : IInstance + { + /// + public InstanceMetadata Metadata + { + get + { + if (!metadata.Enabled) + //metadata needs populating + metadata = serverInterface.GetComponent(null).ListInstances().Where(x => x.Name == metadata.Name).First(); + return metadata; + } + } + + /// + /// Whether or not the current user is known to be an administrator of the + /// + bool UserIsAdministrator + { + get + { + lock (this) + { + if (isAdministrator) + return true; + try + { + serverInterface.GetComponent(metadata.Name).GetCurrentAuthorizedGroup(); + isAdministrator = true; + return true; + } + catch + { + return false; + } + } + } + } + + /// + /// The backing + /// + readonly Client serverInterface; + /// + /// The name of the + /// + InstanceMetadata metadata; + /// + /// Backing field for + /// + bool isAdministrator; + + /// + /// Construct an + /// + /// The to use + /// The for the + public Instance(Client _serverInterface, InstanceMetadata _metadata) + { + serverInterface = _serverInterface; + metadata = _metadata; + if (metadata.Enabled) + //run a connectivity check + serverInterface.GetComponent(metadata.Name).VerifyConnection(); + } + + /// + public ITGAdministration Administration => UserIsAdministrator ? serverInterface.GetComponent(metadata.Name) : null; + + /// + public ITGByond Byond => serverInterface.GetComponent(metadata.Name); + + /// + public ITGChat Chat => serverInterface.GetComponent(metadata.Name); + + /// + public ITGCompiler Compiler => serverInterface.GetComponent(metadata.Name); + + /// + public ITGConfig Config => serverInterface.GetComponent(metadata.Name); + + /// + public ITGDreamDaemon DreamDaemon => serverInterface.GetComponent(metadata.Name); + + /// + public ITGInterop Interop => serverInterface.GetComponent(metadata.Name); + + /// + public ITGRepository Repository => serverInterface.GetComponent(metadata.Name); + + /// + public string ServerDirectory() + { + return serverInterface.GetComponent(metadata.Name).ServerDirectory(); + } + + /// + public string Version() + { + return serverInterface.GetComponent(metadata.Name).Version(); + } + + /// + /// Get a string representation of the + /// + /// A string representation of the + public override string ToString() + { + return String.Format("{0}: {1} - {2} - {3}", metadata.LoggingID, metadata.Name, metadata.Path, metadata.Enabled ? "ONLINE" : "OFFLINE"); + } + } +} diff --git a/TGS.Interface/Server.cs b/TGS.Interface/Server.cs new file mode 100644 index 0000000000..d934528832 --- /dev/null +++ b/TGS.Interface/Server.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using TGS.Interface.Components; + +namespace TGS.Interface +{ + /// + sealed class Server : IServer + { + /// + public Version Version => serverInterface.ServerVersion; + + /// + public IEnumerable Instances { get + { + lock (this) + if (knownInstances == null) + knownInstances = serverInterface.GetComponent(null).ListInstances(); + foreach (var I in knownInstances) + { + IInstance nextInstance; + try + { + nextInstance = new Instance(serverInterface, I); + } + catch + { + continue; + } + yield return nextInstance; + } + } + } + + /// + public ITGInstanceManager InstanceManager => UserIsAdministrator ? serverInterface.GetComponent(null) : null; + + /// + public ITGSService Management => UserIsAdministrator ? serverInterface.GetComponent(null) : null; + + /// + /// If the connected user is an administrator of the + /// + bool UserIsAdministrator + { + get + { + lock (this) + { + if (isAdministrator) + return true; + try + { + serverInterface.GetComponent(null).Version(); + isAdministrator = true; + return true; + } + catch + { + return false; + } + } + } + } + + /// + /// The backing + /// + readonly Client serverInterface; + + /// + /// Result of a call to + /// + IList knownInstances; + + /// + /// Backing field for + /// + bool isAdministrator; + + /// + /// Construct an + /// + /// The to use + public Server(Client _serverInterface) + { + serverInterface = _serverInterface; + } + + /// + public IInstance GetInstance(string name) + { + return new Instance(serverInterface, new InstanceMetadata { Name = name, Enabled = false }); + } + } +} diff --git a/TGS.Interface/ServerInterface.cs b/TGS.Interface/ServerInterface.cs deleted file mode 100644 index 0c358d0ba5..0000000000 --- a/TGS.Interface/ServerInterface.cs +++ /dev/null @@ -1,524 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Net; -using System.Net.Security; -using System.Reflection; -using System.Security.Principal; -using System.ServiceModel; -using System.ServiceModel.Description; -using TGS.Interface.Components; - -namespace TGS.Interface -{ - /// - /// Main for communicating the - /// - public interface IServerInterface : IDisposable - { - /// - /// The of the connected - /// - Version ServerVersion { get; } - - /// - /// The name of the current instance in use. Defaults to - /// - string InstanceName { get; } - - /// - /// The for the . Is for local connections - /// - RemoteLoginInfo LoginInfo { 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) }; - - /// - /// Version of the interface - /// - public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version; - - /// - /// 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"; - - /// - /// The - /// - Version _serverVersion; - - /// - public Version ServerVersion { get - { - lock (this) - if (_serverVersion == null) - { - string rawVersion; - //check ITGSService first for compatiblity reasons - try - { - rawVersion = GetServiceComponent().Version(); - } - catch - { - rawVersion = GetServiceComponent().Version(); - } - var splits = rawVersion.Split(' '); - _serverVersion = new Version(splits[splits.Length - 1].Substring(1)); - } - return _serverVersion; - } } - - /// - public string InstanceName { get; private set; } - - /// - /// Backing field for - /// - readonly RemoteLoginInfo _loginInfo; - - /// - public RemoteLoginInfo LoginInfo { get { return _loginInfo; } } - - /// - /// 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 for a remote connection - public ServerInterface(RemoteLoginInfo loginInfo) - { - if (!loginInfo.HasPassword) - throw new InvalidOperationException("password must be set on loginInfo!"); - _loginInfo = loginInfo; - } - - /// - 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 LoginInfo != 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.Close(); - } - catch - { - cf.Abort(); - } - toRemove.Add(I.Key); - } - foreach (var I in toRemove) - ChannelFactoryCache.Remove(I); - } - } - - /// - public bool VersionMismatch(out string errorMessage) - { - if(ServerVersion.Major != Version.Major || ServerVersion.Minor != Version.Minor || ServerVersion.Build != Version.Build) //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.", Version, ServerVersion); - return true; - } - errorMessage = null; - return false; - } - - /// - 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 instance to connect to, if any - /// The correct - ChannelFactory CreateChannel(string instanceName) - { - var accessPath = instanceName == null ? MasterInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName); - if (!IsRemoteConnection) - return CreateLocalChannel(instanceName, accessPath); - return CreateRemoteChannel(instanceName, accessPath); - } - - //NOTE: This needs to be kept seperate from CreateRemoteChannel because not all our client implementations have NetNamedPipeBinding and attempting to call this function on those platforms will throw an exception - - /// - /// Directly creates a for on a local connection without caching. This should be eventually closed by the caller - /// - /// The component of the channel to be created - /// The instance to connect to, if any - /// The URL of the interface to connect to - /// The correct - ChannelFactory CreateLocalChannel(string instanceName, string accessPath) - { - var interfaceName = typeof(T).Name; - 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; - } - - /// - /// Directly creates a for on a remote connection without caching. This should be eventually closed by the caller - /// - /// The component of the channel to be created - /// The instance to connect to, if any - /// The URL of the interface to connect to - /// The correct - ChannelFactory CreateRemoteChannel(string instanceName, string accessPath) - { - //okay we're going over - var binding = new BasicHttpsBinding() - { - SendTimeout = new TimeSpan(0, 0, 40), - MaxReceivedMessageSize = TransferLimitRemote - }; - - var interfaceName = typeof(T).Name; - var requireAuth = interfaceName != typeof(ITGConnectivity).Name; - var url = String.Format("https://{0}:{1}/{2}/{3}", LoginInfo.IP, LoginInfo.Port, accessPath, interfaceName); - var address = new EndpointAddress(url); - var res = new ChannelFactory(binding, address); - if (requireAuth) - { - var applicator = new AuthenticationHeaderApplicator(LoginInfo); - var t = Type.GetType("Mono.Runtime"); - KeyedCollection behaviours; - if (t != null) - { - var prop = res.Endpoint.GetType() - .GetTypeInfo() - .GetDeclaredProperty("Behaviors"); - behaviours = (KeyedCollection)prop - .GetValue(res.Endpoint); - } - else - behaviours = res.Endpoint.EndpointBehaviors; - behaviours.Add(applicator); - } - return res; - } - - /// - public ConnectivityLevel ConnectionStatus() - { - return ConnectionStatus(out string unused); - } - - /// - public ConnectivityLevel ConnectionStatus(out string error) - { - try - { - GetComponentImpl(false).VerifyConnection(); - } - catch (Exception 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/TGS.Interface/TGS.Interface.csproj b/TGS.Interface/TGS.Interface.csproj index a1b6f3d248..42cb6b71b0 100644 --- a/TGS.Interface/TGS.Interface.csproj +++ b/TGS.Interface/TGS.Interface.csproj @@ -62,18 +62,24 @@ + + + + + - + + diff --git a/TGS.Server/Instance/Compiler.cs b/TGS.Server/Instance/Compiler.cs index 87e933ea33..90ae74a4eb 100644 --- a/TGS.Server/Instance/Compiler.cs +++ b/TGS.Server/Instance/Compiler.cs @@ -119,7 +119,7 @@ namespace TGS.Server //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(IServerInterface)).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(IClient)).GetName().Name + ".dll")))) //its a good tell, jim return CompilerStatus.Initialized; return CompilerStatus.Uninitialized; } diff --git a/TGS.Server/Instance/DreamDaemon.cs b/TGS.Server/Instance/DreamDaemon.cs index 805c315d09..9f7d13774f 100644 --- a/TGS.Server/Instance/DreamDaemon.cs +++ b/TGS.Server/Instance/DreamDaemon.cs @@ -535,7 +535,7 @@ namespace TGS.Server return; //Copy the interface dll to the static dir - var InterfacePath = Assembly.GetAssembly(typeof(IServerInterface)).Location; + var InterfacePath = Assembly.GetAssembly(typeof(IClient)).Location; //bridge is installed next to the interface var BridgePath = Path.Combine(Path.GetDirectoryName(InterfacePath), BridgeDLLName); #if DEBUG diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 513e25e20f..4b4cfc7fcb 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -198,9 +198,11 @@ namespace TGS.Server /// void SetupService() { - serviceHost = CreateHost(this, ServerInterface.MasterInterfaceName); - foreach (var I in ServerInterface.ValidServiceInterfaces) - AddEndpoint(serviceHost, I); + serviceHost = CreateHost(this, Definitions.MasterInterfaceName); + AddEndpoint(serviceHost, typeof(ITGConnectivity)); + AddEndpoint(serviceHost, typeof(ITGInstanceManager)); + AddEndpoint(serviceHost, typeof(ITGLanding)); + AddEndpoint(serviceHost, typeof(ITGSService)); serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us serviceHost.Authentication.ServiceAuthenticationManager = new AuthenticationHeaderDecoder(); } @@ -313,11 +315,19 @@ namespace TGS.Server return null; } - var host = CreateHost(instance, String.Format("{0}/{1}", ServerInterface.InstanceInterfaceName, instanceName)); + var host = CreateHost(instance, String.Format("{0}/{1}", Definitions.InstanceInterfaceName, instanceName)); hosts.Add(instanceName, host); - - foreach (var J in ServerInterface.ValidInstanceInterfaces) - AddEndpoint(host, J); + + AddEndpoint(host, typeof(ITGConnectivity)); + AddEndpoint(host, typeof(ITGAdministration)); + AddEndpoint(host, typeof(ITGChat)); + AddEndpoint(host, typeof(ITGCompiler)); + AddEndpoint(host, typeof(ITGConfig)); + AddEndpoint(host, typeof(ITGConnectivity)); + AddEndpoint(host, typeof(ITGDreamDaemon)); + AddEndpoint(host, typeof(ITGInstance)); + AddEndpoint(host, typeof(ITGInterop)); + AddEndpoint(host, typeof(ITGRepository)); host.Authorization.ServiceAuthorizationManager = instance; host.Authentication.ServiceAuthenticationManager = new AuthenticationHeaderDecoder(); @@ -332,11 +342,11 @@ namespace TGS.Server 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); + host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = Definitions.TransferLimitLocal }, bindingName); var httpsBinding = new BasicHttpsBinding() { SendTimeout = new TimeSpan(0, 0, 40), - MaxReceivedMessageSize = ServerInterface.TransferLimitRemote + MaxReceivedMessageSize = Definitions.TransferLimitRemote }; var requireAuth = typetype.Name != typeof(ITGConnectivity).Name; host.AddServiceEndpoint(typetype, httpsBinding, bindingName); diff --git a/TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs b/TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs index 04d6bc1343..4735b8ccd5 100644 --- a/TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs +++ b/TGS.Tests/CommandLine/Commands/Repository/RepositoryCommandTest.cs @@ -8,14 +8,14 @@ namespace TGS.CommandLine.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 IServerInterface MockInterfaceToRepo(ITGRepository repo) + /// The the resulting should return + /// A mock + protected IInstance MockInterfaceToRepo(ITGRepository repo) { - var mock = new Mock(); - mock.Setup(foo => foo.GetComponent()).Returns(repo); + var mock = new Mock(); + mock.Setup(foo => foo.Repository).Returns(repo); return mock.Object; } } diff --git a/TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs b/TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs index 54df717166..a5f2b72ede 100644 --- a/TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs +++ b/TGS.Tests/CommandLine/Commands/Repository/TestRepoSetPushTestmergeCommitsCommand.cs @@ -21,7 +21,7 @@ namespace TGS.CommandLine.Commands.Repository.Tests var ran = false; var repo = new Mock(); repo.Setup(foo => foo.SetPushTestmergeCommits(true)).Callback(() => { ran = true; }); - ConsoleCommand.Interface = MockInterfaceToRepo(repo.Object); + ConsoleCommand.Instance = MockInterfaceToRepo(repo.Object); Assert.AreEqual(new RepoSetPushTestmergeCommitsCommand().DoRun(new List { "on" }), Command.ExitCode.Normal); Assert.IsTrue(ran); } @@ -36,7 +36,7 @@ namespace TGS.CommandLine.Commands.Repository.Tests var ran = false; var repo = new Mock(); repo.Setup(foo => foo.SetPushTestmergeCommits(false)).Callback(() => { ran = true; }); - ConsoleCommand.Interface = MockInterfaceToRepo(repo.Object); + ConsoleCommand.Instance = MockInterfaceToRepo(repo.Object); Assert.AreEqual(new RepoSetPushTestmergeCommitsCommand().DoRun(new List { "off" }), Command.ExitCode.Normal); Assert.IsTrue(ran); } diff --git a/TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs b/TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs index 3efebced20..f1aea5ce1d 100644 --- a/TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs +++ b/TGS.Tests/CommandLine/Commands/Repository/TestRepoStatusCommand.cs @@ -32,13 +32,13 @@ namespace TGS.CommandLine.Commands.Repository.Tests var ran = false; var mock = GetDefaultMock(); mock.Setup(foo => foo.PushTestmergeCommits()).Returns(false).Callback(() => ran = true); - ConsoleCommand.Interface = MockInterfaceToRepo(mock.Object); + ConsoleCommand.Instance = MockInterfaceToRepo(mock.Object); Assert.AreEqual(new RepoStatusCommand().DoRun(new List { }), Command.ExitCode.Normal); Assert.IsTrue(ran); ran = false; mock.Setup(foo => foo.PushTestmergeCommits()).Returns(true).Callback(() => ran = true); - ConsoleCommand.Interface = MockInterfaceToRepo(mock.Object); + ConsoleCommand.Instance = MockInterfaceToRepo(mock.Object); Assert.AreEqual(new RepoStatusCommand().DoRun(new List { }), Command.ExitCode.Normal); Assert.IsTrue(ran); } diff --git a/TGS.Tests/ControlPanel/TestInstanceSelector.cs b/TGS.Tests/ControlPanel/TestInstanceSelector.cs index 913d89017d..2d65a3b1db 100644 --- a/TGS.Tests/ControlPanel/TestInstanceSelector.cs +++ b/TGS.Tests/ControlPanel/TestInstanceSelector.cs @@ -20,8 +20,7 @@ namespace TGS.ControlPanel.Tests { var mockLanding = new Mock(); mockLanding.Setup(x => x.ListInstances()).Returns(new List()); - var mockInter = new Mock(); - mockInter.Setup(x => x.GetComponent()).Returns(mockLanding.Object); + var mockInter = new Mock(); new InstanceSelector(mockInter.Object).Dispose(); } diff --git a/TGS.Tests/ServiceInterface/TestInterface.cs b/TGS.Tests/ServiceInterface/TestInterface.cs index 5afeaadc6e..1b51fa2b50 100644 --- a/TGS.Tests/ServiceInterface/TestInterface.cs +++ b/TGS.Tests/ServiceInterface/TestInterface.cs @@ -27,7 +27,7 @@ namespace TGS.Interface.Tests Assert.IsFalse(String.IsNullOrWhiteSpace(message)); return true; }; - ServerInterface.SetBadCertificateHandler(func); + Client.SetBadCertificateHandler(func); } /// @@ -37,7 +37,7 @@ namespace TGS.Interface.Tests public void TestBadCertificateHandler() { var ran = false; - ServerInterface.SetBadCertificateHandler(_ => + Client.SetBadCertificateHandler(_ => { ran = true; return true; @@ -50,9 +50,9 @@ namespace TGS.Interface.Tests /// Creates a remote configured pointing at an invalid address /// /// The created - ServerInterface CreateFakeRemoteInterface() + Client CreateFakeRemoteInterface() { - return new ServerInterface(new RemoteLoginInfo("some.fake.url.420", 34752, "user", "password")); + return new Client(new RemoteLoginInfo("some.fake.url.420", 34752, "user", "password")); } /// @@ -61,7 +61,7 @@ namespace TGS.Interface.Tests [TestMethod] public void TestLocalInstantiation() { - Assert.IsFalse(new ServerInterface().IsRemoteConnection); + Assert.IsFalse(new Client().IsRemoteConnection); } /// @@ -77,7 +77,7 @@ namespace TGS.Interface.Tests public void TestCopyRemoteInterface() { var first = CreateFakeRemoteInterface(); - var second = new ServerInterface(first.LoginInfo); + var second = new Client(first.LoginInfo); Assert.AreEqual(first.LoginInfo.IP, second.LoginInfo.IP); Assert.AreEqual(first.LoginInfo.Port, second.LoginInfo.Port); Assert.AreEqual(first.LoginInfo.Username, second.LoginInfo.Username); @@ -88,7 +88,7 @@ namespace TGS.Interface.Tests [TestMethod] public void TestLocalAccessInterfaceAllowsWindowsImpersonation() { - var inter = new ServerInterface(); + var inter = new Client(); var po = new PrivateObject(inter); var cf = (ChannelFactory)po.Invoke("CreateChannel", new Type[] { typeof(string) }, new object[] { TestInstanceName }, new Type[] { typeof(ITGConfig) }); Assert.AreEqual(cf.Credentials.Windows.AllowedImpersonationLevel, System.Security.Principal.TokenImpersonationLevel.Impersonation);