mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-29 08:00:19 +01:00
Merge pull request #449 from Cyberboss/InterfaceRestructure
Interface Restructure
This commit is contained in:
@@ -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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGAdministration>().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<string> parameters)
|
||||
{
|
||||
var group = Interface.GetComponent<ITGAdministration>().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<string> parameters)
|
||||
{
|
||||
var result = Interface.GetComponent<ITGAdministration>().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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGAdministration>().SetAuthorizedGroup(null);
|
||||
var res = Instance.Administration.SetAuthorizedGroup(null);
|
||||
if(res != "ADMIN")
|
||||
{
|
||||
OutputProc("Failed to clear the group??? We are currently set to: " + res);
|
||||
|
||||
@@ -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<ITGByond>().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<string> parameters)
|
||||
{
|
||||
switch (Interface.GetComponent<ITGByond>().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<ITGByond>();
|
||||
var BYOND = Instance.Byond;
|
||||
if (!BYOND.UpdateToVersion(Major, Minor))
|
||||
|
||||
{
|
||||
|
||||
@@ -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<string> parameters)
|
||||
{
|
||||
var Chat = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
var IRC = Instance.Chat;
|
||||
var info = IRC.ProviderInfos()[providerIndex];
|
||||
List<string> channels;
|
||||
|
||||
@@ -156,7 +155,7 @@ namespace TGS.CommandLine
|
||||
}
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
var IRC = Instance.Chat;
|
||||
var info = IRC.ProviderInfos()[providerIndex];
|
||||
List<string> channels;
|
||||
|
||||
@@ -222,7 +221,7 @@ namespace TGS.CommandLine
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var info = Interface.GetComponent<ITGChat>().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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGChat>().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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var IRC = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var Chat = Interface.GetComponent<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var Chat = Interface.GetComponent<ITGChat>();
|
||||
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<ITGChat>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var Chat = Interface.GetComponent<ITGChat>();
|
||||
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;
|
||||
|
||||
@@ -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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGConfig>().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<string> parameters)
|
||||
{
|
||||
var list = Interface.GetComponent<ITGConfig>().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<string> parameters)
|
||||
{
|
||||
OutputProc(Interface.GetComponent<ITGInstance>().ServerDirectory());
|
||||
OutputProc(Instance.ServerDirectory());
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
|
||||
@@ -108,7 +107,7 @@ namespace TGS.CommandLine
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var bytes = Interface.GetComponent<ITGConfig>().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<ITGConfig>().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);
|
||||
|
||||
@@ -5,8 +5,12 @@ namespace TGS.CommandLine
|
||||
abstract class ConsoleCommand : Command
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IServerInterface"/> currently in use by the <see cref="Program"/>
|
||||
/// The <see cref="IServer"/> currently in use by the <see cref="Program"/>
|
||||
/// </summary>
|
||||
public static IServerInterface Interface;
|
||||
public static IServer Server;
|
||||
/// <summary>
|
||||
/// The <see cref="IInstance"/> currently in use by the <see cref="Program"/>
|
||||
/// </summary>
|
||||
public static IInstance Instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGDreamDaemon>().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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGDreamDaemon>().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<string> parameters)
|
||||
{
|
||||
var DD = Interface.GetComponent<ITGDreamDaemon>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var DD = Interface.GetComponent<ITGDreamDaemon>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var DD = Interface.GetComponent<ITGDreamDaemon>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var DD = Interface.GetComponent<ITGDreamDaemon>();
|
||||
var DD = Instance.DreamDaemon;
|
||||
switch (parameters[0].ToLower())
|
||||
{
|
||||
case "on":
|
||||
@@ -205,7 +204,7 @@ namespace TGS.CommandLine
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var DD = Interface.GetComponent<ITGDreamDaemon>();
|
||||
var DD = Instance.DreamDaemon;
|
||||
switch (parameters[0].ToLower())
|
||||
{
|
||||
case "on":
|
||||
@@ -255,7 +254,7 @@ namespace TGS.CommandLine
|
||||
return ExitCode.BadCommand;
|
||||
}
|
||||
|
||||
Interface.GetComponent<ITGDreamDaemon>().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<ITGDreamDaemon>().SetSecurityLevel(sec);
|
||||
Instance.DreamDaemon.SetSecurityLevel(sec);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<string> parameters)
|
||||
{
|
||||
var DM = Interface.GetComponent<ITGCompiler>();
|
||||
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<ITGByond>().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<ITGCompiler>().CompileError();
|
||||
var error = Instance.Compiler.CompileError();
|
||||
if (error != null)
|
||||
OutputProc("Last error: " + error);
|
||||
}
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var DM = Interface.GetComponent<ITGCompiler>();
|
||||
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<string> parameters)
|
||||
{
|
||||
Interface.GetComponent<ITGCompiler>().SetProjectName(parameters[0]);
|
||||
Instance.Compiler.SetProjectName(parameters[0]);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +165,7 @@ namespace TGS.CommandLine
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var DM = Interface.GetComponent<ITGCompiler>();
|
||||
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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGCompiler>().Cancel();
|
||||
var res = Instance.Compiler.Cancel();
|
||||
OutputProc(res ?? "Success!");
|
||||
return ExitCode.Normal; //because failing cancellation implys it's already cancelled
|
||||
}
|
||||
|
||||
@@ -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<string> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
-22
@@ -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<string> 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<ITGLanding>().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
|
||||
/// </summary>
|
||||
/// <param name="instanceName">The name of the <see cref="ITGInstance"/> to test</param>
|
||||
/// <param name="silentSuccess">If <see langword="true"/>, does not output on success</param>
|
||||
/// <returns><see langword="true"/> if a <see cref="ConnectivityLevel.Authenticated"/> was achieved with <see cref="IServerInterface.ConnectToInstance(string, bool)"/>, <see langword="false"/> otherwise</returns>
|
||||
/// <returns><see langword="true"/> if the connection was made, <see langword="false"/> otherwise</returns>
|
||||
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<ITGSService>().PrepareForUpdate();
|
||||
currentInterface.Server.Management.PrepareForUpdate();
|
||||
return (int)Command.ExitCode.Normal;
|
||||
default:
|
||||
//linq voodoo to get quoted strings
|
||||
|
||||
@@ -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<ITGRepository>().SetPushTestmergeCommits(true);
|
||||
Instance.Repository.SetPushTestmergeCommits(true);
|
||||
break;
|
||||
case "off":
|
||||
Interface.GetComponent<ITGRepository>().SetPushTestmergeCommits(false);
|
||||
Instance.Repository.SetPushTestmergeCommits(false);
|
||||
break;
|
||||
default:
|
||||
OutputProc("Invalid option!");
|
||||
@@ -67,7 +66,7 @@ namespace TGS.CommandLine
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGRepository>().UpdateTGS3Json();
|
||||
var res = Instance.Repository.UpdateTGS3Json();
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -86,7 +85,7 @@ namespace TGS.CommandLine
|
||||
}
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
var Repo = Interface.GetComponent<ITGRepository>();
|
||||
var Repo = Instance.Repository;
|
||||
var busy = Repo.OperationInProgress();
|
||||
if (!busy)
|
||||
{
|
||||
@@ -167,7 +166,7 @@ namespace TGS.CommandLine
|
||||
}
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var result = Interface.GetComponent<ITGRepository>().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<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
var result = Interface.GetComponent<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
var result = Interface.GetComponent<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
Interface.GetComponent<ITGRepository>().SetCommitterEmail(parameters[0]);
|
||||
Instance.Repository.SetCommitterEmail(parameters[0]);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
|
||||
@@ -286,7 +285,7 @@ namespace TGS.CommandLine
|
||||
}
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
Interface.GetComponent<ITGRepository>().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<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
var data = Interface.GetComponent<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
var data = Interface.GetComponent<ITGRepository>().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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGRepository>().Checkout(parameters[0]);
|
||||
var res = Instance.Repository.Checkout(parameters[0]);
|
||||
OutputProc(res ?? "Success");
|
||||
return res == null ? ExitCode.Normal : ExitCode.ServerError;
|
||||
}
|
||||
|
||||
@@ -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<Command> { 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<string> parameters)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGRepository>().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<ITGRepository>().SetAutoUpdateInterval(NewInterval);
|
||||
Instance.Repository.SetAutoUpdateInterval(NewInterval);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
|
||||
@@ -91,7 +90,7 @@ namespace TGS.CommandLine
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var gen_cl = parameters.Count > 1 && parameters[1].ToLower() == "--cl";
|
||||
var Repo = Interface.GetComponent<ITGRepository>();
|
||||
var Repo = Instance.Repository;
|
||||
switch (parameters[0].ToLower())
|
||||
{
|
||||
case "hard":
|
||||
@@ -126,7 +125,7 @@ namespace TGS.CommandLine
|
||||
OutputProc(res);
|
||||
}
|
||||
}
|
||||
var resu = Interface.GetComponent<ITGCompiler>().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<ITGRepository>();
|
||||
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<ITGCompiler>().Compile(true);
|
||||
var resu = Instance.Compiler.Compile(true);
|
||||
OutputProc(resu ? "Compilation started!" : "Compilation could not be started!");
|
||||
return resu ? ExitCode.Normal : ExitCode.ServerError;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().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
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
foreach (var I in Interface.GetServiceComponent<ITGLanding>().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
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().DetachInstance(parameters[0]);
|
||||
var res = Server.InstanceManager.DetachInstance(parameters[0]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -161,7 +161,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().ImportInstance(parameters[0]);
|
||||
var res = Server.InstanceManager.ImportInstance(parameters[0]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -193,7 +193,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGSService>().PythonPath();
|
||||
var res = Server.Management.PythonPath();
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -232,7 +232,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
Interface.GetServiceComponent<ITGSService>().SetPythonPath(parameters[0]);
|
||||
Server.Management.SetPythonPath(parameters[0]);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
@@ -266,7 +266,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().SetInstanceEnabled(parameters[0], true);
|
||||
var res = Server.InstanceManager.SetInstanceEnabled(parameters[0], true);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -305,7 +305,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().SetInstanceEnabled(parameters[0], false);
|
||||
var res = Server.InstanceManager.SetInstanceEnabled(parameters[0], false);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -316,7 +316,7 @@ namespace TGS.CommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGS.Interface.Components.ITGSService.RemoteAccessPort"/>
|
||||
/// Command for calling <see cref="ITGSService.RemoteAccessPort"/>
|
||||
/// </summary>
|
||||
class ServiceRemoteAccessPortCommand : ConsoleCommand
|
||||
{
|
||||
@@ -337,7 +337,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
OutputProc(Interface.GetServiceComponent<ITGSService>().RemoteAccessPort().ToString());
|
||||
OutputProc(Server.Management.RemoteAccessPort().ToString());
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ namespace TGS.CommandLine
|
||||
return ExitCode.BadCommand;
|
||||
}
|
||||
|
||||
var res = Interface.GetServiceComponent<ITGSService>().SetRemoteAccessPort(port);
|
||||
var res = Server.Management.SetRemoteAccessPort(port);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -422,7 +422,7 @@ namespace TGS.CommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().RenameInstance(parameters[0], parameters[1]);
|
||||
var res = Server.InstanceManager.RenameInstance(parameters[0], parameters[1]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
<Compile Include="DDCommands.cs" />
|
||||
<Compile Include="DMCommands.cs" />
|
||||
<Compile Include="ChatCommands.cs" />
|
||||
<Compile Include="InstanceRootCommand.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RepoCommands.cs" />
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace TGS.ControlPanel
|
||||
string lastReadError = null;
|
||||
void InitBYONDPage()
|
||||
{
|
||||
var BYOND = Interface.GetComponent<ITGByond>();
|
||||
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<ITGByond>().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<ITGByond>();
|
||||
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<ITGByond>().GetError();
|
||||
var error = Instance.Byond.GetError();
|
||||
if (error != lastReadError)
|
||||
{
|
||||
lastReadError = error;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace TGS.ControlPanel
|
||||
void LoadChatPage()
|
||||
{
|
||||
updatingChat = true;
|
||||
var Chat = Interface.GetComponent<ITGChat>();
|
||||
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<ITGChat>().Reconnect(ModifyingProvider);
|
||||
Instance.Chat.Reconnect(ModifyingProvider);
|
||||
LoadChatPage();
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace TGS.ControlPanel
|
||||
}
|
||||
void SetAdminsAreSpecial(bool value)
|
||||
{
|
||||
var Chat = Interface.GetComponent<ITGChat>();
|
||||
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<ITGChat>().SetProviderInfo(wip);
|
||||
res = Instance.Chat.SetProviderInfo(wip);
|
||||
}
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
|
||||
@@ -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<string, ControlPanel> InstancesInUse { get; private set; } = new Dictionary<string, ControlPanel>();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IServerInterface"/> instance for this <see cref="ControlPanel"/>
|
||||
/// The <see cref="IInstance"/> for this <see cref="ControlPanel"/>
|
||||
/// </summary>
|
||||
readonly IServerInterface Interface;
|
||||
readonly IInstance Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="ControlPanel"/>
|
||||
/// </summary>
|
||||
/// <param name="I">The <see cref="IServerInterface"/> for the <see cref="ControlPanel"/></param>
|
||||
public ControlPanel(IServerInterface I)
|
||||
/// <param name="server">The <see cref="IServer"/> to use</param>
|
||||
/// <param name="instance">The <see cref="IInstance"/> to use</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -50,7 +54,7 @@ namespace TGS.ControlPanel
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
void ControlPanel_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
InstancesInUse.Remove(Interface.InstanceName);
|
||||
InstancesInUse.Remove(Instance.Metadata.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -58,8 +62,7 @@ namespace TGS.ControlPanel
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace TGS.ControlPanel
|
||||
if (RepoBusyCheck())
|
||||
return;
|
||||
|
||||
var Repo = Interface.GetComponent<ITGRepository>();
|
||||
var Repo = Instance.Repository;
|
||||
|
||||
RepoProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
RepoProgressBar.Visible = false;
|
||||
@@ -148,7 +148,7 @@ namespace TGS.ControlPanel
|
||||
|
||||
bool RepoBusyCheck()
|
||||
{
|
||||
if (Interface.GetComponent<ITGRepository>().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<ITGRepository>();
|
||||
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<ITGRepository>();
|
||||
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<ITGRepository>().UpdateTGS3Json();
|
||||
var res = Instance.Repository.UpdateTGS3Json();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace TGS.ControlPanel
|
||||
|
||||
private void CompileCancelButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var res = Interface.GetComponent<ITGCompiler>().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<ITGRepository>().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<ITGCompiler>();
|
||||
var DD = Interface.GetComponent<ITGDreamDaemon>();
|
||||
var Config = Interface.GetComponent<ITGConfig>();
|
||||
var Repo = Interface.GetComponent<ITGRepository>();
|
||||
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<ITGInstance>().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<ITGCompiler>().SetProjectName(projectNameText.Text);
|
||||
Instance.Compiler.SetProjectName(projectNameText.Text);
|
||||
}
|
||||
|
||||
private void PortSelector_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Interface.GetComponent<ITGDreamDaemon>().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<ITGCompiler>().Initialize())
|
||||
if (!Instance.Compiler.Initialize())
|
||||
MessageBox.Show("Unable to start initialization!");
|
||||
LoadServerPage();
|
||||
}
|
||||
private void CompileButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Interface.GetComponent<ITGCompiler>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().RequestRestart();
|
||||
Instance.DreamDaemon.RequestRestart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -293,7 +293,7 @@ namespace TGS.ControlPanel
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
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<ITGRepository>();
|
||||
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<ITGCompiler>().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<ITGRepository>();
|
||||
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<ITGCompiler>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().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<ITGDreamDaemon>().SetWebclient(WebclientCheckBox.Checked);
|
||||
Instance.DreamDaemon.SetWebclient(WebclientCheckBox.Checked);
|
||||
}
|
||||
|
||||
private void AutoUpdateInterval_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Interface.GetComponent<ITGRepository>().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<ITGRepository>().SetAutoUpdateInterval(0);
|
||||
Instance.Repository.SetAutoUpdateInterval(0);
|
||||
else
|
||||
Interface.GetComponent<ITGRepository>().SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value);
|
||||
Instance.Repository.SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ITGConfig>(), 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<ITGConfig>().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<ITGConfig>().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<ITGConfig>().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<ITGConfig>();
|
||||
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<ITGConfig>().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<ITGConfig>().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<ITGAdministration>().RecreateStaticFolder();
|
||||
var res = Instance.Administration.RecreateStaticFolder();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
BuildFileList();
|
||||
|
||||
-1
@@ -15,7 +15,6 @@
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
Cleanup();
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Form used for managing <see cref="ITGSService"/> <see cref="ITGInstance"/> manipulation functions
|
||||
/// Form used for managing <see cref="IInstance"/>s
|
||||
/// </summary>
|
||||
sealed partial class InstanceSelector : CountedForm
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IServerInterface"/> we build instance connections from
|
||||
/// The <see cref="IServer"/> we build instance connections from
|
||||
/// </summary>
|
||||
readonly IServerInterface masterInterface;
|
||||
/// <summary>
|
||||
/// List of <see cref="InstanceMetadata"/> from <see cref="masterInterface"/>
|
||||
/// </summary>
|
||||
IList<InstanceMetadata> InstanceData;
|
||||
readonly IServer server;
|
||||
/// <summary>
|
||||
/// Used for modifying <see cref="EnabledCheckBox"/> without invoking its side effects
|
||||
/// </summary>
|
||||
@@ -28,17 +23,17 @@ namespace TGS.ControlPanel
|
||||
/// <summary>
|
||||
/// Construct an <see cref="InstanceSelector"/>
|
||||
/// </summary>
|
||||
/// <param name="I">An <see cref="IServerInterface"/> connected a the <see cref="ITGSService"/></param>
|
||||
public InstanceSelector(IServerInterface I)
|
||||
/// <param name="_server">The value of <see cref="server"/></param>
|
||||
public InstanceSelector(IServer _server)
|
||||
{
|
||||
InitializeComponent();
|
||||
InstanceListBox.MouseDoubleClick += InstanceListBox_MouseDoubleClick;
|
||||
masterInterface = I;
|
||||
server = _server;
|
||||
RefreshInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connects to a <see cref="ITGInstance"/> if it is double clicked in <see cref="InstanceListBox"/>
|
||||
/// Connects to a <see cref="IInstance"/> if it is double clicked in <see cref="InstanceListBox"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="MouseEventArgs"/></param>
|
||||
@@ -53,36 +48,25 @@ namespace TGS.ControlPanel
|
||||
/// <returns>The <see cref="InstanceMetadata"/> associated with <see cref="InstanceListBox"/>'s current selected index if it exists, <see langword="null"/> otherwise</returns>
|
||||
InstanceMetadata GetSelectedInstanceMetadata()
|
||||
{
|
||||
var index = InstanceListBox.SelectedIndex;
|
||||
return index != ListBox.NoMatches ? InstanceData[index] : null;
|
||||
var index = (IInstance)InstanceListBox.SelectedItem;
|
||||
return index?.Metadata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by <see cref="Dispose(bool)"/>
|
||||
/// Loads the <see cref="InstanceListBox"/> using <see cref="Interface.Components.ITGLanding.ListInstances"/>
|
||||
/// </summary>
|
||||
void Cleanup()
|
||||
{
|
||||
masterInterface.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the <see cref="InstanceListBox"/> using <see cref="ITGLanding.ListInstances"/>
|
||||
/// </summary>
|
||||
async void RefreshInstances()
|
||||
void RefreshInstances()
|
||||
{
|
||||
InstanceListBox.Items.Clear();
|
||||
await WrapServerOp(() => {
|
||||
InstanceData = masterInterface.GetServiceComponent<ITGLanding>().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 <see cref="ControlPanel"/> for a given <see cref="InstanceListBox"/> <paramref name="index"/>
|
||||
/// </summary>
|
||||
/// <param name="index">The <see cref="ListBox.SelectedIndex"/> of <see cref="InstanceListBox"/> to connect to</param>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.DetachInstance(string)"/>
|
||||
/// Prompts the user for parameters to <see cref="Interface.Components.ITGInstanceManager.DetachInstance(string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -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<ITGInstanceManager>().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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.RenameInstance(string, string)"/>
|
||||
/// Prompts the user for parameters to <see cref="Interface.Components.ITGInstanceManager.RenameInstance(string, string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -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<ITGInstanceManager>().RenameInstance(imd.Name, new_name));
|
||||
await WrapServerOp(() => res = server.InstanceManager.RenameInstance(imd.Name, new_name));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
RefreshInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.ImportInstance(string)"/>
|
||||
/// Prompts the user for parameters to <see cref="Interface.Components.ITGInstanceManager.ImportInstance(string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -184,14 +150,14 @@ namespace TGS.ControlPanel
|
||||
if (instance_path == null)
|
||||
return;
|
||||
string res = null;
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().ImportInstance(instance_path));
|
||||
await WrapServerOp(() => res = server.InstanceManager.ImportInstance(instance_path));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
RefreshInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.CreateInstance(string, string)"/>
|
||||
/// Prompts the user for parameters to <see cref="Interface.Components.ITGInstanceManager.CreateInstance(string, string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -204,14 +170,14 @@ namespace TGS.ControlPanel
|
||||
if (instance_path == null)
|
||||
return;
|
||||
string res = null;
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().CreateInstance(instance_name, instance_path));
|
||||
await WrapServerOp(() => res = server.InstanceManager.CreateInstance(instance_name, instance_path));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
RefreshInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to connect the user to an <see cref="ITGInstance"/> based on the <see cref="ListBox.SelectedIndex"/> of <see cref="InstanceListBox"/>
|
||||
/// Attempts to connect the user to an <see cref="IInstance"/> based on the <see cref="ListBox.SelectedIndex"/> of <see cref="InstanceListBox"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -221,7 +187,7 @@ namespace TGS.ControlPanel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user if they want to call <see cref="ITGInstanceManager.SetInstanceEnabled(string, bool)"/> to either online or offline an <see cref="ITGInstance"/> based on its current state
|
||||
/// Prompts the user if they want to call <see cref="Interface.Components.ITGInstanceManager.SetInstanceEnabled(string, bool)"/> to either online or offline an <see cref="IInstance"/> based on its current state
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -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<ITGInstanceManager>().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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update <see cref="EnabledCheckBox"/> based on the selected <see cref="ITGInstance"/>'s <see cref="InstanceMetadata.Enabled"/> property
|
||||
/// Update <see cref="EnabledCheckBox"/> based on the selected <see cref="IInstance"/>'s <see cref="InstanceMetadata.Enabled"/> property
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-22
@@ -5,7 +5,7 @@ using TGS.Interface;
|
||||
|
||||
namespace TGS.ControlPanel
|
||||
{
|
||||
sealed partial class Login : CountedForm
|
||||
sealed partial class Login : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently selected saved <see cref="RemoteLoginInfo"/>
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts a connection on a given <see cref="IServerInterface"/>
|
||||
/// Attempts a connection on a given <see cref="IClient"/>
|
||||
/// </summary>
|
||||
/// <param name="I">The <see cref="IServerInterface"/> to attempt a connection on</param>
|
||||
/// <param name="I">The <see cref="IClient"/> to attempt a connection on</param>
|
||||
/// <returns><see langword="true"/> if the connection was made and authenticated, <see langword="false"/> otherwise</returns>
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Windows.Forms;
|
||||
namespace TGS.ControlPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to provide an ATP function for calls into an <see cref="TGS.Interface.IServerInterface"/>
|
||||
/// Used to provide an ATP function for calls into an <see cref="TGS.Interface.IClient"/>
|
||||
/// </summary>
|
||||
#if !DEBUG
|
||||
abstract
|
||||
@@ -13,9 +13,9 @@ namespace TGS.ControlPanel
|
||||
class ServerOpForm : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to wrap <see cref="TGS.Interface.IServerInterface"/> calls in a non-blocking fashion while disabling the <see cref="Form"/> and enabling the wait cursor
|
||||
/// Used to wrap <see cref="TGS.Interface.IClient"/> calls in a non-blocking fashion while disabling the <see cref="Form"/> and enabling the wait cursor
|
||||
/// </summary>
|
||||
/// <param name="action">The <see cref="TGS.Interface.IServerInterface"/> operation to wrap</param>
|
||||
/// <param name="action">The <see cref="TGS.Interface.IClient"/> operation to wrap</param>
|
||||
/// <returns>A <see cref="Task"/> wrapping <paramref name="action"/></returns>
|
||||
protected Task WrapServerOp(Action action)
|
||||
{
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace TGS.ControlPanel
|
||||
const string MergedPullsError = "Error retrieving currently merged pull requests: {0}";
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IServerInterface"/> connected to an <see cref="ITGInstance"/> to handle the pull requests for
|
||||
/// The <see cref="IInstance"/>to handle pull requests for
|
||||
/// </summary>
|
||||
readonly IServerInterface currentInterface;
|
||||
readonly IInstance currentInterface;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="GitHubClient"/> to use to read PR lists
|
||||
@@ -38,9 +38,9 @@ namespace TGS.ControlPanel
|
||||
/// <summary>
|
||||
/// Construct a <see cref="TestMergeManager"/>
|
||||
/// </summary>
|
||||
/// <param name="interfaceToUse">The <see cref="IServerInterface"/> to use for managing the <see cref="ITGInstance"/></param>
|
||||
/// <param name="interfaceToUse">The <see cref="IInstance"/> to manage pull requests for</param>
|
||||
/// <param name="clientToUse">The <see cref="GitHubClient"/> to use for getting pull request information</param>
|
||||
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<ITGRepository>();
|
||||
var repo = currentInterface.Repository;
|
||||
string error = null;
|
||||
List<PullRequestInfo> pulls = null;
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace TGS.ControlPanel
|
||||
void PullRequestManager_Load(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
var repo = currentInterface.GetComponent<ITGRepository>();
|
||||
var repo = currentInterface.Repository;
|
||||
if(!Program.GetRepositoryRemote(repo, out repoOwner, out repoName))
|
||||
{
|
||||
Close();
|
||||
@@ -256,7 +256,7 @@ namespace TGS.ControlPanel
|
||||
}
|
||||
}
|
||||
|
||||
var repo = currentInterface.GetComponent<ITGRepository>();
|
||||
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<ITGCompiler>().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<PullRequestInfo> pulls = null;
|
||||
string error = null;
|
||||
var mergedPullsTask = WrapServerOp(() => pulls = currentInterface.GetComponent<ITGRepository>().MergedPullRequests(out error));
|
||||
var mergedPullsTask = WrapServerOp(() => pulls = currentInterface.Repository.MergedPullRequests(out error));
|
||||
|
||||
int PRNumber;
|
||||
try
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace TGS.Installer.UI
|
||||
/// </summary>
|
||||
bool attemptNetSettingsMigration = false;
|
||||
|
||||
IServerInterface Interface;
|
||||
IClient Interface;
|
||||
|
||||
/// <summary>
|
||||
/// 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<ITGSService>().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<ITGSService>().PythonPath();
|
||||
sc.PythonPath = Interface.Server.Management.PythonPath();
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
sc.RemoteAccessPort = Interface.GetServiceComponent<ITGSService>().RemoteAccessPort();
|
||||
sc.RemoteAccessPort = Interface.Server.Management.RemoteAccessPort();
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
foreach (var I in Interface.GetServiceComponent<ITGLanding>().ListInstances())
|
||||
sc.InstancePaths.Add(I.Path);
|
||||
foreach (var I in Interface.Server.Instances)
|
||||
sc.InstancePaths.Add(I.Metadata.Path);
|
||||
}
|
||||
catch { }
|
||||
|
||||
|
||||
@@ -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<ITGInterop>().InteropMessage(String.Join(" ", parsedArgs));
|
||||
using (var I = new Client())
|
||||
I.Server.GetInstance(instance).Interop.InteropMessage(String.Join(" ", parsedArgs));
|
||||
}
|
||||
catch { }
|
||||
return 0;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed public class Client : IClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Version of the <see cref="Client"/>
|
||||
/// </summary>
|
||||
public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IServer Server => server;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Version ServerVersion { get
|
||||
{
|
||||
lock (this)
|
||||
if (_serverVersion == null)
|
||||
{
|
||||
string rawVersion;
|
||||
//check ITGSService first for compatiblity reasons
|
||||
try
|
||||
{
|
||||
rawVersion = GetComponent<ITGSService>(null).Version();
|
||||
}
|
||||
catch
|
||||
{
|
||||
rawVersion = GetComponent<ITGLanding>(null).Version();
|
||||
}
|
||||
var splits = rawVersion.Split(' ');
|
||||
_serverVersion = new Version(splits[splits.Length - 1].Substring(1));
|
||||
}
|
||||
return _serverVersion;
|
||||
} }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string InstanceName { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public RemoteLoginInfo LoginInfo { get { return _loginInfo; } }
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="Server"/>
|
||||
/// </summary>
|
||||
readonly IServer server;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="LoginInfo"/>
|
||||
/// </summary>
|
||||
readonly RemoteLoginInfo _loginInfo;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ServerVersion"/>
|
||||
/// </summary>
|
||||
Version _serverVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Associated list of open <see cref="ChannelFactory"/>s keyed by <see langword="interface"/> type name. A <see cref="ChannelFactory"/> in this list may close or fault at any time. <see langword="this"/> must be locked before being accessed
|
||||
/// </summary>
|
||||
IDictionary<string, ChannelFactory> ChannelFactoryCache;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the function called when a remote login fails due to the server having an invalid SSL cert
|
||||
/// </summary>
|
||||
/// <param name="handler">The <see cref="Func{T, TResult}"/> to be called when a remote login is attempted while the server posesses a bad certificate. Passed a <see cref="string"/> of error information about the and should return <see langword="true"/> if it the connection should be made anyway</param>
|
||||
public static void SetBadCertificateHandler(Func<string, bool> 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);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="Client"/> for a local connection
|
||||
/// </summary>
|
||||
public Client()
|
||||
{
|
||||
ChannelFactoryCache = new Dictionary<string, ChannelFactory>();
|
||||
server = new Server(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="Client"/> for a remote connection
|
||||
/// </summary>
|
||||
/// <param name="loginInfo">The <see cref="RemoteLoginInfo"/> for a remote connection</param>
|
||||
public Client(RemoteLoginInfo loginInfo) : this()
|
||||
{
|
||||
if (!loginInfo.HasPassword)
|
||||
throw new InvalidOperationException("password must be set on loginInfo!");
|
||||
_loginInfo = loginInfo;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsRemoteConnection { get { return LoginInfo != null; } }
|
||||
|
||||
/// <summary>
|
||||
/// Closes all <see cref="ChannelFactory"/>s stored in <see cref="ChannelFactoryCache"/> and <see langword="nulls"/> it
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the requested <see cref="Client"/> component <see langword="interface"/> for the instance <see cref="InstanceName"/>. This does not guarantee a successful connection. <see cref="ChannelFactory{TChannel}"/>s created this way are recycled for minimum latency and bandwidth usage
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> to retrieve</typeparam>
|
||||
/// <param name="instanceName">The name of the <see cref="IInstance"/> to use</param>
|
||||
/// <returns>The correct component <see langword="interface"/></returns>
|
||||
internal T GetComponent<T>(string instanceName)
|
||||
{
|
||||
var actualToT = typeof(T);
|
||||
var tot = actualToT.Name;
|
||||
if (instanceName != null)
|
||||
tot = instanceName + tot;
|
||||
ChannelFactory<T> cf;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
if (ChannelFactoryCache == null)
|
||||
throw new ObjectDisposedException(GetType().Name);
|
||||
if (ChannelFactoryCache.ContainsKey(tot))
|
||||
try
|
||||
{
|
||||
cf = ((ChannelFactory<T>)ChannelFactoryCache[tot]);
|
||||
if (cf.State != CommunicationState.Opened)
|
||||
throw new Exception();
|
||||
return cf.CreateChannel();
|
||||
}
|
||||
catch
|
||||
{
|
||||
ChannelFactoryCache[tot].Abort();
|
||||
ChannelFactoryCache.Remove(tot);
|
||||
}
|
||||
cf = CreateChannel<T>(instanceName);
|
||||
ChannelFactoryCache[tot] = cf;
|
||||
}
|
||||
return cf.CreateChannel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directly creates a <see cref="ChannelFactory{TChannel}"/> for <typeparamref name="T"/> without caching. This should be eventually closed by the caller
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <param name="instanceName">The instance to connect to, if any</param>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
ChannelFactory<T> CreateChannel<T>(string instanceName)
|
||||
{
|
||||
var accessPath = instanceName == null ? Definitions.MasterInterfaceName : String.Format("{0}/{1}", Definitions.InstanceInterfaceName, instanceName);
|
||||
if (!IsRemoteConnection)
|
||||
return CreateLocalChannel<T>(instanceName, accessPath);
|
||||
return CreateRemoteChannel<T>(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
|
||||
|
||||
/// <summary>
|
||||
/// Directly creates a <see cref="ChannelFactory{TChannel}"/> for on a local connection <typeparamref name="T"/> without caching. This should be eventually closed by the caller
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <param name="instanceName">The instance to connect to, if any</param>
|
||||
/// <param name="accessPath">The URL of the interface to connect to</param>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
ChannelFactory<T> CreateLocalChannel<T>(string instanceName, string accessPath)
|
||||
{
|
||||
var interfaceName = typeof(T).Name;
|
||||
var res2 = new ChannelFactory<T>(
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directly creates a <see cref="ChannelFactory{TChannel}"/> for on a remote connection <typeparamref name="T"/> without caching. This should be eventually closed by the caller
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <param name="instanceName">The instance to connect to, if any</param>
|
||||
/// <param name="accessPath">The URL of the interface to connect to</param>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
ChannelFactory<T> CreateRemoteChannel<T>(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<T>(binding, address);
|
||||
if (requireAuth)
|
||||
{
|
||||
var applicator = new AuthenticationHeaderApplicator(LoginInfo);
|
||||
var t = Type.GetType("Mono.Runtime");
|
||||
KeyedCollection<Type, IEndpointBehavior> behaviours;
|
||||
if (t != null)
|
||||
{
|
||||
var prop = res.Endpoint.GetType()
|
||||
.GetTypeInfo()
|
||||
.GetDeclaredProperty("Behaviors");
|
||||
behaviours = (KeyedCollection<Type, IEndpointBehavior>)prop
|
||||
.GetValue(res.Endpoint);
|
||||
}
|
||||
else
|
||||
behaviours = res.Endpoint.EndpointBehaviors;
|
||||
behaviours.Add(applicator);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConnectivityLevel ConnectionStatus()
|
||||
{
|
||||
return ConnectionStatus(out string unused);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConnectivityLevel ConnectionStatus(out string error)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetComponent<ITGConnectivity>(null).VerifyConnection();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.None;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GetComponent<ITGLanding>(null).Version();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.Connected;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GetComponent<ITGSService>(null).Version();
|
||||
error = null;
|
||||
return ConnectivityLevel.Administrator;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.Authenticated;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using TGS.Interface.Components;
|
||||
|
||||
namespace TGS.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains constants for the interface
|
||||
/// </summary>
|
||||
public static class Definitions
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum message size to and from a local server
|
||||
/// </summary>
|
||||
public const long TransferLimitLocal = Int32.MaxValue; //2GB can't go higher
|
||||
|
||||
/// <summary>
|
||||
/// The maximum message size to and from a remote server
|
||||
/// </summary>
|
||||
public const long TransferLimitRemote = 10485760; //10 MB
|
||||
|
||||
/// <summary>
|
||||
/// Base name of communication URLs
|
||||
/// </summary>
|
||||
public const string MasterInterfaceName = "TGStationServerService";
|
||||
/// <summary>
|
||||
/// Base name of instance URLs
|
||||
/// </summary>
|
||||
public const string InstanceInterfaceName = MasterInterfaceName + "/Instance";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace TGS.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Main <see langword="interface"/> for communicating the <see cref="Components.ITGSService"/>
|
||||
/// </summary>
|
||||
public interface IClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IServer"/> the <see cref="IClient"/> connects to
|
||||
/// </summary>
|
||||
IServer Server { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RemoteLoginInfo"/> for the <see cref="IClient"/>. Is <see langword="null"/> for local connections
|
||||
/// </summary>
|
||||
RemoteLoginInfo LoginInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="IClient"/> is setup for a remote connection
|
||||
/// </summary>
|
||||
bool IsRemoteConnection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the <see cref="IClient"/> interface being used to connect to a service does not have the same release version as the service
|
||||
/// </summary>
|
||||
/// <param name="errorMessage">An error message to display to the user should this function return <see langword="true"/></param>
|
||||
/// <returns><see langword="true"/> if the <see cref="IClient"/> interface being used to connect to a service does not have the same release version as the service</returns>
|
||||
bool VersionMismatch(out string errorMessage);
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="ConnectionStatus(out string)"/> without the error argument
|
||||
/// </summary>
|
||||
ConnectivityLevel ConnectionStatus();
|
||||
|
||||
/// <summary>
|
||||
/// Used to test if the <see cref="Components.ITGSService"/> 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
|
||||
/// </summary>
|
||||
/// <param name="error">String of the error that prevented an elevated connectivity level</param>
|
||||
/// <returns>The apporopriate <see cref="ConnectivityLevel"/></returns>
|
||||
ConnectivityLevel ConnectionStatus(out string error);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using TGS.Interface.Components;
|
||||
|
||||
namespace TGS.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for <see cref="ITGInstance"/> components
|
||||
/// </summary>
|
||||
public interface IInstance : ITGInstance
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the <see cref="InstanceMetadata"/> for the <see cref="IInstance"/>
|
||||
/// </summary>
|
||||
InstanceMetadata Metadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGAdministration"/> component. Will be <see langword="null"/> if the connected user is not an administrator of the <see cref="IInstance"/>
|
||||
/// </summary>
|
||||
ITGAdministration Administration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGByond"/> component
|
||||
/// </summary>
|
||||
ITGByond Byond { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGChat"/> component
|
||||
/// </summary>
|
||||
ITGChat Chat { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGCompiler"/> component
|
||||
/// </summary>
|
||||
ITGCompiler Compiler { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGConfig"/> component
|
||||
/// </summary>
|
||||
ITGConfig Config { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGDreamDaemon"/> component
|
||||
/// </summary>
|
||||
ITGDreamDaemon DreamDaemon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGInterop"/> component
|
||||
/// </summary>
|
||||
ITGInterop Interop { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGRepository"/> component
|
||||
/// </summary>
|
||||
ITGRepository Repository { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TGS.Interface.Components;
|
||||
|
||||
namespace TGS.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper representing a <see cref="ITGSService"/>
|
||||
/// </summary>
|
||||
public interface IServer
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="System.Version"/> of the <see cref="IServer"/>
|
||||
/// </summary>
|
||||
Version Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="IInstance"/>s the <see cref="IServer"/> contains that the current user can access and connect to
|
||||
/// </summary>
|
||||
IEnumerable<IInstance> Instances { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGInstanceManager"/> component. Will be <see langword="null"/> if the connected user is not an administrator of the <see cref="IServer"/>
|
||||
/// </summary>
|
||||
ITGInstanceManager InstanceManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ITGSService"/> component. Will be <see langword="null"/> if the connected user is not an administrator of the <see cref="IServer"/>
|
||||
/// </summary>
|
||||
ITGSService Management { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified <see cref="IInstance"/> without connectivity checks
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the <see cref="IInstance"/> to get</param>
|
||||
/// <returns>The <see cref="IInstance"/> named <paramref name="name"/> on success, <see langword="null"/> on failure</returns>
|
||||
IInstance GetInstance(string name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using TGS.Interface.Components;
|
||||
|
||||
namespace TGS.Interface
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class Instance : IInstance
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public InstanceMetadata Metadata
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!metadata.Enabled)
|
||||
//metadata needs populating
|
||||
metadata = serverInterface.GetComponent<ITGLanding>(null).ListInstances().Where(x => x.Name == metadata.Name).First();
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the current user is known to be an administrator of the <see cref="IInstance"/>
|
||||
/// </summary>
|
||||
bool UserIsAdministrator
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (isAdministrator)
|
||||
return true;
|
||||
try
|
||||
{
|
||||
serverInterface.GetComponent<ITGAdministration>(metadata.Name).GetCurrentAuthorizedGroup();
|
||||
isAdministrator = true;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="Client"/>
|
||||
/// </summary>
|
||||
readonly Client serverInterface;
|
||||
/// <summary>
|
||||
/// The name of the <see cref="IInstance"/>
|
||||
/// </summary>
|
||||
InstanceMetadata metadata;
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="UserIsAdministrator"/>
|
||||
/// </summary>
|
||||
bool isAdministrator;
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="Instance"/>
|
||||
/// </summary>
|
||||
/// <param name="_serverInterface">The <see cref="Client"/> to use</param>
|
||||
/// <param name="_metadata">The <see cref="InstanceMetadata"/> for the <see cref="IInstance"/></param>
|
||||
public Instance(Client _serverInterface, InstanceMetadata _metadata)
|
||||
{
|
||||
serverInterface = _serverInterface;
|
||||
metadata = _metadata;
|
||||
if (metadata.Enabled)
|
||||
//run a connectivity check
|
||||
serverInterface.GetComponent<ITGConnectivity>(metadata.Name).VerifyConnection();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGAdministration Administration => UserIsAdministrator ? serverInterface.GetComponent<ITGAdministration>(metadata.Name) : null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGByond Byond => serverInterface.GetComponent<ITGByond>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGChat Chat => serverInterface.GetComponent<ITGChat>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGCompiler Compiler => serverInterface.GetComponent<ITGCompiler>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGConfig Config => serverInterface.GetComponent<ITGConfig>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGDreamDaemon DreamDaemon => serverInterface.GetComponent<ITGDreamDaemon>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGInterop Interop => serverInterface.GetComponent<ITGInterop>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGRepository Repository => serverInterface.GetComponent<ITGRepository>(metadata.Name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ServerDirectory()
|
||||
{
|
||||
return serverInterface.GetComponent<ITGInstance>(metadata.Name).ServerDirectory();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Version()
|
||||
{
|
||||
return serverInterface.GetComponent<ITGInstance>(metadata.Name).Version();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the <see cref="Instance"/>
|
||||
/// </summary>
|
||||
/// <returns>A string representation of the <see cref="Instance"/></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0}: {1} - {2} - {3}", metadata.LoggingID, metadata.Name, metadata.Path, metadata.Enabled ? "ONLINE" : "OFFLINE");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TGS.Interface.Components;
|
||||
|
||||
namespace TGS.Interface
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class Server : IServer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Version Version => serverInterface.ServerVersion;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IInstance> Instances { get
|
||||
{
|
||||
lock (this)
|
||||
if (knownInstances == null)
|
||||
knownInstances = serverInterface.GetComponent<ITGLanding>(null).ListInstances();
|
||||
foreach (var I in knownInstances)
|
||||
{
|
||||
IInstance nextInstance;
|
||||
try
|
||||
{
|
||||
nextInstance = new Instance(serverInterface, I);
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
yield return nextInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGInstanceManager InstanceManager => UserIsAdministrator ? serverInterface.GetComponent<ITGInstanceManager>(null) : null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGSService Management => UserIsAdministrator ? serverInterface.GetComponent<ITGSService>(null) : null;
|
||||
|
||||
/// <summary>
|
||||
/// If the connected user is an administrator of the <see cref="IServer"/>
|
||||
/// </summary>
|
||||
bool UserIsAdministrator
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (isAdministrator)
|
||||
return true;
|
||||
try
|
||||
{
|
||||
serverInterface.GetComponent<ITGSService>(null).Version();
|
||||
isAdministrator = true;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The backing <see cref="Client"/>
|
||||
/// </summary>
|
||||
readonly Client serverInterface;
|
||||
|
||||
/// <summary>
|
||||
/// Result of a call to <see cref="ITGLanding.ListInstances"/>
|
||||
/// </summary>
|
||||
IList<InstanceMetadata> knownInstances;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="UserIsAdministrator"/>
|
||||
/// </summary>
|
||||
bool isAdministrator;
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="Server"/>
|
||||
/// </summary>
|
||||
/// <param name="_serverInterface">The <see cref="Client"/> to use</param>
|
||||
public Server(Client _serverInterface)
|
||||
{
|
||||
serverInterface = _serverInterface;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IInstance GetInstance(string name)
|
||||
{
|
||||
return new Instance(serverInterface, new InstanceMetadata { Name = name, Enabled = false });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Main <see langword="interface"/> for communicating the <see cref="ITGSService"/>
|
||||
/// </summary>
|
||||
public interface IServerInterface : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="Version"/> of the connected <see cref="ITGSService"/>
|
||||
/// </summary>
|
||||
Version ServerVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the current instance in use. Defaults to <see langword="null"/>
|
||||
/// </summary>
|
||||
string InstanceName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RemoteLoginInfo"/> for the <see cref="IServerInterface"/>. Is <see langword="null"/> for local connections
|
||||
/// </summary>
|
||||
RemoteLoginInfo LoginInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="IServerInterface"/> is setup for a remote connection
|
||||
/// </summary>
|
||||
bool IsRemoteConnection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Targets <paramref name="instanceName"/> as the instance to use with <see cref="GetComponent{T}"/>. Closes all connections to any previous instance
|
||||
/// </summary>
|
||||
/// <param name="instanceName">The name of the instance to connect to</param>
|
||||
/// <param name="skipChecks">If set to <see langword="true"/>, skips the connectivity and authentication checks, sets <see cref="InstanceName"/>, and returns <see cref="ConnectivityLevel.Connected"/></param>
|
||||
/// <returns>The apporopriate <see cref="ConnectivityLevel"/></returns>
|
||||
ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false);
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the <see cref="IServerInterface"/> interface being used to connect to a service does not have the same release version as the service
|
||||
/// </summary>
|
||||
/// <param name="errorMessage">An error message to display to the user should this function return <see langword="true"/></param>
|
||||
/// <returns><see langword="true"/> if the <see cref="IServerInterface"/> interface being used to connect to a service does not have the same release version as the service</returns>
|
||||
bool VersionMismatch(out string errorMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the requested <see cref="IServerInterface"/> component <see langword="interface"/> for the instance <see cref="InstanceName"/>. This does not guarantee a successful connection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> to retrieve</typeparam>
|
||||
/// <returns>The correct component <see langword="interface"/></returns>
|
||||
T GetComponent<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a root service component
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="ITGSService"/> component for the service</returns>
|
||||
T GetServiceComponent<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Used to test if the <see cref="ITGSService"/> 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
|
||||
/// </summary>
|
||||
/// <returns><see langword="null"/> on successful connection, error message <see cref="string"/> on failure</returns>
|
||||
ConnectivityLevel ConnectionStatus();
|
||||
|
||||
/// <summary>
|
||||
/// Used to test if the <see cref="ITGSService"/> 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
|
||||
/// </summary>
|
||||
/// <param name="error">String of the error that prevented an elevated connectivity level</param>
|
||||
/// <returns>The apporopriate <see cref="ConnectivityLevel"/></returns>
|
||||
ConnectivityLevel ConnectionStatus(out string error);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
sealed public class ServerInterface : IServerInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// List of <see langword="interface"/>s that can be used with <see cref="GetServiceComponent{T}"/>
|
||||
/// </summary>
|
||||
public static readonly IList<Type> ValidServiceInterfaces = new List<Type> { typeof(ITGSService), typeof(ITGInstanceManager), typeof(ITGConnectivity), typeof(ITGLanding) };
|
||||
|
||||
/// <summary>
|
||||
/// Version of the interface
|
||||
/// </summary>
|
||||
public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
|
||||
/// <summary>
|
||||
/// List of <see langword="interface"/>s that can be used with <see cref="GetComponent{T}"/>
|
||||
/// </summary>
|
||||
public static readonly IList<Type> ValidInstanceInterfaces = CollectComponents();
|
||||
|
||||
/// <summary>
|
||||
/// The maximum message size to and from a local server
|
||||
/// </summary>
|
||||
public const long TransferLimitLocal = Int32.MaxValue; //2GB can't go higher
|
||||
|
||||
/// <summary>
|
||||
/// The maximum message size to and from a remote server
|
||||
/// </summary>
|
||||
public const long TransferLimitRemote = 10485760; //10 MB
|
||||
|
||||
/// <summary>
|
||||
/// Base name of communication URLs
|
||||
/// </summary>
|
||||
public const string MasterInterfaceName = "TGStationServerService";
|
||||
/// <summary>
|
||||
/// Base name of instance URLs
|
||||
/// </summary>
|
||||
public const string InstanceInterfaceName = MasterInterfaceName + "/Instance";
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ServerVersion"/>
|
||||
/// </summary>
|
||||
Version _serverVersion;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Version ServerVersion { get
|
||||
{
|
||||
lock (this)
|
||||
if (_serverVersion == null)
|
||||
{
|
||||
string rawVersion;
|
||||
//check ITGSService first for compatiblity reasons
|
||||
try
|
||||
{
|
||||
rawVersion = GetServiceComponent<ITGSService>().Version();
|
||||
}
|
||||
catch
|
||||
{
|
||||
rawVersion = GetServiceComponent<ITGLanding>().Version();
|
||||
}
|
||||
var splits = rawVersion.Split(' ');
|
||||
_serverVersion = new Version(splits[splits.Length - 1].Substring(1));
|
||||
}
|
||||
return _serverVersion;
|
||||
} }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string InstanceName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="LoginInfo"/>
|
||||
/// </summary>
|
||||
readonly RemoteLoginInfo _loginInfo;
|
||||
|
||||
/// <inheritdoc />
|
||||
public RemoteLoginInfo LoginInfo { get { return _loginInfo; } }
|
||||
|
||||
/// <summary>
|
||||
/// Associated list of open <see cref="ChannelFactory"/>s keyed by <see langword="interface"/> type name. A <see cref="ChannelFactory"/> in this list may close or fault at any time. Must be locked before being accessed
|
||||
/// </summary>
|
||||
IDictionary<string, ChannelFactory> ChannelFactoryCache = new Dictionary<string, ChannelFactory>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="IList{T}"/> of <see langword="interface"/> <see cref="Type"/>s that can be used with the service
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="IList{T}"/> of <see langword="interface"/> <see cref="Type"/>s that can be used with the service</returns>
|
||||
static IList<Type> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the function called when a remote login fails due to the server having an invalid SSL cert
|
||||
/// </summary>
|
||||
/// <param name="handler">The <see cref="Func{T, TResult}"/> to be called when a remote login is attempted while the server posesses a bad certificate. Passed a <see cref="string"/> of error information about the and should return <see langword="true"/> if it the connection should be made anyway</param>
|
||||
public static void SetBadCertificateHandler(Func<string, bool> 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);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="ServerInterface"/> for a local connection
|
||||
/// </summary>
|
||||
public ServerInterface() { }
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="ServerInterface"/> for a remote connection
|
||||
/// </summary>
|
||||
/// <param name="loginInfo">The <see cref="RemoteLoginInfo"/> for a remote connection</param>
|
||||
public ServerInterface(RemoteLoginInfo loginInfo)
|
||||
{
|
||||
if (!loginInfo.HasPassword)
|
||||
throw new InvalidOperationException("password must be set on loginInfo!");
|
||||
_loginInfo = loginInfo;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<ITGConnectivity>().VerifyConnection();
|
||||
}
|
||||
catch
|
||||
{
|
||||
InstanceName = prevInstance;
|
||||
return ConnectivityLevel.None;
|
||||
}
|
||||
try
|
||||
{
|
||||
GetComponent<ITGInstance>().ServerDirectory();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return ConnectivityLevel.Connected;
|
||||
}
|
||||
try
|
||||
{
|
||||
GetComponent<ITGAdministration>().GetCurrentAuthorizedGroup();
|
||||
return ConnectivityLevel.Administrator;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return ConnectivityLevel.Authenticated;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsRemoteConnection { get { return LoginInfo != null; } }
|
||||
|
||||
/// <summary>
|
||||
/// Closes all <see cref="ChannelFactory"/>s stored in <see cref="ChannelFactoryCache"/> and clears it
|
||||
/// </summary>
|
||||
/// <param name="includingRoot">If set to <see langword="false"/>, doesn't clear the channels that are used by <see cref="ITGSService"/></param>
|
||||
void CloseAllChannels(bool includingRoot)
|
||||
{
|
||||
string[] RootThings = { typeof(ITGSService).Name, 'S' + typeof(ITGConnectivity).Name };
|
||||
lock (ChannelFactoryCache)
|
||||
{
|
||||
var toRemove = new List<string>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T GetComponent<T>()
|
||||
{
|
||||
var ToT = typeof(T);
|
||||
if (!ValidInstanceInterfaces.Contains(ToT))
|
||||
throw new Exception("Invalid type!");
|
||||
return GetComponentImpl<T>(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the requested <see cref="ServerInterface"/> component <see langword="interface"/> for the instance <see cref="InstanceName"/>. This does not guarantee a successful connection. <see cref="ChannelFactory{TChannel}"/>s created this way are recycled for minimum latency and bandwidth usage
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> to retrieve</typeparam>
|
||||
/// <param name="useInstanceName">If <see cref="InstanceName"/> should be used to connect</param>
|
||||
/// <returns>The correct component <see langword="interface"/></returns>
|
||||
T GetComponentImpl<T>(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<T> cf;
|
||||
|
||||
lock (ChannelFactoryCache)
|
||||
{
|
||||
if (ChannelFactoryCache.ContainsKey(tot))
|
||||
try
|
||||
{
|
||||
cf = ((ChannelFactory<T>)ChannelFactoryCache[tot]);
|
||||
if (cf.State != CommunicationState.Opened)
|
||||
throw new Exception();
|
||||
return cf.CreateChannel();
|
||||
}
|
||||
catch
|
||||
{
|
||||
ChannelFactoryCache[tot].Abort();
|
||||
ChannelFactoryCache.Remove(tot);
|
||||
}
|
||||
cf = CreateChannel<T>(useInstanceName ? InstanceName : null);
|
||||
ChannelFactoryCache[tot] = cf;
|
||||
}
|
||||
return cf.CreateChannel();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T GetServiceComponent<T>()
|
||||
{
|
||||
var ToT = typeof(T);
|
||||
if (!ValidServiceInterfaces.Contains(ToT))
|
||||
throw new Exception("Invalid type!");
|
||||
return GetComponentImpl<T>(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directly creates a <see cref="ChannelFactory{TChannel}"/> for <typeparamref name="T"/> without caching. This should be eventually closed by the caller
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <param name="instanceName">The instance to connect to, if any</param>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
ChannelFactory<T> CreateChannel<T>(string instanceName)
|
||||
{
|
||||
var accessPath = instanceName == null ? MasterInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName);
|
||||
if (!IsRemoteConnection)
|
||||
return CreateLocalChannel<T>(instanceName, accessPath);
|
||||
return CreateRemoteChannel<T>(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
|
||||
|
||||
/// <summary>
|
||||
/// Directly creates a <see cref="ChannelFactory{TChannel}"/> for on a local connection <typeparamref name="T"/> without caching. This should be eventually closed by the caller
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <param name="instanceName">The instance to connect to, if any</param>
|
||||
/// <param name="accessPath">The URL of the interface to connect to</param>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
ChannelFactory<T> CreateLocalChannel<T>(string instanceName, string accessPath)
|
||||
{
|
||||
var interfaceName = typeof(T).Name;
|
||||
var res2 = new ChannelFactory<T>(
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directly creates a <see cref="ChannelFactory{TChannel}"/> for on a remote connection <typeparamref name="T"/> without caching. This should be eventually closed by the caller
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <param name="instanceName">The instance to connect to, if any</param>
|
||||
/// <param name="accessPath">The URL of the interface to connect to</param>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
ChannelFactory<T> CreateRemoteChannel<T>(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<T>(binding, address);
|
||||
if (requireAuth)
|
||||
{
|
||||
var applicator = new AuthenticationHeaderApplicator(LoginInfo);
|
||||
var t = Type.GetType("Mono.Runtime");
|
||||
KeyedCollection<Type, IEndpointBehavior> behaviours;
|
||||
if (t != null)
|
||||
{
|
||||
var prop = res.Endpoint.GetType()
|
||||
.GetTypeInfo()
|
||||
.GetDeclaredProperty("Behaviors");
|
||||
behaviours = (KeyedCollection<Type, IEndpointBehavior>)prop
|
||||
.GetValue(res.Endpoint);
|
||||
}
|
||||
else
|
||||
behaviours = res.Endpoint.EndpointBehaviors;
|
||||
behaviours.Add(applicator);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConnectivityLevel ConnectionStatus()
|
||||
{
|
||||
return ConnectionStatus(out string unused);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConnectivityLevel ConnectionStatus(out string error)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetComponentImpl<ITGConnectivity>(false).VerifyConnection();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.None;
|
||||
}
|
||||
try
|
||||
{
|
||||
GetServiceComponent<ITGLanding>().Version();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.Connected;
|
||||
}
|
||||
try
|
||||
{
|
||||
GetServiceComponent<ITGSService>().Version();
|
||||
error = null;
|
||||
return ConnectivityLevel.Administrator;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.Authenticated;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
/// <summary>
|
||||
/// To detect redundant <see cref="Dispose(bool)"/> calls
|
||||
/// </summary>
|
||||
private bool disposedValue = false;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IDisposable"/> pattern. Calls <see cref="CloseAllChannels"/>
|
||||
/// </summary>
|
||||
/// <param name="disposing"><see langword="true"/> if <see cref="Dispose()"/> was called manually, <see langword="false"/> if it was from the finalizer</param>
|
||||
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);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IDisposable"/> pattern
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -62,18 +62,24 @@
|
||||
<Compile Include="Components\Instance.cs" />
|
||||
<Compile Include="Components\InstanceManager.cs" />
|
||||
<Compile Include="Components\Landing.cs" />
|
||||
<Compile Include="Definitions.cs" />
|
||||
<Compile Include="Enumerations.cs" />
|
||||
<Compile Include="Helpers.cs" />
|
||||
<Compile Include="IInstance.cs" />
|
||||
<Compile Include="InstanceMetadata.cs" />
|
||||
<Compile Include="Instance.cs" />
|
||||
<Compile Include="IServer.cs" />
|
||||
<Compile Include="IClient.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Components\Repository.cs" />
|
||||
<Compile Include="PullRequestInfo.cs" />
|
||||
<Compile Include="RemoteLoginInfo.cs" />
|
||||
<Compile Include="RootCommand.cs" />
|
||||
<Compile Include="ServerInterface.cs" />
|
||||
<Compile Include="Client.cs" />
|
||||
<Compile Include="..\AssemblyInfo.global.cs" />
|
||||
<Compile Include="Components\Service.cs" />
|
||||
<Compile Include="Components\Interop.cs" />
|
||||
<Compile Include="Server.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="tgs.ico" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+19
-9
@@ -198,9 +198,11 @@ namespace TGS.Server
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
@@ -8,14 +8,14 @@ namespace TGS.CommandLine.Commands.Repository.Tests
|
||||
public abstract class RepositoryCommandTest : OutputProcOverriderTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a mock <see cref="IServerInterface"/> that returns a specific <see cref="ITGRepository"/> when that component is requested
|
||||
/// Creates a mock <see cref="IClient"/> that returns a specific <see cref="ITGRepository"/> when that component is requested
|
||||
/// </summary>
|
||||
/// <param name="repo">The <see cref="ITGRepository"/> the resulting <see cref="IServerInterface.GetComponent{T}"/> should return</param>
|
||||
/// <returns>A mock <see cref="IServerInterface"/></returns>
|
||||
protected IServerInterface MockInterfaceToRepo(ITGRepository repo)
|
||||
/// <param name="repo">The <see cref="ITGRepository"/> the resulting <see cref="IClient.GetComponent{T}"/> should return</param>
|
||||
/// <returns>A mock <see cref="IClient"/></returns>
|
||||
protected IInstance MockInterfaceToRepo(ITGRepository repo)
|
||||
{
|
||||
var mock = new Mock<IServerInterface>();
|
||||
mock.Setup(foo => foo.GetComponent<ITGRepository>()).Returns(repo);
|
||||
var mock = new Mock<IInstance>();
|
||||
mock.Setup(foo => foo.Repository).Returns(repo);
|
||||
return mock.Object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace TGS.CommandLine.Commands.Repository.Tests
|
||||
var ran = false;
|
||||
var repo = new Mock<ITGRepository>();
|
||||
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<string> { "on" }), Command.ExitCode.Normal);
|
||||
Assert.IsTrue(ran);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ namespace TGS.CommandLine.Commands.Repository.Tests
|
||||
var ran = false;
|
||||
var repo = new Mock<ITGRepository>();
|
||||
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<string> { "off" }), Command.ExitCode.Normal);
|
||||
Assert.IsTrue(ran);
|
||||
}
|
||||
|
||||
@@ -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<string> { }), 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<string> { }), Command.ExitCode.Normal);
|
||||
Assert.IsTrue(ran);
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ namespace TGS.ControlPanel.Tests
|
||||
{
|
||||
var mockLanding = new Mock<ITGLanding>();
|
||||
mockLanding.Setup(x => x.ListInstances()).Returns(new List<InstanceMetadata>());
|
||||
var mockInter = new Mock<IServerInterface>();
|
||||
mockInter.Setup(x => x.GetComponent<ITGLanding>()).Returns(mockLanding.Object);
|
||||
var mockInter = new Mock<IServer>();
|
||||
|
||||
new InstanceSelector(mockInter.Object).Dispose();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace TGS.Interface.Tests
|
||||
Assert.IsFalse(String.IsNullOrWhiteSpace(message));
|
||||
return true;
|
||||
};
|
||||
ServerInterface.SetBadCertificateHandler(func);
|
||||
Client.SetBadCertificateHandler(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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 <see cref="Interface"/> pointing at an invalid address
|
||||
/// </summary>
|
||||
/// <returns>The created <see cref="Interface"/></returns>
|
||||
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"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -61,7 +61,7 @@ namespace TGS.Interface.Tests
|
||||
[TestMethod]
|
||||
public void TestLocalInstantiation()
|
||||
{
|
||||
Assert.IsFalse(new ServerInterface().IsRemoteConnection);
|
||||
Assert.IsFalse(new Client().IsRemoteConnection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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<ITGConfig>)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);
|
||||
|
||||
Reference in New Issue
Block a user