mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 22:48:20 +01:00
Merge pull request #330 from Cyberboss/Permissions
Fixes required for 3.2
This commit is contained in:
@@ -85,7 +85,7 @@ namespace TGCommandLine
|
||||
}
|
||||
else if (interactive && !saidSrvVersion)
|
||||
{
|
||||
Console.WriteLine("Connectd to service version: " + currentInterface.GetService().Version());
|
||||
Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent<ITGLanding>().Version());
|
||||
saidSrvVersion = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TGServiceInterface;
|
||||
using TGServiceInterface.Components;
|
||||
|
||||
namespace TGCommandLine
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for managing the <see cref="TGServiceInterface.Components.ITGSService"/>
|
||||
/// Used for managing the <see cref="ITGSService"/> components
|
||||
/// </summary>
|
||||
class ServiceCommand : RootCommand
|
||||
{
|
||||
@@ -26,7 +27,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.CreateInstance(string, string)"/>
|
||||
/// Command for calling <see cref="ITGInstanceManager.CreateInstance(string, string)"/>
|
||||
/// </summary>
|
||||
class ServiceCreateInstanceCommand : ConsoleCommand
|
||||
{
|
||||
@@ -54,7 +55,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().CreateInstance(parameters[0], parameters[1]);
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().CreateInstance(parameters[0], parameters[1]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -65,7 +66,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.ListInstances"/>
|
||||
/// Command for calling <see cref="ITGLanding.ListInstances"/>
|
||||
/// </summary>
|
||||
class ServiceListInstancesCommand : ConsoleCommand
|
||||
{
|
||||
@@ -86,14 +87,14 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
foreach (var I in Interface.GetService().ListInstances())
|
||||
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) : ""));
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.DetachInstance(string)"/>
|
||||
/// Command for calling <see cref="ITGInstanceManager.DetachInstance(string)"/>
|
||||
/// </summary>
|
||||
class ServiceDetachInstanceCommand : ConsoleCommand
|
||||
{
|
||||
@@ -121,7 +122,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().DetachInstance(parameters[0]);
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().DetachInstance(parameters[0]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -132,7 +133,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.ImportInstance(string)"/>
|
||||
/// Command for calling <see cref="ITGInstanceManager.ImportInstance(string)"/>
|
||||
/// </summary>
|
||||
class ServiceImportInstanceCommand : ConsoleCommand
|
||||
{
|
||||
@@ -160,7 +161,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().ImportInstance(parameters[0]);
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().ImportInstance(parameters[0]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -171,7 +172,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.PythonPath"/>
|
||||
/// Command for calling <see cref="ITGSService.PythonPath"/>
|
||||
/// </summary>
|
||||
class ServicePythonPathCommand : ConsoleCommand
|
||||
{
|
||||
@@ -192,7 +193,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().PythonPath();
|
||||
var res = Interface.GetServiceComponent<ITGSService>().PythonPath();
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -203,7 +204,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.SetPythonPath(string)"/>
|
||||
/// Command for calling <see cref="ITGSService.SetPythonPath(string)"/>
|
||||
/// </summary>
|
||||
class ServiceSetPythonPathCommand : ConsoleCommand
|
||||
{
|
||||
@@ -231,13 +232,13 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
Interface.GetService().SetPythonPath(parameters[0]);
|
||||
Interface.GetServiceComponent<ITGSService>().SetPythonPath(parameters[0]);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.SetInstanceEnabled(string, bool)"/> with a <see langword="true"/> parameter
|
||||
/// Command for calling <see cref="ITGInstanceManager.SetInstanceEnabled(string, bool)"/> with a <see langword="true"/> parameter
|
||||
/// </summary>
|
||||
class ServiceEnableInstanceCommand : ConsoleCommand
|
||||
{
|
||||
@@ -265,7 +266,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().SetInstanceEnabled(parameters[0], true);
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().SetInstanceEnabled(parameters[0], true);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -276,7 +277,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.SetInstanceEnabled(string, bool)"/> with a <see langword="false"/> parameter
|
||||
/// Command for calling <see cref="ITGInstanceManager.SetInstanceEnabled(string, bool)"/> with a <see langword="false"/> parameter
|
||||
/// </summary>
|
||||
class ServiceDisableInstanceCommand : ConsoleCommand
|
||||
{
|
||||
@@ -304,7 +305,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().SetInstanceEnabled(parameters[0], false);
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().SetInstanceEnabled(parameters[0], false);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -336,7 +337,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
OutputProc(Interface.GetService().RemoteAccessPort().ToString());
|
||||
OutputProc(Interface.GetServiceComponent<ITGSService>().RemoteAccessPort().ToString());
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
@@ -381,7 +382,7 @@ namespace TGCommandLine
|
||||
return ExitCode.BadCommand;
|
||||
}
|
||||
|
||||
var res = Interface.GetService().SetRemoteAccessPort(port);
|
||||
var res = Interface.GetServiceComponent<ITGSService>().SetRemoteAccessPort(port);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
@@ -393,7 +394,7 @@ namespace TGCommandLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command for calling <see cref="TGServiceInterface.Components.ITGSService.RenameInstance(string, string)"/>
|
||||
/// Command for calling <see cref="ITGInstanceManager.RenameInstance(string, string)"/>
|
||||
/// </summary>
|
||||
class ServiceRenameInstanceCommand : ConsoleCommand
|
||||
{
|
||||
@@ -421,7 +422,7 @@ namespace TGCommandLine
|
||||
/// <inheritdoc />
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Interface.GetService().RenameInstance(parameters[0], parameters[1]);
|
||||
var res = Interface.GetServiceComponent<ITGInstanceManager>().RenameInstance(parameters[0], parameters[1]);
|
||||
if (res != null)
|
||||
{
|
||||
OutputProc(res);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace TGControlPanel
|
||||
/// <summary>
|
||||
/// The main <see cref="ControlPanel"/> form
|
||||
/// </summary>
|
||||
partial class ControlPanel : CountedForm
|
||||
sealed partial class ControlPanel : CountedForm
|
||||
{
|
||||
/// <summary>
|
||||
/// List of instances being used by open control panels
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace TGControlPanel
|
||||
/// <summary>
|
||||
/// Calls <see cref="Application.Exit()"/> when all <see cref="CountedForm"/>s are <see cref="Form.Close"/>d
|
||||
/// </summary>
|
||||
class CountedForm : Form
|
||||
abstract class CountedForm : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// The current number of active <see cref="CountedForm"/>s
|
||||
|
||||
+32
-1
@@ -36,6 +36,8 @@
|
||||
this.RenameInstanceButton = new System.Windows.Forms.Button();
|
||||
this.DetachInstanceButton = new System.Windows.Forms.Button();
|
||||
this.RefreshButton = new System.Windows.Forms.Button();
|
||||
this.ConnectButton = new System.Windows.Forms.Button();
|
||||
this.EnabledCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// InstanceListBox
|
||||
@@ -46,6 +48,7 @@
|
||||
this.InstanceListBox.Name = "InstanceListBox";
|
||||
this.InstanceListBox.Size = new System.Drawing.Size(339, 238);
|
||||
this.InstanceListBox.TabIndex = 0;
|
||||
this.InstanceListBox.SelectedIndexChanged += new System.EventHandler(this.InstanceListBox_SelectedIndexChanged);
|
||||
//
|
||||
// CreateInstanceButton
|
||||
//
|
||||
@@ -94,7 +97,7 @@
|
||||
// RefreshButton
|
||||
//
|
||||
this.RefreshButton.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||
this.RefreshButton.Location = new System.Drawing.Point(358, 226);
|
||||
this.RefreshButton.Location = new System.Drawing.Point(358, 195);
|
||||
this.RefreshButton.Name = "RefreshButton";
|
||||
this.RefreshButton.Size = new System.Drawing.Size(148, 25);
|
||||
this.RefreshButton.TabIndex = 19;
|
||||
@@ -102,12 +105,37 @@
|
||||
this.RefreshButton.UseVisualStyleBackColor = true;
|
||||
this.RefreshButton.Click += new System.EventHandler(this.RefreshButton_Click);
|
||||
//
|
||||
// ConnectButton
|
||||
//
|
||||
this.ConnectButton.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||
this.ConnectButton.Location = new System.Drawing.Point(358, 226);
|
||||
this.ConnectButton.Name = "ConnectButton";
|
||||
this.ConnectButton.Size = new System.Drawing.Size(148, 25);
|
||||
this.ConnectButton.TabIndex = 20;
|
||||
this.ConnectButton.Text = "Connect";
|
||||
this.ConnectButton.UseVisualStyleBackColor = true;
|
||||
this.ConnectButton.Click += new System.EventHandler(this.ConnectButton_Click);
|
||||
//
|
||||
// EnabledCheckBox
|
||||
//
|
||||
this.EnabledCheckBox.AutoSize = true;
|
||||
this.EnabledCheckBox.ForeColor = System.Drawing.Color.White;
|
||||
this.EnabledCheckBox.Location = new System.Drawing.Point(396, 149);
|
||||
this.EnabledCheckBox.Name = "EnabledCheckBox";
|
||||
this.EnabledCheckBox.Size = new System.Drawing.Size(65, 17);
|
||||
this.EnabledCheckBox.TabIndex = 21;
|
||||
this.EnabledCheckBox.Text = "Enabled";
|
||||
this.EnabledCheckBox.UseVisualStyleBackColor = true;
|
||||
this.EnabledCheckBox.CheckedChanged += new System.EventHandler(this.EnabledCheckBox_CheckedChanged);
|
||||
//
|
||||
// InstanceSelector
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(40)))), ((int)(((byte)(34)))));
|
||||
this.ClientSize = new System.Drawing.Size(518, 261);
|
||||
this.Controls.Add(this.EnabledCheckBox);
|
||||
this.Controls.Add(this.ConnectButton);
|
||||
this.Controls.Add(this.RefreshButton);
|
||||
this.Controls.Add(this.DetachInstanceButton);
|
||||
this.Controls.Add(this.RenameInstanceButton);
|
||||
@@ -119,6 +147,7 @@
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Server Instances";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@@ -130,5 +159,7 @@
|
||||
private System.Windows.Forms.Button RenameInstanceButton;
|
||||
private System.Windows.Forms.Button DetachInstanceButton;
|
||||
private System.Windows.Forms.Button RefreshButton;
|
||||
private System.Windows.Forms.Button ConnectButton;
|
||||
private System.Windows.Forms.CheckBox EnabledCheckBox;
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,14 @@ using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using TGServiceInterface;
|
||||
using TGServiceInterface.Components;
|
||||
|
||||
namespace TGControlPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Form used for managing <see cref="TGServiceInterface.Components.ITGSService"/> <see cref="TGServiceInterface.Components.ITGInstance"/> manipulation functions
|
||||
/// Form used for managing <see cref="ITGSService"/> <see cref="ITGInstance"/> manipulation functions
|
||||
/// </summary>
|
||||
partial class InstanceSelector : CountedForm
|
||||
sealed partial class InstanceSelector : CountedForm
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IInterface"/> we build instance connections from
|
||||
@@ -19,6 +20,15 @@ namespace TGControlPanel
|
||||
/// List of <see cref="InstanceMetadata"/> from <see cref="masterInterface"/>
|
||||
/// </summary>
|
||||
IList<InstanceMetadata> InstanceData;
|
||||
/// <summary>
|
||||
/// Used for modifying <see cref="EnabledCheckBox"/> without invoking its side effects
|
||||
/// </summary>
|
||||
bool UpdatingEnabledCheckbox = false;
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="InstanceSelector"/>
|
||||
/// </summary>
|
||||
/// <param name="I">An <see cref="IInterface"/> connected a the <see cref="ITGSService"/></param>
|
||||
public InstanceSelector(IInterface I)
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -47,15 +57,13 @@ namespace TGControlPanel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connects to a <see cref="TGServiceInterface.Components.ITGInstance"/> if it is double clicked in <see cref="InstanceListBox"/>
|
||||
/// Connects to a <see cref="ITGInstance"/> 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>
|
||||
void InstanceListBox_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
var index = InstanceListBox.IndexFromPoint(e.Location);
|
||||
if (index != ListBox.NoMatches)
|
||||
TryConnectToInstance(InstanceData[index].Name);
|
||||
TryConnectToIndexInstance(InstanceListBox.IndexFromPoint(e.Location));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,25 +85,36 @@ namespace TGControlPanel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the <see cref="InstanceListBox"/> using <see cref="TGServiceInterface.Components.ITGSService.ListInstances"/>
|
||||
/// Loads the <see cref="InstanceListBox"/> using <see cref="ITGLanding.ListInstances"/>
|
||||
/// </summary>
|
||||
async void RefreshInstances()
|
||||
{
|
||||
InstanceListBox.Items.Clear();
|
||||
await WrapServerOp(() => {
|
||||
InstanceData = masterInterface.GetService().ListInstances();
|
||||
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);
|
||||
CreateInstanceButton.Enabled = HasServerAdmin;
|
||||
ImportInstanceButton.Enabled = HasServerAdmin;
|
||||
RenameInstanceButton.Enabled = HasServerAdmin;
|
||||
DetachInstanceButton.Enabled = HasServerAdmin;
|
||||
EnabledCheckBox.Enabled = HasServerAdmin;
|
||||
if(InstanceData.Count > 0)
|
||||
InstanceListBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to start a <see cref="ControlPanel"/> for a given <paramref name="instanceName"/>
|
||||
/// Tries to start a <see cref="ControlPanel"/> for a given <see cref="InstanceListBox"/> <paramref name="index"/>
|
||||
/// </summary>
|
||||
/// <param name="instanceName">The name of the <see cref="TGServiceInterface.Components.ITGInstance"/> to connect to</param>
|
||||
async void TryConnectToInstance(string instanceName)
|
||||
/// <param name="index">The <see cref="ListBox.SelectedIndex"/> of <see cref="InstanceListBox"/> to connect to</param>
|
||||
async void TryConnectToIndexInstance(int index)
|
||||
{
|
||||
if(ControlPanel.InstancesInUse.TryGetValue(instanceName, out ControlPanel activeCP))
|
||||
if (index == ListBox.NoMatches)
|
||||
return;
|
||||
var instanceName = InstanceData[index].Name;
|
||||
if (ControlPanel.InstancesInUse.TryGetValue(instanceName, out ControlPanel activeCP))
|
||||
{
|
||||
activeCP.BringToFront();
|
||||
return;
|
||||
@@ -123,7 +142,7 @@ namespace TGControlPanel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="TGServiceInterface.Components.ITGSService.DetachInstance(string)"/>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.DetachInstance(string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -135,7 +154,7 @@ namespace TGControlPanel
|
||||
if (MessageBox.Show(String.Format("This will dissociate the server instance at \"{0}\"! Are you sure?", imd.Path), "Instance Detach", MessageBoxButtons.YesNo) != DialogResult.Yes)
|
||||
return;
|
||||
string res = null;
|
||||
await WrapServerOp(() => { res = masterInterface.GetService().DetachInstance(imd.Name); });
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().DetachInstance(imd.Name));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
RefreshInstances();
|
||||
@@ -152,7 +171,7 @@ namespace TGControlPanel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="TGServiceInterface.Components.ITGSService.RenameInstance(string, string)"/>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.RenameInstance(string, string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -167,14 +186,14 @@ namespace TGControlPanel
|
||||
if (imd.Enabled && MessageBox.Show(String.Format("This will temporarily offline the server instance! Are you sure?", imd.Path), "Instance Restart", MessageBoxButtons.YesNo) != DialogResult.Yes)
|
||||
return;
|
||||
string res = null;
|
||||
await WrapServerOp(() => { res = masterInterface.GetService().RenameInstance(imd.Name, new_name); });
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().RenameInstance(imd.Name, new_name));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
RefreshInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="TGServiceInterface.Components.ITGSService.ImportInstance(string)"/>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.ImportInstance(string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -184,14 +203,14 @@ namespace TGControlPanel
|
||||
if (instance_path == null)
|
||||
return;
|
||||
string res = null;
|
||||
await WrapServerOp(() => { res = masterInterface.GetService().ImportInstance(instance_path); });
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().ImportInstance(instance_path));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
RefreshInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prompts the user for parameters to <see cref="TGServiceInterface.Components.ITGSService.CreateInstance(string, string)"/>
|
||||
/// Prompts the user for parameters to <see cref="ITGInstanceManager.CreateInstance(string, string)"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
@@ -204,10 +223,62 @@ namespace TGControlPanel
|
||||
if (instance_path == null)
|
||||
return;
|
||||
string res = null;
|
||||
await WrapServerOp(() => { res = masterInterface.GetService().CreateInstance(instance_name, instance_path); });
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().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"/>
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
void ConnectButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
TryConnectToIndexInstance(InstanceListBox.SelectedIndex);
|
||||
}
|
||||
|
||||
/// <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
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">The <see cref="EventArgs"/></param>
|
||||
async void EnabledCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (UpdatingEnabledCheckbox)
|
||||
return;
|
||||
var enabling = EnabledCheckBox.Checked;
|
||||
try
|
||||
{
|
||||
if (MessageBox.Show(String.Format("Are you sure you want to {0} this instance?", enabling ? "online" : "offline"), "Instance Status Change", MessageBoxButtons.YesNo) != DialogResult.Yes)
|
||||
return;
|
||||
string res = null;
|
||||
var index = InstanceListBox.SelectedIndex;
|
||||
await WrapServerOp(() => res = masterInterface.GetServiceComponent<ITGInstanceManager>().SetInstanceEnabled(InstanceData[index].Name, enabling));
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RefreshInstances();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update <see cref="EnabledCheckBox"/> based on the selected <see cref="ITGInstance"/>'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)
|
||||
{
|
||||
UpdatingEnabledCheckbox = true;
|
||||
EnabledCheckBox.Checked = InstanceData[index].Enabled;
|
||||
UpdatingEnabledCheckbox = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-23
@@ -4,7 +4,7 @@ using TGServiceInterface;
|
||||
|
||||
namespace TGControlPanel
|
||||
{
|
||||
partial class Login : CountedForm
|
||||
sealed partial class Login : CountedForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a <see cref="Login"/> form
|
||||
@@ -73,28 +73,8 @@ namespace TGControlPanel
|
||||
MessageBox.Show("Authentication error: Username/password/windows identity is not authorized! Ensure you are a system administrator or in the correct Windows group on the service machine.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res.HasFlag(ConnectivityLevel.Administrator))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var InstanceToConnectTo = Program.TextPrompt("Select instance", "You do not have permission to list server instances. Please enter the name of the instance to connect to:");
|
||||
if (InstanceToConnectTo == null)
|
||||
return;
|
||||
|
||||
res = I.ConnectToInstance(InstanceToConnectTo);
|
||||
if (!res.HasFlag(ConnectivityLevel.Connected))
|
||||
MessageBox.Show("Unable to connect to instance! Does it exist?");
|
||||
else if (!res.HasFlag(ConnectivityLevel.Authenticated))
|
||||
MessageBox.Show("The current user is not authorized to access this instance!");
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
new ControlPanel(I).Show();
|
||||
}
|
||||
else
|
||||
new InstanceSelector(I).Show();
|
||||
|
||||
new InstanceSelector(I).Show();
|
||||
Close();
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace TGInstallerWrapper
|
||||
var verifiedConnection = Interface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator);
|
||||
try
|
||||
{
|
||||
VersionLabel.Text = Interface.GetService().Version();
|
||||
VersionLabel.Text = Interface.GetServiceComponent<ITGSService>().Version();
|
||||
var isV0 = VersionLabel.Text.Contains("v3.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");
|
||||
@@ -98,7 +98,7 @@ namespace TGInstallerWrapper
|
||||
var connectionVerified = Interface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator);
|
||||
try
|
||||
{
|
||||
Interface.GetService().PrepareForUpdate();
|
||||
Interface.GetServiceComponent<ITGSService>().PrepareForUpdate();
|
||||
Thread.Sleep(3000); //chat messages
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace TGServerService
|
||||
public static IInstanceConfig CreateFromNETSettings()
|
||||
{
|
||||
var Config = Properties.Settings.Default;
|
||||
var result = new DeprecatedInstanceConfig(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3"));
|
||||
var result = new DeprecatedInstanceConfig(Program.NormalizePath(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3")));
|
||||
// using nameof for sanity where possible
|
||||
result.ProjectName = LoadPreviousNetPropertyOrDefault(nameof(ProjectName), result.ProjectName);
|
||||
result.Port = LoadPreviousNetPropertyOrDefault("ServerPort", result.Port);
|
||||
|
||||
@@ -175,5 +175,17 @@ namespace TGServerService
|
||||
{
|
||||
return input.Replace("%", "%25").Replace("=", "%3d").Replace(";", "%3b").Replace("&", "%26").Replace("+", "%2b");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes different versions of a path <see cref="string"/>
|
||||
/// </summary>
|
||||
/// <param name="path">The path to normalize</param>
|
||||
/// <returns>The normalized path</returns>
|
||||
public static string NormalizePath(string path)
|
||||
{
|
||||
return Path.GetFullPath(new Uri(path).LocalPath)
|
||||
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
|
||||
.ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceModel;
|
||||
using TGServiceInterface.Components;
|
||||
@@ -9,21 +11,23 @@ namespace TGServerService
|
||||
/// <summary>
|
||||
/// A <see cref="ServiceAuthorizationManager"/> used to determine only if the caller is an admin
|
||||
/// </summary>
|
||||
sealed class AdministrativeAuthorizationManager : ServiceAuthorizationManager
|
||||
sealed class RootAuthorizationManager : ServiceAuthorizationManager
|
||||
{
|
||||
string LastSeenUser;
|
||||
public static readonly IList<ServiceAuthorizationManager> InstanceAuthManagers = new List<ServiceAuthorizationManager>();
|
||||
protected override bool CheckAccessCore(OperationContext operationContext)
|
||||
{
|
||||
var contract = operationContext.EndpointDispatcher.ContractName;
|
||||
|
||||
if (contract == typeof(ITGConnectivity).Name) //always allow connectivity checks
|
||||
return true;
|
||||
|
||||
|
||||
var windowsIdent = operationContext.ServiceSecurityContext.WindowsIdentity;
|
||||
|
||||
var wp = new WindowsPrincipal(windowsIdent);
|
||||
//first allow admins
|
||||
var authSuccess = wp.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
if(!authSuccess && contract == typeof(ITGLanding).Name)
|
||||
return InstanceAuthManagers.FirstOrDefault(x => x.CheckAccess(operationContext)) != null;
|
||||
|
||||
var user = windowsIdent.Name;
|
||||
if (LastSeenUser != user)
|
||||
@@ -73,6 +73,7 @@ namespace TGServerService
|
||||
/// <returns>The name of the group allowed to access the <see cref="ServerInstance"/> if it could be found, <see langword="null"/> otherwise</returns>
|
||||
string FindTheDroidsWereLookingFor(string search = null, bool useDomain = false)
|
||||
{
|
||||
RootAuthorizationManager.InstanceAuthManagers.Add(this);
|
||||
//find the group that is authorized to use the tools
|
||||
var pc = new PrincipalContext(useDomain ? ContextType.Domain : ContextType.Machine);
|
||||
var groupName = search ?? Config.AuthorizedUserGroupSID;
|
||||
@@ -95,6 +96,14 @@ namespace TGServerService
|
||||
}
|
||||
return gp.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up the <see cref="ITGAdministration"/> component
|
||||
/// </summary>
|
||||
void DisposeAdministration()
|
||||
{
|
||||
RootAuthorizationManager.InstanceAuthManagers.Remove(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by WCF whenever a component call is made. Checks to see that the supplied user account has access to the requested component
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace TGServerService
|
||||
DisposeByond();
|
||||
DisposeRepo();
|
||||
DisposeChat();
|
||||
DisposeAdministration();
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
|
||||
+16
-23
@@ -15,7 +15,7 @@ namespace TGServerService
|
||||
/// The windows service the application runs as
|
||||
/// </summary>
|
||||
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
|
||||
class Service : ServiceBase, ITGSService, ITGConnectivity
|
||||
class Service : ServiceBase, ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager
|
||||
{
|
||||
/// <summary>
|
||||
/// The logging ID used for <see cref="Service"/> events
|
||||
@@ -233,9 +233,9 @@ namespace TGServerService
|
||||
void SetupService()
|
||||
{
|
||||
serviceHost = CreateHost(this, Interface.MasterInterfaceName);
|
||||
AddEndpoint(serviceHost, typeof(ITGSService));
|
||||
AddEndpoint(serviceHost, typeof(ITGConnectivity));
|
||||
serviceHost.Authorization.ServiceAuthorizationManager = new AdministrativeAuthorizationManager(); //only admins can diddle us
|
||||
foreach (var I in Interface.ValidServiceInterfaces)
|
||||
AddEndpoint(serviceHost, I);
|
||||
serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -277,7 +277,7 @@ namespace TGServerService
|
||||
WriteEntry(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID);
|
||||
pathsToRemove.Add(I.Directory);
|
||||
}
|
||||
if (SetupInstance(I) == null)
|
||||
if (I.Enabled && SetupInstance(I) == null)
|
||||
pathsToRemove.Add(I.Directory);
|
||||
else
|
||||
seenNames.Add(I.Name);
|
||||
@@ -331,7 +331,6 @@ namespace TGServerService
|
||||
{
|
||||
var datInstance = ((ServerInstance)hosts[config.Directory].SingletonInstance);
|
||||
WriteEntry(String.Format("Unable to start instance at path {0}. Has the same name as instance at path {1}. Detaching...", config.Directory, datInstance.ServerDirectory()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID);
|
||||
Properties.Settings.Default.InstancePaths.Remove(config.Directory);
|
||||
return null;
|
||||
}
|
||||
if (!config.Enabled)
|
||||
@@ -350,7 +349,7 @@ namespace TGServerService
|
||||
var host = CreateHost(instance, String.Format("{0}/{1}", Interface.InstanceInterfaceName, instanceName));
|
||||
hosts.Add(instanceName, host);
|
||||
|
||||
foreach (var J in Interface.ValidInterfaces)
|
||||
foreach (var J in Interface.ValidInstanceInterfaces)
|
||||
AddEndpoint(host, J);
|
||||
|
||||
host.Authorization.ServiceAuthorizationManager = instance;
|
||||
@@ -471,6 +470,7 @@ namespace TGServerService
|
||||
/// <inheritdoc />
|
||||
public string CreateInstance(string Name, string path)
|
||||
{
|
||||
path = Program.NormalizePath(path);
|
||||
var res = CheckInstanceName(Name);
|
||||
if (res != null)
|
||||
return res;
|
||||
@@ -510,6 +510,8 @@ namespace TGServerService
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
string SetupOneInstance(IInstanceConfig config)
|
||||
{
|
||||
if (!config.Enabled)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
var host = SetupInstance(config);
|
||||
@@ -529,6 +531,7 @@ namespace TGServerService
|
||||
/// <inheritdoc />
|
||||
public string ImportInstance(string path)
|
||||
{
|
||||
path = Program.NormalizePath(path);
|
||||
var Config = Properties.Settings.Default;
|
||||
lock (this)
|
||||
{
|
||||
@@ -587,24 +590,14 @@ namespace TGServerService
|
||||
{
|
||||
if (hostIsOnline)
|
||||
return null;
|
||||
//now this is a bit awkward because we need to check each instance config for the one named Name
|
||||
string LastCheckedConfig = null;
|
||||
try
|
||||
{
|
||||
foreach (var ic in GetInstanceConfigs())
|
||||
foreach (var ic in GetInstanceConfigs())
|
||||
if (ic.Name == Name)
|
||||
{
|
||||
if (ic.Name == Name)
|
||||
{
|
||||
path = ic.Directory;
|
||||
ic.Enabled = true;
|
||||
return SetupOneInstance(ic);
|
||||
}
|
||||
path = ic.Directory;
|
||||
ic.Enabled = true;
|
||||
ic.Save();
|
||||
return SetupOneInstance(ic);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return String.Format("An error occurred while checking instance config at {0}! Error: ", LastCheckedConfig, e.ToString());
|
||||
}
|
||||
return String.Format("Instance {0} does not exist!", Name);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
<Compile Include="ChatCommands\RootChatCommand.cs" />
|
||||
<Compile Include="ChatCommands\ServerChatCommand.cs" />
|
||||
<Compile Include="ChatCommands\VersionCommand.cs" />
|
||||
<Compile Include="AdministrativeAuthorizationManager.cs" />
|
||||
<Compile Include="RootAuthorizationManager.cs" />
|
||||
<Compile Include="DeprecatedInstanceConfig.cs" />
|
||||
<Compile Include="InstanceConfig.cs" />
|
||||
<Compile Include="MessageType.cs" />
|
||||
|
||||
@@ -13,12 +13,5 @@ namespace TGServiceInterface.Components
|
||||
/// </summary>
|
||||
[OperationContract]
|
||||
void VerifyConnection();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve's the service's version
|
||||
/// </summary>
|
||||
/// <returns>The service's version</returns>
|
||||
[OperationContract]
|
||||
string Version();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,5 +14,12 @@ namespace TGServiceInterface.Components
|
||||
/// <returns>The path to the directory on success, null on failure</returns>
|
||||
[OperationContract]
|
||||
string ServerDirectory();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve's the service's version
|
||||
/// </summary>
|
||||
/// <returns>The service's version</returns>
|
||||
[OperationContract]
|
||||
string Version();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace TGServiceInterface.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for managing <see cref="ITGInstance"/>s
|
||||
/// </summary>
|
||||
[ServiceContract]
|
||||
public interface ITGInstanceManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ITGInstance"/>
|
||||
/// </summary>
|
||||
/// <param name="Name">The name of the instance</param>
|
||||
/// <param name="path">The path to the instance</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string CreateInstance(string Name, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Registers an existing server instance
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the instance</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string ImportInstance(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if an instance is online
|
||||
/// </summary>
|
||||
/// <param name="Name">The name of the instance</param>
|
||||
/// <returns><see langword="true"/> if the Instance exists and is online, <see langword="false"/> otherwise</returns>
|
||||
[OperationContract]
|
||||
bool InstanceEnabled(string Name);
|
||||
|
||||
/// <summary>
|
||||
/// Sets an instance's enabled status
|
||||
/// </summary>
|
||||
/// <param name="Name">The instance whom's status should be changed</param>
|
||||
/// <param name="enabled"><see langword="true"/> to enable the instance, <see langword="false"/> to disable it</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string SetInstanceEnabled(string Name, bool enabled);
|
||||
|
||||
/// <summary>
|
||||
/// Renames an instance, this will restart the instance if it is enabled
|
||||
/// </summary>
|
||||
/// <param name="name">The current name of the instance</param>
|
||||
/// <param name="new_name">The new name of the instance</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string RenameInstance(string name, string new_name);
|
||||
|
||||
/// <summary>
|
||||
/// Disables and unregisters an instance, allowing the folder and data to be manipulated manually
|
||||
/// </summary>
|
||||
/// <param name="name">The instance to detach</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string DetachInstance(string name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace TGServiceInterface.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for general authentication and listing <see cref="ITGInstance"/>s
|
||||
/// </summary>
|
||||
[ServiceContract]
|
||||
public interface ITGLanding
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve's the service's version
|
||||
/// </summary>
|
||||
/// <returns>The service's version</returns>
|
||||
[OperationContract]
|
||||
string Version();
|
||||
|
||||
/// <summary>
|
||||
/// List instances that the caller can access
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="IDictionary{TKey, TValue}"/> of instance names relating to their paths</returns>
|
||||
[OperationContract]
|
||||
IList<InstanceMetadata> ListInstances();
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,6 @@ namespace TGServiceInterface.Components
|
||||
[OperationContract]
|
||||
void PrepareForUpdate();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve's the service's version
|
||||
/// </summary>
|
||||
/// <returns>The service's version</returns>
|
||||
[OperationContract]
|
||||
string Version();
|
||||
|
||||
/// <summary>
|
||||
/// Get the port used for remote operation
|
||||
/// </summary>
|
||||
@@ -40,62 +33,11 @@ namespace TGServiceInterface.Components
|
||||
string SetRemoteAccessPort(ushort port);
|
||||
|
||||
/// <summary>
|
||||
/// List instances
|
||||
/// Retrieve's the service's version
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="IDictionary{TKey, TValue}"/> of instance names relating to their paths</returns>
|
||||
/// <returns>The service's version</returns>
|
||||
[OperationContract]
|
||||
IList<InstanceMetadata> ListInstances();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new server instance
|
||||
/// </summary>
|
||||
/// <param name="Name">The name of the instance</param>
|
||||
/// <param name="path">The path to the instance</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string CreateInstance(string Name, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Registers an existing server instance
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the instance</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string ImportInstance(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if an instance is online
|
||||
/// </summary>
|
||||
/// <param name="Name">The name of the instance</param>
|
||||
/// <returns><see langword="true"/> if the Instance exists and is online, <see langword="false"/> otherwise</returns>
|
||||
[OperationContract]
|
||||
bool InstanceEnabled(string Name);
|
||||
|
||||
/// <summary>
|
||||
/// Sets an instance's enabled status
|
||||
/// </summary>
|
||||
/// <param name="Name">The instance whom's status should be changed</param>
|
||||
/// <param name="enabled"><see langword="true"/> to enable the instance, <see langword="false"/> to disable it</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string SetInstanceEnabled(string Name, bool enabled);
|
||||
|
||||
/// <summary>
|
||||
/// Renames an instance, this will restart the instance if it is enabled
|
||||
/// </summary>
|
||||
/// <param name="name">The current name of the instance</param>
|
||||
/// <param name="new_name">The new name of the instance</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string RenameInstance(string name, string new_name);
|
||||
|
||||
/// <summary>
|
||||
/// Disables and unregisters an instance, allowing the folder and data to be manipulated manually
|
||||
/// </summary>
|
||||
/// <param name="name">The instance to detach</param>
|
||||
/// <returns><see langword="null"/> on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string DetachInstance(string name);
|
||||
string Version();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the path to the python 2.7 installation
|
||||
|
||||
@@ -52,17 +52,17 @@ namespace TGServiceInterface
|
||||
bool VersionMismatch(out string errorMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the requested <see cref="IInterface"/> 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
|
||||
/// Returns the requested <see cref="IInterface"/> 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 the <see cref="ITGSService"/> component for the service
|
||||
/// Returns a root service component
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="ITGSService"/> component for the service</returns>
|
||||
ITGSService GetService();
|
||||
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
|
||||
@@ -82,9 +82,14 @@ namespace TGServiceInterface
|
||||
sealed public class Interface : IInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// List of <see langword="interface"/>s that can be used with <see cref="GetComponent{T}"/> and <see cref="CreateChannel{T}"/>
|
||||
/// List of <see langword="interface"/>s that can be used with <see cref="GetServiceComponent{T}"/>
|
||||
/// </summary>
|
||||
public static readonly IList<Type> ValidInterfaces = CollectComponents();
|
||||
public static readonly IList<Type> ValidServiceInterfaces = new List<Type> { typeof(ITGSService), typeof(ITGInstanceManager), typeof(ITGConnectivity), typeof(ITGLanding) };
|
||||
|
||||
/// <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
|
||||
@@ -145,13 +150,13 @@ namespace TGServiceInterface
|
||||
/// <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 ServiceComponent = typeof(ITGSService); //this is special
|
||||
//find all interfaces in this assembly in this namespace that have the service contract attribute
|
||||
var ConnectivityComponent = typeof(ITGConnectivity);
|
||||
//find all interfaces in this assembly in this namespace that have the service contract attribute
|
||||
var query = from t in Assembly.GetExecutingAssembly().GetTypes()
|
||||
where t.IsInterface
|
||||
&& t.Namespace == ServiceComponent.Namespace
|
||||
&& t.Namespace == ConnectivityComponent.Namespace
|
||||
&& t.GetCustomAttribute(typeof(ServiceContractAttribute)) != null
|
||||
&& t != ServiceComponent
|
||||
&& (t == ConnectivityComponent || !ValidServiceInterfaces.Contains(t))
|
||||
select t;
|
||||
return query.ToList();
|
||||
}
|
||||
@@ -288,7 +293,7 @@ namespace TGServiceInterface
|
||||
/// <inheritdoc />
|
||||
public bool VersionMismatch(out string errorMessage)
|
||||
{
|
||||
var splits = GetService().Version().Split(' ');
|
||||
var splits = GetServiceComponent<ITGLanding>().Version().Split(' ');
|
||||
var theirs = new Version(splits[splits.Length - 1].Substring(1));
|
||||
var ours = new Version(FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion);
|
||||
if(theirs.Major != ours.Major || theirs.Minor != ours.Minor || theirs.Revision != ours.Revision) //don't care about the patch level
|
||||
@@ -314,7 +319,7 @@ namespace TGServiceInterface
|
||||
public T GetComponent<T>()
|
||||
{
|
||||
var ToT = typeof(T);
|
||||
if (!ValidInterfaces.Contains(ToT) && ToT != typeof(ITGSService))
|
||||
if (!ValidInstanceInterfaces.Contains(ToT))
|
||||
throw new Exception("Invalid type!");
|
||||
return GetComponentImpl<T>(true);
|
||||
}
|
||||
@@ -357,9 +362,12 @@ namespace TGServiceInterface
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITGSService GetService()
|
||||
public T GetServiceComponent<T>()
|
||||
{
|
||||
return GetComponentImpl<ITGSService>(false);
|
||||
var ToT = typeof(T);
|
||||
if (!ValidServiceInterfaces.Contains(ToT))
|
||||
throw new Exception("Invalid type!");
|
||||
return GetComponentImpl<T>(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -420,10 +428,9 @@ namespace TGServiceInterface
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.None;
|
||||
}
|
||||
var service = GetService();
|
||||
try
|
||||
{
|
||||
service.Version();
|
||||
GetServiceComponent<ITGLanding>().Version();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@@ -432,8 +439,7 @@ namespace TGServiceInterface
|
||||
}
|
||||
try
|
||||
{
|
||||
// TODO
|
||||
|
||||
GetServiceComponent<ITGSService>().Version();
|
||||
error = null;
|
||||
return ConnectivityLevel.Administrator;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<Compile Include="Components\DreamDaemon.cs" />
|
||||
<Compile Include="Components\Chat.cs" />
|
||||
<Compile Include="Components\Instance.cs" />
|
||||
<Compile Include="Components\InstanceManager.cs" />
|
||||
<Compile Include="Components\Landing.cs" />
|
||||
<Compile Include="Enumerations.cs" />
|
||||
<Compile Include="Helpers.cs" />
|
||||
<Compile Include="InstanceMetadata.cs" />
|
||||
|
||||
Reference in New Issue
Block a user