diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 9dc136a1df..930b4465b8 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -28,29 +28,11 @@ Visual Studio comes with the nuget package manager. To install the dependencies,
##### (Optional) Installing WiX Toolset and Visual Studio Extension
-The [WiX Toolset](http://wixtoolset.org/) is used for creating the installer .msi (Not the .exe, which is a standard C# program wrapper to the .msi). Building and modifying this is not required for debugging and development of the service but necessary if you want to debug tweaks to the installer configuration. You can download the Wix Toolset and Visual studio extension [here](http://wixtoolset.org/releases/). This will allow you to build `TGServiceInstaller.wixproj` just like all the other projects.
+The [WiX Toolset](http://wixtoolset.org/) is used for creating the installer .msi (Not the .exe, which is a standard C# program wrapper to the .msi). Building and modifying this is not required for debugging and development of the service but necessary if you want to debug tweaks to the installer configuration. You can download the Wix Toolset and Visual studio extension [here](http://wixtoolset.org/releases/). This will allow you to build `TGS.Installer.wixproj` just like all the other projects.
-#### Debugging
+##### Debugging
-So you've built the project and everything's good, right? Now you have to debug it. Debugging the command line and control panel are easy enough, just launch them like any other process. Debugging the TGServerService itself though requires a bit of finagling due to how Windows services work.
-
-1. Uninstall any release versions of TG Station Server 3 you may have on your machine
-1. Open an administrative Windows cmd prompt
-1. Run `sc delete "TG Station Server"` for sanity
-1. Build the service in debug mode
-1. Navigate to `C:\Windows\Microsoft.NET\Framework\v4.0.30319`
-1. Run `InstallUtil.exe` with the path to your debug `TGServerService.exe` as an argument. This will register your debug build as a Windows service.
-
-If the command runs successfully you're all set up. Now, here is the debugging process.
-
-1. BEFORE BUILDING. Stop `TG Station Server` from the Windows Services control panel
-1. Build your new Debug version
-1. Set your breakpoints
-1. Start the service
-1. Use your environment to attach to `TGServerService.exe` for debugging
-1. If you need to debug startup, you'll have to add `System.Diagnostics.Debugger.Start()` where you want the service to wait for you. Do not write a constructor for the Service classas Windows will not let you debug it properly
-
-Now be careful while debugging. The service runs with root level privileges and you wouldn't want any [accidents](http://i.imgur.com/zvGEpJD.png) to happen, would you?
+Be careful while debugging. The service runs with root level privileges and you wouldn't want any [accidents](http://i.imgur.com/zvGEpJD.png) to happen, would you?
## Meet the Team
diff --git a/AssemblyInfo.global.cs b/AssemblyInfo.global.cs
index 614572a360..6ca7084733 100644
--- a/AssemblyInfo.global.cs
+++ b/AssemblyInfo.global.cs
@@ -7,4 +7,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyFileVersion("3.2.0.6")]
[assembly: AssemblyInformationalVersion("3.2.0.6")]
-[assembly: InternalsVisibleTo("TGServiceTests")]
+[assembly: InternalsVisibleTo("TGS.Tests")]
diff --git a/README.md b/README.md
index 21bdb7331a..8c1ca4f6c4 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[](https://ci.appveyor.com/project/Cyberboss/tgstation-server-tools) [](https://travis-ci.org/tgstation/tgstation-server) [](https://codecov.io/gh/tgstation/tgstation-server)
-[](https://github.com/tgstation/tgstation-server/blob/master/LICENSE) [](http://isitmaintained.com/project/tgstation/tgstation-server "Average time to resolve an issue") [](https://badge.fury.io/nu/TGServiceInterface)
+[](https://github.com/tgstation/tgstation-server/blob/master/LICENSE) [](http://isitmaintained.com/project/tgstation/tgstation-server "Average time to resolve an issue") [](https://badge.fury.io/nu/TGServiceInterface)
[](http://forthebadge.com) [](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a)
@@ -191,7 +191,7 @@ You can clear all active test merges using `Reset to Origin Branch` in the `Repo
### Viewing Server Logs
* Logs are stored in the Windows event viewer under `Windows Logs` -> `Application`. You'll need to filter this list for `TG Station Server`
-* Every event type is keyed with an ID. A complete listing of these IDs and their purpose can be found [here](https://github.com/tgstation/tgstation-server/blob/master/TGServerService/EventID.cs).
+* Every event type is keyed with an ID. A complete listing of these IDs and their purpose can be found [here](https://github.com/tgstation/tgstation-server/blob/master/TGS.Server/EventID.cs).
* You can also import the custom view `View TGS3 Logs.xml` in this folder to have them automatically filtered
### Enabling upstream changelog generation
diff --git a/TGCommandLine/ConsoleCommand.cs b/TGCommandLine/ConsoleCommand.cs
deleted file mode 100644
index 7f9489d1c1..0000000000
--- a/TGCommandLine/ConsoleCommand.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using TGServiceInterface;
-
-namespace TGCommandLine
-{
- abstract class ConsoleCommand : Command
- {
- ///
- /// The currently in use by the
- ///
- public static IInterface Interface;
- }
-}
diff --git a/TGCommandLine/AdminCommands.cs b/TGS.CommandLine/AdminCommands.cs
similarity index 96%
rename from TGCommandLine/AdminCommands.cs
rename to TGS.CommandLine/AdminCommands.cs
index aedddd15b1..953c002b07 100644
--- a/TGCommandLine/AdminCommands.cs
+++ b/TGS.CommandLine/AdminCommands.cs
@@ -1,8 +1,8 @@
using System.Collections.Generic;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class AdminCommand : InstanceRootCommand
{
diff --git a/TGCommandLine/App.config b/TGS.CommandLine/App.config
similarity index 100%
rename from TGCommandLine/App.config
rename to TGS.CommandLine/App.config
diff --git a/TGCommandLine/BYONDCommands.cs b/TGS.CommandLine/BYONDCommands.cs
similarity index 97%
rename from TGCommandLine/BYONDCommands.cs
rename to TGS.CommandLine/BYONDCommands.cs
index 2666104e44..869c1ccfd3 100644
--- a/TGCommandLine/BYONDCommands.cs
+++ b/TGS.CommandLine/BYONDCommands.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class BYONDCommand : InstanceRootCommand
{
diff --git a/TGCommandLine/ChatCommands.cs b/TGS.CommandLine/ChatCommands.cs
similarity index 99%
rename from TGCommandLine/ChatCommands.cs
rename to TGS.CommandLine/ChatCommands.cs
index 651520457d..bf5fd5d3aa 100644
--- a/TGCommandLine/ChatCommands.cs
+++ b/TGS.CommandLine/ChatCommands.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class IRCCommand : InstanceRootCommand
{
diff --git a/TGCommandLine/ConfigCommands.cs b/TGS.CommandLine/ConfigCommands.cs
similarity index 97%
rename from TGCommandLine/ConfigCommands.cs
rename to TGS.CommandLine/ConfigCommands.cs
index 0aae903ed4..ab4191a5d6 100644
--- a/TGCommandLine/ConfigCommands.cs
+++ b/TGS.CommandLine/ConfigCommands.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class ConfigCommand : InstanceRootCommand
{
diff --git a/TGS.CommandLine/ConsoleCommand.cs b/TGS.CommandLine/ConsoleCommand.cs
new file mode 100644
index 0000000000..1aa0e3f773
--- /dev/null
+++ b/TGS.CommandLine/ConsoleCommand.cs
@@ -0,0 +1,12 @@
+using TGS.Interface;
+
+namespace TGS.CommandLine
+{
+ abstract class ConsoleCommand : Command
+ {
+ ///
+ /// The currently in use by the
+ ///
+ public static IServerInterface Interface;
+ }
+}
diff --git a/TGCommandLine/DDCommands.cs b/TGS.CommandLine/DDCommands.cs
similarity index 94%
rename from TGCommandLine/DDCommands.cs
rename to TGS.CommandLine/DDCommands.cs
index ef518c8911..9681589cf8 100644
--- a/TGCommandLine/DDCommands.cs
+++ b/TGS.CommandLine/DDCommands.cs
@@ -1,315 +1,315 @@
-using System;
-using System.Collections.Generic;
-using TGServiceInterface;
-using TGServiceInterface.Components;
-
-namespace TGCommandLine
-{
- class DDCommand : InstanceRootCommand
- {
- public DDCommand()
- {
- Keyword = "dd";
- Children = new Command[] { new DDStartCommand(), new DDStopCommand(), new DDRestartCommand(), new DDStatusCommand(), new DDAutostartCommand(), new DDPortCommand(), new DDSecurityCommand(), new DDWorldAnnounceCommand(), new DDWebclientCommand() };
- }
- public override string GetHelpText()
- {
- return "Manage DreamDaemon";
- }
- }
-
- class DDWorldAnnounceCommand : ConsoleCommand
- {
- public DDWorldAnnounceCommand()
- {
- Keyword = "announce";
- RequiredParameters = 1;
- }
-
- public override string GetHelpText()
- {
- return "Sends a message all players on the server";
- }
-
- public override string GetArgumentString()
- {
- return "";
- }
-
- protected override ExitCode Run(IList parameters)
- {
- var res = Interface.GetComponent().WorldAnnounce(String.Join(" ", parameters));
- OutputProc(res ?? "Success!");
- return res == null ? ExitCode.Normal : ExitCode.ServerError;
- }
- }
-
- class DDStartCommand : ConsoleCommand
- {
- public DDStartCommand()
- {
- Keyword = "start";
- }
-
- public override string GetHelpText()
- {
- return "Starts the server and watchdog";
- }
-
- protected override ExitCode Run(IList parameters)
- {
- var res = Interface.GetComponent().Start();
- OutputProc(res ?? "Success!");
- return res == null ? ExitCode.Normal : ExitCode.ServerError;
- }
- }
-
- class DDStopCommand : ConsoleCommand
- {
- public DDStopCommand()
- {
- Keyword = "stop";
- }
- public override string GetArgumentString()
- {
- return "[--graceful]";
- }
-
- public override string GetHelpText()
- {
- return "Stops the server and watchdog optionally waiting for the current round to end";
- }
-
- protected override ExitCode Run(IList parameters)
- {
- var DD = Interface.GetComponent();
- if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful")
- {
- if (DD.DaemonStatus() != DreamDaemonStatus.Online)
- {
- OutputProc("Error: The game is not currently running!");
- return ExitCode.ServerError;
- }
- DD.RequestStop();
- return ExitCode.Normal;
- }
- var res = DD.Stop();
- OutputProc(res ?? "Success!");
- return res == null ? ExitCode.Normal : ExitCode.ServerError;
- }
- }
- class DDRestartCommand : ConsoleCommand
- {
- public DDRestartCommand()
- {
- Keyword = "restart";
- }
-
- public override string GetArgumentString()
- {
- return "[--graceful]";
- }
- protected override ExitCode Run(IList parameters)
- {
- var DD = Interface.GetComponent();
- if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful")
- {
- if (DD.DaemonStatus() != DreamDaemonStatus.Online)
- {
- OutputProc("Error: The game is not currently running!");
- return ExitCode.ServerError;
- }
- DD.RequestRestart();
- return ExitCode.Normal;
- }
- var res = DD.Restart();
- OutputProc(res ?? "Success!");
- return res == null ? ExitCode.Normal : ExitCode.ServerError;
- }
-
- public override string GetHelpText()
- {
- return "Restarts the server and watchdog optionally waiting for the current round to end";
- }
- }
- class DDStatusCommand : ConsoleCommand
- {
- public DDStatusCommand()
- {
- Keyword = "status";
- }
-
- public override string GetHelpText()
- {
- return "Gets the current status of the watchdog and server";
- }
-
- protected override ExitCode Run(IList parameters)
- {
- var DD = Interface.GetComponent();
- OutputProc(DD.StatusString(true));
- if (DD.ShutdownInProgress())
- OutputProc("The server will shutdown once the current round completes.");
- var pc = DD.PlayerCount();
- if (pc != -1)
- OutputProc(pc + " connected clients");
- return ExitCode.Normal;
- }
- }
-
- class DDAutostartCommand : ConsoleCommand
- {
- public DDAutostartCommand()
- {
- Keyword = "autostart";
- RequiredParameters = 1;
- }
-
- protected override ExitCode Run(IList parameters)
- {
- var DD = Interface.GetComponent();
- switch (parameters[0].ToLower())
- {
- case "on":
- DD.SetAutostart(true);
- break;
- case "off":
- DD.SetAutostart(false);
- break;
- case "check":
- OutputProc("Autostart is: " + (DD.Autostart() ? "On" : "Off"));
- break;
- default:
- OutputProc("Invalid parameter: " + parameters[0]);
- return ExitCode.BadCommand;
- }
- return ExitCode.Normal;
- }
-
- public override string GetArgumentString()
- {
- return "";
- }
- public override string GetHelpText()
- {
- return "Change or check autostarting of the game server with the service";
- }
- }
- class DDWebclientCommand : ConsoleCommand
- {
- public DDWebclientCommand()
- {
- Keyword = "webclient";
- RequiredParameters = 1;
- }
-
- protected override ExitCode Run(IList parameters)
- {
- var DD = Interface.GetComponent();
- switch (parameters[0].ToLower())
- {
- case "on":
- DD.SetWebclient(true);
- break;
- case "off":
- DD.SetWebclient(false);
- break;
- case "check":
- OutputProc("Webclient is: " + (DD.Webclient() ? "Enabled" : "Disabled"));
- break;
- default:
- OutputProc("Invalid parameter: " + parameters[0]);
- return ExitCode.BadCommand;
- }
- return ExitCode.Normal;
- }
-
- public override string GetArgumentString()
- {
- return "";
- }
- public override string GetHelpText()
- {
- return "Change or check if the BYOND webclient is enabled for the game server";
- }
- }
-
- class DDPortCommand : ConsoleCommand
- {
- public DDPortCommand()
- {
- Keyword = "set-port";
- RequiredParameters = 1;
- }
-
- protected override ExitCode Run(IList parameters)
- {
- ushort port;
- try
- {
- port = Convert.ToUInt16(parameters[0]);
- }
- catch
- {
- OutputProc("Invalid port number!");
- return ExitCode.BadCommand;
- }
-
- Interface.GetComponent().SetPort(port);
- return ExitCode.Normal;
- }
-
- public override string GetArgumentString()
- {
- return "";
- }
-
- public override string GetHelpText()
- {
- return "Sets the port DreamDaemon will open the server on. Requires a server restart to apply and queues a graceful one up";
- }
- }
-
- class DDSecurityCommand : ConsoleCommand
- {
- public DDSecurityCommand()
- {
- Keyword = "set-security";
- RequiredParameters = 1;
- }
-
- protected override ExitCode Run(IList parameters)
- {
- DreamDaemonSecurity sec;
- switch (parameters[0].ToLower())
- {
- case "safe":
- sec = DreamDaemonSecurity.Safe;
- break;
- case "ultra":
- case "ultrasafe":
- sec = DreamDaemonSecurity.Ultrasafe;
- break;
- case "trust":
- case "trusted":
- sec = DreamDaemonSecurity.Trusted;
- break;
- default:
- OutputProc("Invalid security word!");
- return ExitCode.BadCommand;
- }
- Interface.GetComponent().SetSecurityLevel(sec);
- return ExitCode.Normal;
- }
-
- public override string GetArgumentString()
- {
- return "";
- }
-
- public override string GetHelpText()
- {
- return "Sets the visibility option for the DreamDaemon world";
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using TGS.Interface;
+using TGS.Interface.Components;
+
+namespace TGS.CommandLine
+{
+ class DDCommand : InstanceRootCommand
+ {
+ public DDCommand()
+ {
+ Keyword = "dd";
+ Children = new Command[] { new DDStartCommand(), new DDStopCommand(), new DDRestartCommand(), new DDStatusCommand(), new DDAutostartCommand(), new DDPortCommand(), new DDSecurityCommand(), new DDWorldAnnounceCommand(), new DDWebclientCommand() };
+ }
+ public override string GetHelpText()
+ {
+ return "Manage DreamDaemon";
+ }
+ }
+
+ class DDWorldAnnounceCommand : ConsoleCommand
+ {
+ public DDWorldAnnounceCommand()
+ {
+ Keyword = "announce";
+ RequiredParameters = 1;
+ }
+
+ public override string GetHelpText()
+ {
+ return "Sends a message all players on the server";
+ }
+
+ public override string GetArgumentString()
+ {
+ return "";
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ var res = Interface.GetComponent().WorldAnnounce(String.Join(" ", parameters));
+ OutputProc(res ?? "Success!");
+ return res == null ? ExitCode.Normal : ExitCode.ServerError;
+ }
+ }
+
+ class DDStartCommand : ConsoleCommand
+ {
+ public DDStartCommand()
+ {
+ Keyword = "start";
+ }
+
+ public override string GetHelpText()
+ {
+ return "Starts the server and watchdog";
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ var res = Interface.GetComponent().Start();
+ OutputProc(res ?? "Success!");
+ return res == null ? ExitCode.Normal : ExitCode.ServerError;
+ }
+ }
+
+ class DDStopCommand : ConsoleCommand
+ {
+ public DDStopCommand()
+ {
+ Keyword = "stop";
+ }
+ public override string GetArgumentString()
+ {
+ return "[--graceful]";
+ }
+
+ public override string GetHelpText()
+ {
+ return "Stops the server and watchdog optionally waiting for the current round to end";
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ var DD = Interface.GetComponent();
+ if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful")
+ {
+ if (DD.DaemonStatus() != DreamDaemonStatus.Online)
+ {
+ OutputProc("Error: The game is not currently running!");
+ return ExitCode.ServerError;
+ }
+ DD.RequestStop();
+ return ExitCode.Normal;
+ }
+ var res = DD.Stop();
+ OutputProc(res ?? "Success!");
+ return res == null ? ExitCode.Normal : ExitCode.ServerError;
+ }
+ }
+ class DDRestartCommand : ConsoleCommand
+ {
+ public DDRestartCommand()
+ {
+ Keyword = "restart";
+ }
+
+ public override string GetArgumentString()
+ {
+ return "[--graceful]";
+ }
+ protected override ExitCode Run(IList parameters)
+ {
+ var DD = Interface.GetComponent();
+ if (parameters.Count > 0 && parameters[0].ToLower() == "--graceful")
+ {
+ if (DD.DaemonStatus() != DreamDaemonStatus.Online)
+ {
+ OutputProc("Error: The game is not currently running!");
+ return ExitCode.ServerError;
+ }
+ DD.RequestRestart();
+ return ExitCode.Normal;
+ }
+ var res = DD.Restart();
+ OutputProc(res ?? "Success!");
+ return res == null ? ExitCode.Normal : ExitCode.ServerError;
+ }
+
+ public override string GetHelpText()
+ {
+ return "Restarts the server and watchdog optionally waiting for the current round to end";
+ }
+ }
+ class DDStatusCommand : ConsoleCommand
+ {
+ public DDStatusCommand()
+ {
+ Keyword = "status";
+ }
+
+ public override string GetHelpText()
+ {
+ return "Gets the current status of the watchdog and server";
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ var DD = Interface.GetComponent();
+ OutputProc(DD.StatusString(true));
+ if (DD.ShutdownInProgress())
+ OutputProc("The server will shutdown once the current round completes.");
+ var pc = DD.PlayerCount();
+ if (pc != -1)
+ OutputProc(pc + " connected clients");
+ return ExitCode.Normal;
+ }
+ }
+
+ class DDAutostartCommand : ConsoleCommand
+ {
+ public DDAutostartCommand()
+ {
+ Keyword = "autostart";
+ RequiredParameters = 1;
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ var DD = Interface.GetComponent();
+ switch (parameters[0].ToLower())
+ {
+ case "on":
+ DD.SetAutostart(true);
+ break;
+ case "off":
+ DD.SetAutostart(false);
+ break;
+ case "check":
+ OutputProc("Autostart is: " + (DD.Autostart() ? "On" : "Off"));
+ break;
+ default:
+ OutputProc("Invalid parameter: " + parameters[0]);
+ return ExitCode.BadCommand;
+ }
+ return ExitCode.Normal;
+ }
+
+ public override string GetArgumentString()
+ {
+ return "";
+ }
+ public override string GetHelpText()
+ {
+ return "Change or check autostarting of the game server with the service";
+ }
+ }
+ class DDWebclientCommand : ConsoleCommand
+ {
+ public DDWebclientCommand()
+ {
+ Keyword = "webclient";
+ RequiredParameters = 1;
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ var DD = Interface.GetComponent();
+ switch (parameters[0].ToLower())
+ {
+ case "on":
+ DD.SetWebclient(true);
+ break;
+ case "off":
+ DD.SetWebclient(false);
+ break;
+ case "check":
+ OutputProc("Webclient is: " + (DD.Webclient() ? "Enabled" : "Disabled"));
+ break;
+ default:
+ OutputProc("Invalid parameter: " + parameters[0]);
+ return ExitCode.BadCommand;
+ }
+ return ExitCode.Normal;
+ }
+
+ public override string GetArgumentString()
+ {
+ return "";
+ }
+ public override string GetHelpText()
+ {
+ return "Change or check if the BYOND webclient is enabled for the game server";
+ }
+ }
+
+ class DDPortCommand : ConsoleCommand
+ {
+ public DDPortCommand()
+ {
+ Keyword = "set-port";
+ RequiredParameters = 1;
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ ushort port;
+ try
+ {
+ port = Convert.ToUInt16(parameters[0]);
+ }
+ catch
+ {
+ OutputProc("Invalid port number!");
+ return ExitCode.BadCommand;
+ }
+
+ Interface.GetComponent().SetPort(port);
+ return ExitCode.Normal;
+ }
+
+ public override string GetArgumentString()
+ {
+ return "";
+ }
+
+ public override string GetHelpText()
+ {
+ return "Sets the port DreamDaemon will open the server on. Requires a server restart to apply and queues a graceful one up";
+ }
+ }
+
+ class DDSecurityCommand : ConsoleCommand
+ {
+ public DDSecurityCommand()
+ {
+ Keyword = "set-security";
+ RequiredParameters = 1;
+ }
+
+ protected override ExitCode Run(IList parameters)
+ {
+ DreamDaemonSecurity sec;
+ switch (parameters[0].ToLower())
+ {
+ case "safe":
+ sec = DreamDaemonSecurity.Safe;
+ break;
+ case "ultra":
+ case "ultrasafe":
+ sec = DreamDaemonSecurity.Ultrasafe;
+ break;
+ case "trust":
+ case "trusted":
+ sec = DreamDaemonSecurity.Trusted;
+ break;
+ default:
+ OutputProc("Invalid security word!");
+ return ExitCode.BadCommand;
+ }
+ Interface.GetComponent().SetSecurityLevel(sec);
+ return ExitCode.Normal;
+ }
+
+ public override string GetArgumentString()
+ {
+ return "";
+ }
+
+ public override string GetHelpText()
+ {
+ return "Sets the visibility option for the DreamDaemon world";
+ }
+ }
+}
diff --git a/TGCommandLine/DMCommands.cs b/TGS.CommandLine/DMCommands.cs
similarity index 98%
rename from TGCommandLine/DMCommands.cs
rename to TGS.CommandLine/DMCommands.cs
index cbc1ef6ae2..380f2307e7 100644
--- a/TGCommandLine/DMCommands.cs
+++ b/TGS.CommandLine/DMCommands.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class DMCommand : InstanceRootCommand
{
diff --git a/TGCommandLine/InstanceRootCommand.cs b/TGS.CommandLine/InstanceRootCommand.cs
similarity index 88%
rename from TGCommandLine/InstanceRootCommand.cs
rename to TGS.CommandLine/InstanceRootCommand.cs
index 85fd78610b..107fe20689 100644
--- a/TGCommandLine/InstanceRootCommand.cs
+++ b/TGS.CommandLine/InstanceRootCommand.cs
@@ -1,11 +1,11 @@
using System.Collections.Generic;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
abstract class InstanceRootCommand : RootCommand
{
- public static IInterface currentInterface;
+ public static IServerInterface currentInterface;
public override ExitCode DoRun(IList parameters)
{
if (currentInterface.InstanceName == null)
diff --git a/TGCommandLine/Program.cs b/TGS.CommandLine/Program.cs
similarity index 88%
rename from TGCommandLine/Program.cs
rename to TGS.CommandLine/Program.cs
index fb0e245d09..a9157d9512 100644
--- a/TGCommandLine/Program.cs
+++ b/TGS.CommandLine/Program.cs
@@ -1,286 +1,285 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TGServiceInterface;
-using TGServiceInterface.Components;
-
-namespace TGCommandLine
-{
-
- class Program
- {
- static bool interactive = false, saidSrvVersion = false;
- static IInterface currentInterface;
- static Command.ExitCode RunCommandLine(IList argsAsList)
- {
- //first lookup the connection string
- bool badConnectionString = false;
- for (var I = 0; I < argsAsList.Count - 1; ++I) {
- var lowerarg = argsAsList[I].ToLower();
- if (lowerarg == "-c" || lowerarg == "--connect")
- {
- var connectionString = argsAsList[I + 1];
- var splits = connectionString.Split('@');
- var userpass = splits[0].Split(':');
- if (splits.Length != 2 || userpass.Length != 2)
- {
- badConnectionString = true;
- break;
- }
- var addrport = splits[1].Split(':');
- if (addrport.Length != 2)
- {
- badConnectionString = true;
- break;
- }
- var username = userpass[0];
- var password = userpass[1];
- var address = addrport[0];
- ushort port;
- try
- {
- port = Convert.ToUInt16(addrport[1]);
- }
- catch
- {
- badConnectionString = true;
- break;
- }
- if(String.IsNullOrWhiteSpace(username) || String.IsNullOrWhiteSpace(password) || String.IsNullOrWhiteSpace(address))
- {
- badConnectionString = true;
- break;
- }
- argsAsList.RemoveAt(I);
- argsAsList.RemoveAt(I);
- ReplaceInterface(new Interface(address, port, username, password));
- break;
- }
- }
-
- if (badConnectionString)
- {
- Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port");
- return Command.ExitCode.BadCommand;
- }
-
- var res = currentInterface.ConnectionStatus(out string error);
- if (!res.HasFlag(ConnectivityLevel.Connected))
- {
- Console.WriteLine("Unable to connect to service: " + error);
- Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port");
- return Command.ExitCode.ConnectionError;
- }
-
- if (!res.HasFlag(ConnectivityLevel.Authenticated))
- {
- Console.WriteLine("Authentication error: Username/password/windows identity is not authorized!");
- return Command.ExitCode.ConnectionError;
- }
-
- if (!SentVMMWarning && currentInterface.VersionMismatch(out error))
- {
- SentVMMWarning = true;
- Console.WriteLine(error);
- }
- else if (interactive && !saidSrvVersion)
- {
- Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent().Version());
- saidSrvVersion = true;
- }
-
- try
- {
- return new CLICommand(currentInterface).DoRun(argsAsList);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error: " + e.ToString());
- return Command.ExitCode.ConnectionError;
- };
- }
-
- static void ReplaceInterface(IInterface I)
- {
- currentInterface = I;
- ConsoleCommand.Interface = I;
- InstanceRootCommand.currentInterface = I;
- saidSrvVersion = false;
- }
-
- public static string ReadLineSecure()
- {
- string result = "";
- while (true)
- {
- ConsoleKeyInfo i = Console.ReadKey(true);
- if (i.Key == ConsoleKey.Enter)
- {
- break;
- }
- else if (i.Key == ConsoleKey.Backspace)
- {
- if (result.Length > 0)
- {
- result = result.Substring(0, result.Length - 1);
- Console.Write("\b \b");
- }
- }
- else
- {
- result += i.KeyChar;
- Console.Write("*");
- }
- }
- Console.WriteLine();
- return result;
- }
- static bool SentVMMWarning = false;
- static string AcceptedBadCert;
- static bool BadCertificateInteractive(string message)
- {
- if (AcceptedBadCert == message)
- return true;
- Console.WriteLine(message);
- Console.Write("Do you wish to continue? NOT RECCOMENDED! (y/N): ");
- var result = Console.ReadLine().Trim().ToLower();
- if (result == "y" || result == "yes")
- {
- AcceptedBadCert = message;
- return true;
- }
- return false;
- }
-
- ///
- /// Tries to set 's to , outputting appropriate messages
- ///
- /// The name of the to test
- /// If , does not output on success
- /// if a was achieved with , otherwise
- static bool CheckInstanceConnectivity(string instanceName, bool silentSuccess)
- {
- var res = currentInterface.ConnectToInstance(instanceName);
- if (!res.HasFlag(ConnectivityLevel.Connected))
- Console.WriteLine("Unable to connect to instance! Does it exist?");
- else if (!res.HasFlag(ConnectivityLevel.Authenticated))
- Console.WriteLine("The current user is not authorized to use this instance!");
- else
- {
- if(!silentSuccess)
- Console.WriteLine("Successfully conected to instance!");
- return true;
- }
- return false;
- }
-
- static int Main(string[] args)
- {
- ReplaceInterface(new Interface());
- Command.OutputProcVar.Value = Console.WriteLine;
- if (args.Length != 0)
- {
- var argsAsList = new List(args);
- for (var I = 0; I < argsAsList.Count - 1; ++I)
- {
- if (argsAsList[I].ToLower() == "--instance")
- {
- if (!CheckInstanceConnectivity(args[I + 1], true))
- return (int)Command.ExitCode.ConnectionError;
- argsAsList.RemoveRange(I, 2);
- break;
- }
- else if (argsAsList[I].ToLower() == "--disable-ssl-verification") //im just not even going to document this because i hate it so much
- {
- argsAsList.RemoveAt(I);
- --I;
- Interface.SetBadCertificateHandler(_ => false);
- }
- }
- return (int)RunCommandLine(argsAsList);
- }
- //interactive mode
- Interface.SetBadCertificateHandler(BadCertificateInteractive);
- Console.WriteLine("Type 'instance' to connect to a server instance");
- Console.WriteLine("Type 'remote' to connect to a remote service");
- while (true)
- {
- Console.Write("Enter command: ");
- var NextCommand = Console.ReadLine();
- switch (NextCommand.ToLower())
- {
- case "instance":
- Console.Write("Enter instance name: ");
- CheckInstanceConnectivity(Console.ReadLine(), false);
- break;
- case "remote":
- SentVMMWarning = false;
- Console.Write("Enter server address: ");
- var address = Console.ReadLine();
- Console.Write("Enter server port: ");
- ushort port;
- try{
- port = Convert.ToUInt16(Console.ReadLine());
- }
- catch
- {
- Console.WriteLine("Error: Bad port!");
- break;
- }
- Console.Write("Enter username: ");
- var username = Console.ReadLine();
- Console.Write("Enter password: ");
- var password = ReadLineSecure();
- ReplaceInterface(new Interface(address, port, username, password));
- var res = currentInterface.ConnectionStatus(out string error);
- if (!res.HasFlag(ConnectivityLevel.Connected))
- {
- Console.WriteLine("Unable to connect: " + error);
- ReplaceInterface(new Interface());
- }
- else if (!res.HasFlag(ConnectivityLevel.Authenticated))
- {
- Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode...");
- ReplaceInterface(new Interface());
- }
- else
- {
- Console.WriteLine("Connected remotely");
- if (currentInterface.VersionMismatch(out error))
- {
- SentVMMWarning = true;
- Console.WriteLine(error);
- }
- Console.WriteLine("Type 'disconnect' to return to local mode");
- }
- break;
- case "disconnect":
- SentVMMWarning = false;
- ReplaceInterface(new Interface());
- Console.WriteLine("Switch to local mode");
- break;
- case "quit":
- case "exit":
- return (int)Command.ExitCode.Normal;
-#if DEBUG
- case "debug-upgrade":
- currentInterface.GetComponent().PrepareForUpdate();
- return (int)Command.ExitCode.Normal;
-#endif
- default:
- //linq voodoo to get quoted strings
- var formattedCommand = NextCommand.Split('"')
- .Select((element, index) => index % 2 == 0 // If even index
- ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) // Split the item
- : new string[] { element }) // Keep the entire item
- .SelectMany(element => element).ToList();
-
- formattedCommand = formattedCommand.Select(x => x.Trim()).ToList();
- formattedCommand.Remove("");
- RunCommandLine(formattedCommand);
- break;
- }
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TGS.Interface;
+using TGS.Interface.Components;
+
+namespace TGS.CommandLine
+{
+ class Program
+ {
+ static bool interactive = false, saidSrvVersion = false;
+ static IServerInterface currentInterface;
+ static Command.ExitCode RunCommandLine(IList argsAsList)
+ {
+ //first lookup the connection string
+ bool badConnectionString = false;
+ for (var I = 0; I < argsAsList.Count - 1; ++I) {
+ var lowerarg = argsAsList[I].ToLower();
+ if (lowerarg == "-c" || lowerarg == "--connect")
+ {
+ var connectionString = argsAsList[I + 1];
+ var splits = connectionString.Split('@');
+ var userpass = splits[0].Split(':');
+ if (splits.Length != 2 || userpass.Length != 2)
+ {
+ badConnectionString = true;
+ break;
+ }
+ var addrport = splits[1].Split(':');
+ if (addrport.Length != 2)
+ {
+ badConnectionString = true;
+ break;
+ }
+ var username = userpass[0];
+ var password = userpass[1];
+ var address = addrport[0];
+ ushort port;
+ try
+ {
+ port = Convert.ToUInt16(addrport[1]);
+ }
+ catch
+ {
+ badConnectionString = true;
+ break;
+ }
+ if(String.IsNullOrWhiteSpace(username) || String.IsNullOrWhiteSpace(password) || String.IsNullOrWhiteSpace(address))
+ {
+ badConnectionString = true;
+ break;
+ }
+ argsAsList.RemoveAt(I);
+ argsAsList.RemoveAt(I);
+ ReplaceInterface(new ServerInterface(address, port, username, password));
+ break;
+ }
+ }
+
+ if (badConnectionString)
+ {
+ Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port");
+ return Command.ExitCode.BadCommand;
+ }
+
+ var res = currentInterface.ConnectionStatus(out string error);
+ if (!res.HasFlag(ConnectivityLevel.Connected))
+ {
+ Console.WriteLine("Unable to connect to service: " + error);
+ Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port");
+ return Command.ExitCode.ConnectionError;
+ }
+
+ if (!res.HasFlag(ConnectivityLevel.Authenticated))
+ {
+ Console.WriteLine("Authentication error: Username/password/windows identity is not authorized!");
+ return Command.ExitCode.ConnectionError;
+ }
+
+ if (!SentVMMWarning && currentInterface.VersionMismatch(out error))
+ {
+ SentVMMWarning = true;
+ Console.WriteLine(error);
+ }
+ else if (interactive && !saidSrvVersion)
+ {
+ Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent().Version());
+ saidSrvVersion = true;
+ }
+
+ try
+ {
+ return new CLICommand(currentInterface).DoRun(argsAsList);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: " + e.ToString());
+ return Command.ExitCode.ConnectionError;
+ };
+ }
+
+ static void ReplaceInterface(IServerInterface I)
+ {
+ currentInterface = I;
+ ConsoleCommand.Interface = I;
+ InstanceRootCommand.currentInterface = I;
+ saidSrvVersion = false;
+ }
+
+ public static string ReadLineSecure()
+ {
+ string result = "";
+ while (true)
+ {
+ ConsoleKeyInfo i = Console.ReadKey(true);
+ if (i.Key == ConsoleKey.Enter)
+ {
+ break;
+ }
+ else if (i.Key == ConsoleKey.Backspace)
+ {
+ if (result.Length > 0)
+ {
+ result = result.Substring(0, result.Length - 1);
+ Console.Write("\b \b");
+ }
+ }
+ else
+ {
+ result += i.KeyChar;
+ Console.Write("*");
+ }
+ }
+ Console.WriteLine();
+ return result;
+ }
+ static bool SentVMMWarning = false;
+ static string AcceptedBadCert;
+ static bool BadCertificateInteractive(string message)
+ {
+ if (AcceptedBadCert == message)
+ return true;
+ Console.WriteLine(message);
+ Console.Write("Do you wish to continue? NOT RECCOMENDED! (y/N): ");
+ var result = Console.ReadLine().Trim().ToLower();
+ if (result == "y" || result == "yes")
+ {
+ AcceptedBadCert = message;
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Tries to set 's to , outputting appropriate messages
+ ///
+ /// The name of the to test
+ /// If , does not output on success
+ /// if a was achieved with , otherwise
+ static bool CheckInstanceConnectivity(string instanceName, bool silentSuccess)
+ {
+ var res = currentInterface.ConnectToInstance(instanceName);
+ if (!res.HasFlag(ConnectivityLevel.Connected))
+ Console.WriteLine("Unable to connect to instance! Does it exist?");
+ else if (!res.HasFlag(ConnectivityLevel.Authenticated))
+ Console.WriteLine("The current user is not authorized to use this instance!");
+ else
+ {
+ if(!silentSuccess)
+ Console.WriteLine("Successfully conected to instance!");
+ return true;
+ }
+ return false;
+ }
+
+ static int Main(string[] args)
+ {
+ ReplaceInterface(new ServerInterface());
+ Command.OutputProcVar.Value = Console.WriteLine;
+ if (args.Length != 0)
+ {
+ var argsAsList = new List(args);
+ for (var I = 0; I < argsAsList.Count - 1; ++I)
+ {
+ if (argsAsList[I].ToLower() == "--instance")
+ {
+ if (!CheckInstanceConnectivity(args[I + 1], true))
+ return (int)Command.ExitCode.ConnectionError;
+ argsAsList.RemoveRange(I, 2);
+ break;
+ }
+ else if (argsAsList[I].ToLower() == "--disable-ssl-verification") //im just not even going to document this because i hate it so much
+ {
+ argsAsList.RemoveAt(I);
+ --I;
+ ServerInterface.SetBadCertificateHandler(_ => false);
+ }
+ }
+ return (int)RunCommandLine(argsAsList);
+ }
+ //interactive mode
+ ServerInterface.SetBadCertificateHandler(BadCertificateInteractive);
+ Console.WriteLine("Type 'instance' to connect to a server instance");
+ Console.WriteLine("Type 'remote' to connect to a remote service");
+ while (true)
+ {
+ Console.Write("Enter command: ");
+ var NextCommand = Console.ReadLine();
+ switch (NextCommand.ToLower())
+ {
+ case "instance":
+ Console.Write("Enter instance name: ");
+ CheckInstanceConnectivity(Console.ReadLine(), false);
+ break;
+ case "remote":
+ SentVMMWarning = false;
+ Console.Write("Enter server address: ");
+ var address = Console.ReadLine();
+ Console.Write("Enter server port: ");
+ ushort port;
+ try{
+ port = Convert.ToUInt16(Console.ReadLine());
+ }
+ catch
+ {
+ Console.WriteLine("Error: Bad port!");
+ break;
+ }
+ Console.Write("Enter username: ");
+ var username = Console.ReadLine();
+ Console.Write("Enter password: ");
+ var password = ReadLineSecure();
+ ReplaceInterface(new ServerInterface(address, port, username, password));
+ var res = currentInterface.ConnectionStatus(out string error);
+ if (!res.HasFlag(ConnectivityLevel.Connected))
+ {
+ Console.WriteLine("Unable to connect: " + error);
+ ReplaceInterface(new ServerInterface());
+ }
+ else if (!res.HasFlag(ConnectivityLevel.Authenticated))
+ {
+ Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode...");
+ ReplaceInterface(new ServerInterface());
+ }
+ else
+ {
+ Console.WriteLine("Connected remotely");
+ if (currentInterface.VersionMismatch(out error))
+ {
+ SentVMMWarning = true;
+ Console.WriteLine(error);
+ }
+ Console.WriteLine("Type 'disconnect' to return to local mode");
+ }
+ break;
+ case "disconnect":
+ SentVMMWarning = false;
+ ReplaceInterface(new ServerInterface());
+ Console.WriteLine("Switch to local mode");
+ break;
+ case "quit":
+ case "exit":
+ return (int)Command.ExitCode.Normal;
+#if DEBUG
+ case "debug-upgrade":
+ currentInterface.GetComponent().PrepareForUpdate();
+ return (int)Command.ExitCode.Normal;
+#endif
+ default:
+ //linq voodoo to get quoted strings
+ var formattedCommand = NextCommand.Split('"')
+ .Select((element, index) => index % 2 == 0 // If even index
+ ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) // Split the item
+ : new string[] { element }) // Keep the entire item
+ .SelectMany(element => element).ToList();
+
+ formattedCommand = formattedCommand.Select(x => x.Trim()).ToList();
+ formattedCommand.Remove("");
+ RunCommandLine(formattedCommand);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/TGCommandLine/Properties/AssemblyInfo.cs b/TGS.CommandLine/Properties/AssemblyInfo.cs
similarity index 97%
rename from TGCommandLine/Properties/AssemblyInfo.cs
rename to TGS.CommandLine/Properties/AssemblyInfo.cs
index 7017cbba7f..ba9129eaba 100644
--- a/TGCommandLine/Properties/AssemblyInfo.cs
+++ b/TGS.CommandLine/Properties/AssemblyInfo.cs
@@ -1,17 +1,17 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TGStation Server Commandline")]
-[assembly: AssemblyDescription("CLI for the TG Station Server Service")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("9ad1f086-a83e-4d14-a844-58a9471106b6")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TGStation Server Commandline")]
+[assembly: AssemblyDescription("CLI for the TG Station Server Service")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9ad1f086-a83e-4d14-a844-58a9471106b6")]
diff --git a/TGCommandLine/RepoCommands.cs b/TGS.CommandLine/RepoCommands.cs
similarity index 99%
rename from TGCommandLine/RepoCommands.cs
rename to TGS.CommandLine/RepoCommands.cs
index 9e3fe3e658..a24a26d68f 100644
--- a/TGCommandLine/RepoCommands.cs
+++ b/TGS.CommandLine/RepoCommands.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class RepoCommand : RootCommand
{
diff --git a/TGCommandLine/RootCommands.cs b/TGS.CommandLine/RootCommands.cs
similarity index 97%
rename from TGCommandLine/RootCommands.cs
rename to TGS.CommandLine/RootCommands.cs
index 6394224cd7..de6edae4ac 100644
--- a/TGCommandLine/RootCommands.cs
+++ b/TGS.CommandLine/RootCommands.cs
@@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
class CLICommand : RootCommand
{
- public CLICommand(IInterface I)
+ public CLICommand(IServerInterface I)
{
var tmp = new List { new UpdateCommand(), new TestmergeCommand(), new RepoCommand(), new BYONDCommand(), new DMCommand(), new DDCommand(), new ConfigCommand(), new IRCCommand(), new DiscordCommand(), new AutoUpdateCommand(), new SetAutoUpdateCommand() };
if (I.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator))
diff --git a/TGCommandLine/ServiceCommands.cs b/TGS.CommandLine/ServiceCommands.cs
similarity index 97%
rename from TGCommandLine/ServiceCommands.cs
rename to TGS.CommandLine/ServiceCommands.cs
index a52cd40dec..833469d0c8 100644
--- a/TGCommandLine/ServiceCommands.cs
+++ b/TGS.CommandLine/ServiceCommands.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGCommandLine
+namespace TGS.CommandLine
{
///
/// Used for managing the components
@@ -316,7 +316,7 @@ namespace TGCommandLine
}
///
- /// Command for calling
+ /// Command for calling
///
class ServiceRemoteAccessPortCommand : ConsoleCommand
{
@@ -343,7 +343,7 @@ namespace TGCommandLine
}
///
- /// Command for calling
+ /// Command for calling
///
class ServiceSetRemoteAccessPortCommand : ConsoleCommand
{
diff --git a/TGCommandLine/TGCommandLine.csproj b/TGS.CommandLine/TGS.CommandLine.csproj
similarity index 92%
rename from TGCommandLine/TGCommandLine.csproj
rename to TGS.CommandLine/TGS.CommandLine.csproj
index b228dbaccc..a4086c5979 100644
--- a/TGCommandLine/TGCommandLine.csproj
+++ b/TGS.CommandLine/TGS.CommandLine.csproj
@@ -6,7 +6,7 @@
AnyCPU
{89191F69-B18E-4B59-B72E-E12F9B6811A0}
Exe
- TGCommandLine
+ TGS.CommandLine
TGCommandLine
v4.5.2
512
@@ -31,7 +31,7 @@
bin\Release\
TRACE
- bin\x86\Release\TGCommandLine.xml
+ bin\x86\Release\TGS.CommandLine.xml
true
true
pdbonly
@@ -63,9 +63,9 @@
-
+
{ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}
- TGServiceInterface
+ TGS.Interface
diff --git a/TGCommandLine/tgs.ico b/TGS.CommandLine/tgs.ico
similarity index 100%
rename from TGCommandLine/tgs.ico
rename to TGS.CommandLine/tgs.ico
diff --git a/TGControlPanel/App.config b/TGS.ControlPanel/App.config
similarity index 82%
rename from TGControlPanel/App.config
rename to TGS.ControlPanel/App.config
index 16dd5b3a27..f753d0fbb0 100644
--- a/TGControlPanel/App.config
+++ b/TGS.ControlPanel/App.config
@@ -3,8 +3,8 @@
-
-
+
+
@@ -13,7 +13,7 @@
-
+
0
@@ -50,12 +50,12 @@
-
-
+
+
0
-
+
https://github.com/tgstation/tgstation.git
diff --git a/TGControlPanel/ControlPanel/ByondPage.cs b/TGS.ControlPanel/ControlPanel/ByondPage.cs
similarity index 96%
rename from TGControlPanel/ControlPanel/ByondPage.cs
rename to TGS.ControlPanel/ControlPanel/ByondPage.cs
index 1e65d7daa2..4935b7b3e4 100644
--- a/TGControlPanel/ControlPanel/ByondPage.cs
+++ b/TGS.ControlPanel/ControlPanel/ByondPage.cs
@@ -1,9 +1,9 @@
using System;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class ControlPanel
{
diff --git a/TGControlPanel/ControlPanel/ChatPage.cs b/TGS.ControlPanel/ControlPanel/ChatPage.cs
similarity index 98%
rename from TGControlPanel/ControlPanel/ChatPage.cs
rename to TGS.ControlPanel/ControlPanel/ChatPage.cs
index bea75efbff..96a666d5c6 100644
--- a/TGControlPanel/ControlPanel/ChatPage.cs
+++ b/TGS.ControlPanel/ControlPanel/ChatPage.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class ControlPanel
{
diff --git a/TGControlPanel/ControlPanel/ControlPanel.Designer.cs b/TGS.ControlPanel/ControlPanel/ControlPanel.Designer.cs
similarity index 99%
rename from TGControlPanel/ControlPanel/ControlPanel.Designer.cs
rename to TGS.ControlPanel/ControlPanel/ControlPanel.Designer.cs
index 2091401f42..ba5d05108f 100644
--- a/TGControlPanel/ControlPanel/ControlPanel.Designer.cs
+++ b/TGS.ControlPanel/ControlPanel/ControlPanel.Designer.cs
@@ -1,4 +1,4 @@
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class ControlPanel
{
diff --git a/TGControlPanel/ControlPanel/ControlPanel.cs b/TGS.ControlPanel/ControlPanel/ControlPanel.cs
similarity index 89%
rename from TGControlPanel/ControlPanel/ControlPanel.cs
rename to TGS.ControlPanel/ControlPanel/ControlPanel.cs
index 5e88c8f0c1..eff20b2e33 100644
--- a/TGControlPanel/ControlPanel/ControlPanel.cs
+++ b/TGS.ControlPanel/ControlPanel/ControlPanel.cs
@@ -2,10 +2,10 @@
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
///
/// The main form
@@ -18,15 +18,15 @@ namespace TGControlPanel
public static IDictionary InstancesInUse { get; private set; } = new Dictionary();
///
- /// The instance for this
+ /// The instance for this
///
- readonly IInterface Interface;
+ readonly IServerInterface Interface;
///
/// Constructs a
///
- /// The for the
- public ControlPanel(IInterface I)
+ /// The for the
+ public ControlPanel(IServerInterface I)
{
InitializeComponent();
FormClosed += ControlPanel_FormClosed;
diff --git a/TGControlPanel/ControlPanel/ControlPanel.resx b/TGS.ControlPanel/ControlPanel/ControlPanel.resx
similarity index 100%
rename from TGControlPanel/ControlPanel/ControlPanel.resx
rename to TGS.ControlPanel/ControlPanel/ControlPanel.resx
diff --git a/TGControlPanel/ControlPanel/RepoPage.cs b/TGS.ControlPanel/ControlPanel/RepoPage.cs
similarity index 99%
rename from TGControlPanel/ControlPanel/RepoPage.cs
rename to TGS.ControlPanel/ControlPanel/RepoPage.cs
index 6e99c62277..c6b5658e9d 100644
--- a/TGControlPanel/ControlPanel/RepoPage.cs
+++ b/TGS.ControlPanel/ControlPanel/RepoPage.cs
@@ -2,10 +2,10 @@
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class ControlPanel
{
diff --git a/TGControlPanel/ControlPanel/ServerPage.cs b/TGS.ControlPanel/ControlPanel/ServerPage.cs
similarity index 99%
rename from TGControlPanel/ControlPanel/ServerPage.cs
rename to TGS.ControlPanel/ControlPanel/ServerPage.cs
index 10b5363383..406b402fd4 100644
--- a/TGControlPanel/ControlPanel/ServerPage.cs
+++ b/TGS.ControlPanel/ControlPanel/ServerPage.cs
@@ -5,10 +5,10 @@ using System.ComponentModel;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class ControlPanel
{
diff --git a/TGControlPanel/ControlPanel/StaticPage.cs b/TGS.ControlPanel/ControlPanel/StaticPage.cs
similarity index 99%
rename from TGControlPanel/ControlPanel/StaticPage.cs
rename to TGS.ControlPanel/ControlPanel/StaticPage.cs
index f944570837..0d53e7b680 100644
--- a/TGControlPanel/ControlPanel/StaticPage.cs
+++ b/TGS.ControlPanel/ControlPanel/StaticPage.cs
@@ -2,10 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class ControlPanel
{
diff --git a/TGControlPanel/CountedForm.cs b/TGS.ControlPanel/CountedForm.cs
similarity index 97%
rename from TGControlPanel/CountedForm.cs
rename to TGS.ControlPanel/CountedForm.cs
index 37d7df2607..03ac979ab5 100644
--- a/TGControlPanel/CountedForm.cs
+++ b/TGS.ControlPanel/CountedForm.cs
@@ -1,6 +1,6 @@
using System.Windows.Forms;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
///
/// Calls when all s are d
diff --git a/TGControlPanel/GithubLoginPrompt.Designer.cs b/TGS.ControlPanel/GithubLoginPrompt.Designer.cs
similarity index 99%
rename from TGControlPanel/GithubLoginPrompt.Designer.cs
rename to TGS.ControlPanel/GithubLoginPrompt.Designer.cs
index 04df96ab1a..6035c273a7 100644
--- a/TGControlPanel/GithubLoginPrompt.Designer.cs
+++ b/TGS.ControlPanel/GithubLoginPrompt.Designer.cs
@@ -1,4 +1,4 @@
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class GitHubLoginPrompt
{
diff --git a/TGControlPanel/GithubLoginPrompt.cs b/TGS.ControlPanel/GithubLoginPrompt.cs
similarity index 96%
rename from TGControlPanel/GithubLoginPrompt.cs
rename to TGS.ControlPanel/GithubLoginPrompt.cs
index a90c7353cc..8d676d1646 100644
--- a/TGControlPanel/GithubLoginPrompt.cs
+++ b/TGS.ControlPanel/GithubLoginPrompt.cs
@@ -2,9 +2,9 @@
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
///
/// Used for recieving a GitHub API key for use in
@@ -76,7 +76,7 @@ namespace TGControlPanel
try
{
client.Credentials = new Credentials(UsernameTextBox.Text, PasswordTextBox.Text);
- var token = await client.Authorization.Create(new NewAuthorization { Note = "TGControlPanel token to bypass rate limiting" });
+ var token = await client.Authorization.Create(new NewAuthorization { Note = "TGS.ControlPanel token to bypass rate limiting" });
APIKey = token.Token;
}
catch (AuthorizationException)
diff --git a/TGControlPanel/GithubLoginPrompt.resx b/TGS.ControlPanel/GithubLoginPrompt.resx
similarity index 100%
rename from TGControlPanel/GithubLoginPrompt.resx
rename to TGS.ControlPanel/GithubLoginPrompt.resx
diff --git a/TGControlPanel/InstanceSelector.Designer.cs b/TGS.ControlPanel/InstanceSelector.Designer.cs
similarity index 99%
rename from TGControlPanel/InstanceSelector.Designer.cs
rename to TGS.ControlPanel/InstanceSelector.Designer.cs
index cfaf0a5ab5..87ce1038b7 100644
--- a/TGControlPanel/InstanceSelector.Designer.cs
+++ b/TGS.ControlPanel/InstanceSelector.Designer.cs
@@ -1,4 +1,4 @@
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class InstanceSelector
{
diff --git a/TGControlPanel/InstanceSelector.cs b/TGS.ControlPanel/InstanceSelector.cs
similarity index 95%
rename from TGControlPanel/InstanceSelector.cs
rename to TGS.ControlPanel/InstanceSelector.cs
index 3be9cde5ad..504b2218b9 100644
--- a/TGControlPanel/InstanceSelector.cs
+++ b/TGS.ControlPanel/InstanceSelector.cs
@@ -2,10 +2,10 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
///
/// Form used for managing manipulation functions
@@ -13,9 +13,9 @@ namespace TGControlPanel
sealed partial class InstanceSelector : CountedForm
{
///
- /// The we build instance connections from
+ /// The we build instance connections from
///
- readonly IInterface masterInterface;
+ readonly IServerInterface masterInterface;
///
/// List of from
///
@@ -28,8 +28,8 @@ namespace TGControlPanel
///
/// Construct an
///
- /// An connected a the
- public InstanceSelector(IInterface I)
+ /// An connected a the
+ public InstanceSelector(IServerInterface I)
{
InitializeComponent();
InstanceListBox.MouseDoubleClick += InstanceListBox_MouseDoubleClick;
@@ -100,7 +100,7 @@ namespace TGControlPanel
activeCP.BringToFront();
return;
}
- var InstanceAccessor = new Interface(masterInterface as Interface);
+ var InstanceAccessor = new ServerInterface(masterInterface as ServerInterface);
try
{
ConnectivityLevel res = ConnectivityLevel.None;
diff --git a/TGControlPanel/InstanceSelector.resx b/TGS.ControlPanel/InstanceSelector.resx
similarity index 100%
rename from TGControlPanel/InstanceSelector.resx
rename to TGS.ControlPanel/InstanceSelector.resx
diff --git a/TGControlPanel/Login.Designer.cs b/TGS.ControlPanel/Login.Designer.cs
similarity index 99%
rename from TGControlPanel/Login.Designer.cs
rename to TGS.ControlPanel/Login.Designer.cs
index ab89ca606b..2e7a9afbc6 100644
--- a/TGControlPanel/Login.Designer.cs
+++ b/TGS.ControlPanel/Login.Designer.cs
@@ -1,4 +1,4 @@
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class Login
{
diff --git a/TGControlPanel/Login.cs b/TGS.ControlPanel/Login.cs
similarity index 90%
rename from TGControlPanel/Login.cs
rename to TGS.ControlPanel/Login.cs
index 364746a652..4897e5260d 100644
--- a/TGControlPanel/Login.cs
+++ b/TGS.ControlPanel/Login.cs
@@ -1,8 +1,8 @@
using System;
using System.Windows.Forms;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
sealed partial class Login : CountedForm
{
@@ -31,7 +31,7 @@ namespace TGControlPanel
{
IPTextBox.Text = IPTextBox.Text.Trim();
UsernameTextBox.Text = UsernameTextBox.Text.Trim();
- using (var I = new Interface(IPTextBox.Text, (ushort)PortSelector.Value, UsernameTextBox.Text, PasswordTextBox.Text))
+ using (var I = new ServerInterface(IPTextBox.Text, (ushort)PortSelector.Value, UsernameTextBox.Text, PasswordTextBox.Text))
{
var Config = Properties.Settings.Default;
Config.RemoteIP = IPTextBox.Text;
@@ -55,10 +55,10 @@ namespace TGControlPanel
private void LocalLoginButton_Click(object sender, EventArgs e)
{
Properties.Settings.Default.RemoteDefault = false;
- VerifyAndConnect(new Interface());
+ VerifyAndConnect(new ServerInterface());
}
- void VerifyAndConnect(IInterface I)
+ void VerifyAndConnect(IServerInterface I)
{
try
{
diff --git a/TGControlPanel/Login.resx b/TGS.ControlPanel/Login.resx
similarity index 100%
rename from TGControlPanel/Login.resx
rename to TGS.ControlPanel/Login.resx
diff --git a/TGControlPanel/Program.cs b/TGS.ControlPanel/Program.cs
similarity index 96%
rename from TGControlPanel/Program.cs
rename to TGS.ControlPanel/Program.cs
index b484dbc88f..c0598cbdd9 100644
--- a/TGControlPanel/Program.cs
+++ b/TGS.ControlPanel/Program.cs
@@ -1,9 +1,9 @@
using System;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
static class Program
{
@@ -20,7 +20,7 @@ namespace TGControlPanel
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
- Interface.SetBadCertificateHandler(BadCertificateHandler);
+ ServerInterface.SetBadCertificateHandler(BadCertificateHandler);
var login = new Login();
login.Show();
Application.Run();
diff --git a/TGControlPanel/Properties/AssemblyInfo.cs b/TGS.ControlPanel/Properties/AssemblyInfo.cs
similarity index 97%
rename from TGControlPanel/Properties/AssemblyInfo.cs
rename to TGS.ControlPanel/Properties/AssemblyInfo.cs
index 8b5fb88ca1..1f05bee96e 100644
--- a/TGControlPanel/Properties/AssemblyInfo.cs
+++ b/TGS.ControlPanel/Properties/AssemblyInfo.cs
@@ -1,16 +1,16 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TGStation Server Control Panel")]
-[assembly: AssemblyDescription("Control panel for the TG Station Server Service")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("394e7643-6b8c-416f-ab18-95ac12648cdc")]
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TGStation Server Control Panel")]
+[assembly: AssemblyDescription("Control panel for the TG Station Server Service")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("394e7643-6b8c-416f-ab18-95ac12648cdc")]
diff --git a/TGControlPanel/Properties/Settings.Designer.cs b/TGS.ControlPanel/Properties/Settings.Designer.cs
similarity index 99%
rename from TGControlPanel/Properties/Settings.Designer.cs
rename to TGS.ControlPanel/Properties/Settings.Designer.cs
index 86ec264975..50131930ce 100644
--- a/TGControlPanel/Properties/Settings.Designer.cs
+++ b/TGS.ControlPanel/Properties/Settings.Designer.cs
@@ -8,7 +8,7 @@
//
//------------------------------------------------------------------------------
-namespace TGControlPanel.Properties {
+namespace TGS.ControlPanel.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
diff --git a/TGControlPanel/Properties/Settings.settings b/TGS.ControlPanel/Properties/Settings.settings
similarity index 95%
rename from TGControlPanel/Properties/Settings.settings
rename to TGS.ControlPanel/Properties/Settings.settings
index 54c6fc8cd4..2a1efd2454 100644
--- a/TGControlPanel/Properties/Settings.settings
+++ b/TGS.ControlPanel/Properties/Settings.settings
@@ -1,5 +1,5 @@
-
+
diff --git a/TGControlPanel/ServerOpForm.cs b/TGS.ControlPanel/ServerOpForm.cs
similarity index 64%
rename from TGControlPanel/ServerOpForm.cs
rename to TGS.ControlPanel/ServerOpForm.cs
index 06099fd819..d3843c7c2b 100644
--- a/TGControlPanel/ServerOpForm.cs
+++ b/TGS.ControlPanel/ServerOpForm.cs
@@ -2,10 +2,10 @@
using System.Threading.Tasks;
using System.Windows.Forms;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
///
- /// Used to provide an ATP function for calls into an
+ /// Used to provide an ATP function for calls into an
///
#if !DEBUG
abstract class ServerOpForm : Form
@@ -14,9 +14,9 @@ namespace TGControlPanel
#endif
{
///
- /// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor
+ /// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor
///
- /// The operation to wrap
+ /// The operation to wrap
/// A wrapping
protected Task WrapServerOp(Action action)
{
diff --git a/TGControlPanel/TGControlPanel.csproj b/TGS.ControlPanel/TGS.ControlPanel.csproj
similarity index 95%
rename from TGControlPanel/TGControlPanel.csproj
rename to TGS.ControlPanel/TGS.ControlPanel.csproj
index fb3db6a4a6..8866aebb61 100644
--- a/TGControlPanel/TGControlPanel.csproj
+++ b/TGS.ControlPanel/TGS.ControlPanel.csproj
@@ -6,7 +6,7 @@
AnyCPU
{394E7643-6B8C-416F-AB18-95AC12648CDC}
WinExe
- TGControlPanel
+ TGS.ControlPanel
TGControlPanel
v4.5.2
512
@@ -30,7 +30,7 @@
bin\Release\
TRACE
- bin\x86\Release\TGControlPanel.xml
+ bin\x86\Release\TGS.ControlPanel.xml
true
true
pdbonly
@@ -139,9 +139,9 @@
-
+
{ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}
- TGServiceInterface
+ TGS.Interface
diff --git a/TGControlPanel/TestMergeManager.Designer.cs b/TGS.ControlPanel/TestMergeManager.Designer.cs
similarity index 99%
rename from TGControlPanel/TestMergeManager.Designer.cs
rename to TGS.ControlPanel/TestMergeManager.Designer.cs
index ab229d5fdd..e73ba3944e 100644
--- a/TGControlPanel/TestMergeManager.Designer.cs
+++ b/TGS.ControlPanel/TestMergeManager.Designer.cs
@@ -1,4 +1,4 @@
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
partial class TestMergeManager
{
diff --git a/TGControlPanel/TestMergeManager.cs b/TGS.ControlPanel/TestMergeManager.cs
similarity index 96%
rename from TGControlPanel/TestMergeManager.cs
rename to TGS.ControlPanel/TestMergeManager.cs
index d04e598c73..f609142431 100644
--- a/TGControlPanel/TestMergeManager.cs
+++ b/TGS.ControlPanel/TestMergeManager.cs
@@ -4,10 +4,10 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGControlPanel
+namespace TGS.ControlPanel
{
sealed partial class TestMergeManager : ServerOpForm
{
@@ -17,9 +17,9 @@ namespace TGControlPanel
const string MergedPullsError = "Error retrieving currently merged pull requests: {0}";
///
- /// The connected to an to handle the pull requests for
+ /// The connected to an to handle the pull requests for
///
- readonly IInterface currentInterface;
+ readonly IServerInterface currentInterface;
///
/// The to use to read PR lists
@@ -38,9 +38,9 @@ namespace TGControlPanel
///
/// Construct a
///
- /// The to use for managing the
+ /// The to use for managing the
/// The to use for getting pull request information
- public TestMergeManager(IInterface interfaceToUse, GitHubClient clientToUse)
+ public TestMergeManager(IServerInterface interfaceToUse, GitHubClient clientToUse)
{
InitializeComponent();
DialogResult = DialogResult.Cancel;
diff --git a/TGControlPanel/TestMergeManager.resx b/TGS.ControlPanel/TestMergeManager.resx
similarity index 100%
rename from TGControlPanel/TestMergeManager.resx
rename to TGS.ControlPanel/TestMergeManager.resx
diff --git a/TGControlPanel/packages.config b/TGS.ControlPanel/packages.config
similarity index 100%
rename from TGControlPanel/packages.config
rename to TGS.ControlPanel/packages.config
diff --git a/TGControlPanel/tgs.ico b/TGS.ControlPanel/tgs.ico
similarity index 100%
rename from TGControlPanel/tgs.ico
rename to TGS.ControlPanel/tgs.ico
diff --git a/TGInstallerWrapper/App.config b/TGS.Installer.UI/App.config
similarity index 100%
rename from TGInstallerWrapper/App.config
rename to TGS.Installer.UI/App.config
diff --git a/TGInstallerWrapper/FodyWeavers.xml b/TGS.Installer.UI/FodyWeavers.xml
similarity index 100%
rename from TGInstallerWrapper/FodyWeavers.xml
rename to TGS.Installer.UI/FodyWeavers.xml
diff --git a/TGInstallerWrapper/Main.Designer.cs b/TGS.Installer.UI/Main.Designer.cs
similarity index 99%
rename from TGInstallerWrapper/Main.Designer.cs
rename to TGS.Installer.UI/Main.Designer.cs
index 885db27148..0ed1cf9dec 100644
--- a/TGInstallerWrapper/Main.Designer.cs
+++ b/TGS.Installer.UI/Main.Designer.cs
@@ -2,7 +2,7 @@
using System.Diagnostics;
using System.Reflection;
-namespace TGInstallerWrapper
+namespace TGS.Installer.UI
{
partial class Main
{
diff --git a/TGInstallerWrapper/Main.cs b/TGS.Installer.UI/Main.cs
similarity index 73%
rename from TGInstallerWrapper/Main.cs
rename to TGS.Installer.UI/Main.cs
index c796238fd3..8abcdca084 100644
--- a/TGInstallerWrapper/Main.cs
+++ b/TGS.Installer.UI/Main.cs
@@ -6,10 +6,11 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
+using TGS.Server;
-namespace TGInstallerWrapper
+namespace TGS.Installer.UI
{
partial class Main : Form
{
@@ -19,8 +20,17 @@ namespace TGInstallerWrapper
bool installing = false;
bool cancelled = false;
bool pathIsDefault = true;
+ ///
+ /// If we should attempt to make a for the new install
+ ///
+ bool attemptNetSettingsMigration = false;
+ ///
+ /// If the service we are upgrading is confirmed to be less than version 3.2
+ ///
+ bool isUnderV2 = false;
- IInterface Interface;
+
+ IServerInterface Interface;
///
/// Construct an installer form
@@ -69,17 +79,21 @@ namespace TGInstallerWrapper
}
void CheckForExistingVersion() {
- Interface = new Interface();
+ Interface = new ServerInterface();
var verifiedConnection = Interface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator);
try
{
VersionLabel.Text = Interface.GetServiceComponent().Version();
- var isV0 = VersionLabel.Text.Contains("v3.0");
+ var splits = VersionLabel.Text.Split(' ');
+ var realVersion = new Version(splits[splits.Length - 1].Substring(1));
+ var isV0 = realVersion < new Version(3, 1, 0, 0);
if (isV0) //OH GOD!!!!
MessageBox.Show("Upgrading from version 3.0 may trigger a bug that can delete /config and /data. IT IS STRONGLY RECCOMMENDED THAT YOU BACKUP THESE FOLDERS BEFORE UPDATING!", "Warning");
- if (isV0 || VersionLabel.Text.Contains("v3.1"))
+ isUnderV2 = isV0 || realVersion < new Version(3, 2, 0, 0);
+ if (isUnderV2)
//Friendly reminger
MessageBox.Show("Upgrading to service version 3.2 will break the 3.1 DMAPI. It is recommended you update your game to the 3.2 API before updating the servive to avoid having to trigger hard restarts.", "Note");
+ attemptNetSettingsMigration = realVersion < new Version(3, 2, 1, 0);
}
catch
{
@@ -142,6 +156,39 @@ namespace TGInstallerWrapper
return PKillType.NoneFound;
}
+ ///
+ /// Migrate to the new since the won't know about it until it's upgraded
+ ///
+ void AttemptMigrationOfNetSettings()
+ {
+ if (!attemptNetSettingsMigration)
+ return;
+ var sc = new ServerConfig();
+ try
+ {
+ sc.PythonPath = Interface.GetServiceComponent().PythonPath();
+ }
+ catch { }
+ try
+ {
+ sc.RemoteAccessPort = Interface.GetServiceComponent().RemoteAccessPort();
+ }
+ catch { }
+ try
+ {
+ foreach (var I in Interface.GetServiceComponent().ListInstances())
+ sc.InstancePaths.Add(I.Path);
+ }
+ catch { }
+
+
+ if (sc.InstancePaths.Count == 0 && isUnderV2)
+ //add the default ip as a last resort
+ sc.InstancePaths.Add("C:\\TGSTATION-SERVER-3"); //normalized
+
+ sc.Save(Server.Server.MigrationConfigDirectory);
+ }
+
async void DoInstall()
{
string logfile = null;
@@ -149,12 +196,12 @@ namespace TGInstallerWrapper
{
while (true)
{
- var res = PromptKillProcesses("TGCommandLine");
+ var res = PromptKillProcesses("TGS.CommandLine");
if (res == PKillType.Aborted)
return;
else if (res == PKillType.Killed)
continue;
- res = PromptKillProcesses("TGControlPanel");
+ res = PromptKillProcesses("TGS.ControlPanel");
if (res == PKillType.Aborted)
return;
else if (res == PKillType.Killed)
@@ -183,8 +230,10 @@ namespace TGInstallerWrapper
ShowLogCheckbox.Enabled = false;
InstallButton.Text = "Installing...";
- var msipath = Path.Combine(tempDir, "TGServiceInstaller.msi");
- File.WriteAllBytes(msipath, Properties.Resources.TGServiceInstaller);
+ AttemptMigrationOfNetSettings();
+
+ var msipath = Path.Combine(tempDir, "TGS.Installer.msi");
+ File.WriteAllBytes(msipath, Properties.Resources.TGSInstaller);
File.WriteAllBytes(Path.Combine(tempDir, "cab1.cab"), Properties.Resources.cab1);
ProgressBar.Style = ProgressBarStyle.Marquee;
@@ -193,13 +242,13 @@ namespace TGInstallerWrapper
if (ShowLogCheckbox.Checked)
{
logfile = Path.Combine(tempDir, "tgsinstall.log");
- Installer.EnableLog(InstallLogModes.Verbose | InstallLogModes.PropertyDump, logfile);
+ Microsoft.Deployment.WindowsInstaller.Installer.EnableLog(InstallLogModes.Verbose | InstallLogModes.PropertyDump, logfile);
}
var cl = String.Join(" ", args);
- Installer.SetInternalUI(InstallUIOptions.Silent);
- Installer.SetExternalUI(OnUIUpdate, InstallLogModes.Progress);
+ Microsoft.Deployment.WindowsInstaller.Installer.SetInternalUI(InstallUIOptions.Silent);
+ Microsoft.Deployment.WindowsInstaller.Installer.SetExternalUI(OnUIUpdate, InstallLogModes.Progress);
- await Task.Factory.StartNew(() => Installer.InstallProduct(msipath, cl));
+ await Task.Factory.StartNew(() => Microsoft.Deployment.WindowsInstaller.Installer.InstallProduct(msipath, cl));
if (cancelled)
{
diff --git a/TGInstallerWrapper/Main.resx b/TGS.Installer.UI/Main.resx
similarity index 100%
rename from TGInstallerWrapper/Main.resx
rename to TGS.Installer.UI/Main.resx
diff --git a/TGInstallerWrapper/Program.cs b/TGS.Installer.UI/Program.cs
similarity index 91%
rename from TGInstallerWrapper/Program.cs
rename to TGS.Installer.UI/Program.cs
index 96dc421f86..851a948e3b 100644
--- a/TGInstallerWrapper/Program.cs
+++ b/TGS.Installer.UI/Program.cs
@@ -1,7 +1,7 @@
using System;
using System.Windows.Forms;
-namespace TGInstallerWrapper
+namespace TGS.Installer.UI
{
static class Program
{
diff --git a/TGInstallerWrapper/Properties/AssemblyInfo.cs b/TGS.Installer.UI/Properties/AssemblyInfo.cs
similarity index 100%
rename from TGInstallerWrapper/Properties/AssemblyInfo.cs
rename to TGS.Installer.UI/Properties/AssemblyInfo.cs
diff --git a/TGInstallerWrapper/Properties/Resources.Designer.cs b/TGS.Installer.UI/Properties/Resources.Designer.cs
similarity index 91%
rename from TGInstallerWrapper/Properties/Resources.Designer.cs
rename to TGS.Installer.UI/Properties/Resources.Designer.cs
index cd95f1bb4f..9a0670c601 100644
--- a/TGInstallerWrapper/Properties/Resources.Designer.cs
+++ b/TGS.Installer.UI/Properties/Resources.Designer.cs
@@ -8,7 +8,7 @@
//
//------------------------------------------------------------------------------
-namespace TGInstallerWrapper.Properties {
+namespace TGS.Installer.UI.Properties {
using System;
@@ -39,7 +39,7 @@ namespace TGInstallerWrapper.Properties {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TGInstallerWrapper.Properties.Resources", typeof(Resources).Assembly);
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TGS.Installer.UI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
@@ -73,9 +73,9 @@ namespace TGInstallerWrapper.Properties {
///
/// Looks up a localized resource of type System.Byte[].
///
- internal static byte[] TGServiceInstaller {
+ internal static byte[] TGSInstaller {
get {
- object obj = ResourceManager.GetObject("TGServiceInstaller", resourceCulture);
+ object obj = ResourceManager.GetObject("TGSInstaller", resourceCulture);
return ((byte[])(obj));
}
}
diff --git a/TGInstallerWrapper/Properties/Resources.resx b/TGS.Installer.UI/Properties/Resources.resx
similarity index 93%
rename from TGInstallerWrapper/Properties/Resources.resx
rename to TGS.Installer.UI/Properties/Resources.resx
index 223c76093a..7e63714e76 100644
--- a/TGInstallerWrapper/Properties/Resources.resx
+++ b/TGS.Installer.UI/Properties/Resources.resx
@@ -119,9 +119,9 @@
- ..\..\TGServiceInstaller\bin\Release\cab1.cab;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ ..\..\TGS.Installer\bin\Release\cab1.cab;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- ..\..\TGServiceInstaller\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ ..\..\TGS.Installer\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
\ No newline at end of file
diff --git a/TGInstallerWrapper/TGInstallerWrapper.csproj b/TGS.Installer.UI/TGS.Installer.UI.csproj
similarity index 93%
rename from TGInstallerWrapper/TGInstallerWrapper.csproj
rename to TGS.Installer.UI/TGS.Installer.UI.csproj
index d84f79b22a..fc0fcb0870 100644
--- a/TGInstallerWrapper/TGInstallerWrapper.csproj
+++ b/TGS.Installer.UI/TGS.Installer.UI.csproj
@@ -6,7 +6,7 @@
AnyCPU
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}
WinExe
- TGInstallerWrapper
+ TGS.Installer.UI
TG Station Server Installer
v4.5.2
512
@@ -89,9 +89,13 @@
-
+
{ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}
- TGServiceInterface
+ TGS.Interface
+
+
+ {f32eda25-0855-411c-af5e-f0d042917e2d}
+ TGS.Server
diff --git a/TGInstallerWrapper/app.manifest b/TGS.Installer.UI/app.manifest
similarity index 100%
rename from TGInstallerWrapper/app.manifest
rename to TGS.Installer.UI/app.manifest
diff --git a/TGInstallerWrapper/packages.config b/TGS.Installer.UI/packages.config
similarity index 100%
rename from TGInstallerWrapper/packages.config
rename to TGS.Installer.UI/packages.config
diff --git a/TGInstallerWrapper/tgs.ico b/TGS.Installer.UI/tgs.ico
similarity index 100%
rename from TGInstallerWrapper/tgs.ico
rename to TGS.Installer.UI/tgs.ico
diff --git a/TGServiceInstaller/Product.wxs b/TGS.Installer/Product.wxs
similarity index 71%
rename from TGServiceInstaller/Product.wxs
rename to TGS.Installer/Product.wxs
index d188e2477d..dfb6546fce 100644
--- a/TGServiceInstaller/Product.wxs
+++ b/TGS.Installer/Product.wxs
@@ -1,152 +1,155 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Installed AND NOT UPGRADINGPRODUCTCODE
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- INSTALLSHORTCUTDESK = 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Installed AND NOT UPGRADINGPRODUCTCODE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INSTALLSHORTCUTDESK = 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TGServiceInstaller/TGServiceInstaller.wixproj b/TGS.Installer/TGS.Installer.wixproj
similarity index 80%
rename from TGServiceInstaller/TGServiceInstaller.wixproj
rename to TGS.Installer/TGS.Installer.wixproj
index c2985570e2..bc81125088 100644
--- a/TGServiceInstaller/TGServiceInstaller.wixproj
+++ b/TGS.Installer/TGS.Installer.wixproj
@@ -1,90 +1,98 @@
-
-
-
- Debug
- x86
- 3.10
- 154435f6-0890-42d4-9aec-b743d4fbc1cb
- 2.0
- TGServiceInstaller
- Package
-
-
- bin\$(Configuration)\
- obj\$(Configuration)\
- Debug
-
-
- bin\$(Configuration)\
- obj\$(Configuration)\
- True
- True
-
-
-
-
-
-
- TGControlPanel
- {394e7643-6b8c-416f-ab18-95ac12648cdc}
- True
- True
- Binaries;Content;Satellites
- INSTALLFOLDER
-
-
- TGCommandLine
- {89191f69-b18e-4b59-b72e-e12f9b6811a0}
- True
- True
- Binaries;Content;Satellites
- INSTALLFOLDER
-
-
- TGDreamDaemonBridge
- {9a01ef03-8eae-45cb-8b87-4a17bd904557}
- True
- True
- Binaries;Content;Satellites
- INSTALLFOLDER
-
-
- TGServerService
- {f32eda25-0855-411c-af5e-f0d042917e2d}
- True
- True
- Binaries;Content;Satellites
- INSTALLFOLDER
-
-
- TGServiceInterface
- {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}
- True
- True
- Binaries;Content;Satellites
- INSTALLFOLDER
-
-
-
-
-
-
-
-
-
-
-
- powershell -Command "& \"$(SolutionDir)Tools/SignBasics.ps1\""
-
-
- powershell -Command "& \"$(SolutionDir)Tools/SignMSI.ps1\""
-
-
-
+
+
+
+ Debug
+ x86
+ 3.10
+ 154435f6-0890-42d4-9aec-b743d4fbc1cb
+ 2.0
+ TGServiceInstaller
+ Package
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+ Debug
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+ True
+ True
+
+
+
+
+
+
+ TGS.ControlPanel
+ {394e7643-6b8c-416f-ab18-95ac12648cdc}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+ TGS.CommandLine
+ {89191f69-b18e-4b59-b72e-e12f9b6811a0}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+ TGS.Interface.Bridge
+ {9a01ef03-8eae-45cb-8b87-4a17bd904557}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+ TGS.Server.Service
+ {3f81e398-b223-4006-b40c-c2800714ce29}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+ TGS.Server
+ {f32eda25-0855-411c-af5e-f0d042917e2d}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+ TGS.Interface
+ {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+
+
+
+
+
+
+
+
+
+ powershell -Command "& \"$(SolutionDir)Tools/SignBasics.ps1\""
+
+
+ powershell -Command "& \"$(SolutionDir)Tools/SignMSI.ps1\""
+
+
+
\ No newline at end of file
diff --git a/TGDreamDaemonBridge/DreamDaemonBridge.cs b/TGS.Interface.Bridge/DreamDaemonBridge.cs
similarity index 89%
rename from TGDreamDaemonBridge/DreamDaemonBridge.cs
rename to TGS.Interface.Bridge/DreamDaemonBridge.cs
index 003e9b6b9b..7a6795c39a 100644
--- a/TGDreamDaemonBridge/DreamDaemonBridge.cs
+++ b/TGS.Interface.Bridge/DreamDaemonBridge.cs
@@ -2,10 +2,10 @@ using RGiesecke.DllExport;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGDreamDaemonBridge
+namespace TGS.Interface.Bridge
{
///
/// Holds the proc that DD calls to access
@@ -27,7 +27,7 @@ namespace TGDreamDaemonBridge
parsedArgs.AddRange(args);
var instance = parsedArgs[0];
parsedArgs.RemoveAt(0);
- using (var I = new Interface())
+ using (var I = new ServerInterface())
if(I.ConnectToInstance(instance, true).HasFlag(ConnectivityLevel.Connected))
I.GetComponent().InteropMessage(String.Join(" ", parsedArgs));
}
diff --git a/TGDreamDaemonBridge/FodyWeavers.xml b/TGS.Interface.Bridge/FodyWeavers.xml
similarity index 100%
rename from TGDreamDaemonBridge/FodyWeavers.xml
rename to TGS.Interface.Bridge/FodyWeavers.xml
diff --git a/TGDreamDaemonBridge/Properties/AssemblyInfo.cs b/TGS.Interface.Bridge/Properties/AssemblyInfo.cs
similarity index 100%
rename from TGDreamDaemonBridge/Properties/AssemblyInfo.cs
rename to TGS.Interface.Bridge/Properties/AssemblyInfo.cs
diff --git a/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj b/TGS.Interface.Bridge/TGS.Interface.Bridge.csproj
similarity index 95%
rename from TGDreamDaemonBridge/TGDreamDaemonBridge.csproj
rename to TGS.Interface.Bridge/TGS.Interface.Bridge.csproj
index 0cb0c67596..d960e47808 100644
--- a/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj
+++ b/TGS.Interface.Bridge/TGS.Interface.Bridge.csproj
@@ -7,7 +7,7 @@
{9A01EF03-8EAE-45CB-8B87-4A17BD904557}
Library
Properties
- TGDreamDaemonBridge
+ TGS.Interface.Bridge
TGDreamDaemonBridge
v4.5.2
512
@@ -59,9 +59,9 @@
-
+
{ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}
- TGServiceInterface
+ TGS.Interface
diff --git a/TGDreamDaemonBridge/packages.config b/TGS.Interface.Bridge/packages.config
similarity index 100%
rename from TGDreamDaemonBridge/packages.config
rename to TGS.Interface.Bridge/packages.config
diff --git a/TGServiceInterface/ChatSetupInfo.cs b/TGS.Interface/ChatSetupInfo.cs
similarity index 96%
rename from TGServiceInterface/ChatSetupInfo.cs
rename to TGS.Interface/ChatSetupInfo.cs
index 1f2d0d1967..6a1c346d2b 100644
--- a/TGServiceInterface/ChatSetupInfo.cs
+++ b/TGS.Interface/ChatSetupInfo.cs
@@ -1,344 +1,344 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Web.Script.Serialization;
-
-namespace TGServiceInterface
-{
- ///
- /// For setting up authentication no matter the chat provider
- ///
- [DataContract]
- [KnownType(typeof(IRCSetupInfo))]
- [KnownType(typeof(DiscordSetupInfo))]
- public class ChatSetupInfo
- {
- const int AdminListIndex = 0;
- const int AdminModeIndex = 1;
- const int AdminChannelIndex = 2;
- const int DevChannelIndex = 3;
- const int WDChannelIndex = 4;
- const int GameChannelIndex = 5;
- const int ProviderIndex = 6;
- const int EnabledIndex = 7;
- ///
- /// Starting index of which child classes should use to write their custom data to
- ///
- protected const int BaseIndex = 8;
- ///
- /// Set to if a child constructor should use the baseInfo parameter of to initialize it's property fields, otherwise
- ///
- protected readonly bool InitializeFields;
-
- ///
- /// Raw access to the underlying data
- ///
- [DataMember]
- public IList DataFields { get; protected set; }
-
- ///
- /// Constructs a from optional
- ///
- /// The that this is for
- /// Optional past data
- /// The number of fields in this chat provider
- protected internal ChatSetupInfo(ChatProvider provider, ChatSetupInfo baseInfo, int numFields)
- {
- numFields += BaseIndex;
- InitializeFields = baseInfo == null || baseInfo.DataFields.Count != numFields;
-
- if (InitializeFields)
- {
- DataFields = new List(numFields);
- for (var I = 0; I < numFields; ++I)
- DataFields.Add(null);
-
- AdminList = new List();
- AdminChannels = new List();
- DevChannels = new List();
- GameChannels = new List();
- WatchdogChannels = new List();
- AdminsAreSpecial = false;
- Enabled = false;
- }
- else
- DataFields = baseInfo.DataFields;
- Provider = provider;
- Specialize(true); //to check we have a valid provider
- }
-
- ///
- /// Recreates as the correct child
- ///
- /// If , is returned provided is a valid
- /// A new based on the type
- ChatSetupInfo Specialize(bool checkOnly)
- {
- switch (Provider)
- {
- case ChatProvider.IRC:
- if (!checkOnly)
- return new IRCSetupInfo(this);
- break;
- case ChatProvider.Discord:
- if (!checkOnly)
- return new DiscordSetupInfo(this);
- break;
- default:
- throw new Exception("Invalid provider!");
- }
- return null;
- }
-
- ///
- /// Properly formats a name for the
- ///
- /// The to format
- /// The formatted
- protected virtual string SanitizeChannelName(string channel)
- {
- return Specialize(false).SanitizeChannelName(channel);
- }
-
- ///
- /// Sanitizes a list of
- ///
- /// A of strings
- void SanitizeChannelNames(IList channelnames)
- {
- for (var I = 0; I < channelnames.Count; ++I)
-
- if (String.IsNullOrWhiteSpace(channelnames[I]))
- {
- channelnames.RemoveAt(I);
- --I;
- }
- else
- channelnames[I] = SanitizeChannelName(channelnames[I].Trim());
- }
-
- ///
- /// Constructs a from a data list
- ///
- /// The data
- public ChatSetupInfo(IList DeserializedData)
- {
- DataFields = DeserializedData;
- Specialize(false); //ensure provider type is valid
- }
- ///
- /// The list of admin entries
- ///
- public List AdminList
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminListIndex]); }
- set { DataFields[AdminListIndex] = new JavaScriptSerializer().Serialize(value); }
- }
- ///
- /// If AdminList corresponds to a Provider specific recognization method
- ///
- public bool AdminsAreSpecial
- {
- get { return Convert.ToBoolean(DataFields[AdminModeIndex]); }
- set { DataFields[AdminModeIndex] = Convert.ToString(value); }
- }
- ///
- /// The channels from which admin commands/messages can be sent/received
- ///
- public List AdminChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[AdminChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// The channels to which repo and compile messages are sent
- ///
- public List DevChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[DevChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[DevChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// The channels to which watchdog messages are sent
- ///
- public List WatchdogChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[WDChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[WDChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// The channels to which game messages are sent
- ///
- public List GameChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[GameChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[GameChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// If this chat provider is enabled
- ///
- public bool Enabled
- {
- get { return Convert.ToBoolean(DataFields[EnabledIndex]); }
- set { DataFields[EnabledIndex] = Convert.ToString(value); }
- }
-
- ///
- /// The type of provider
- ///
- public ChatProvider Provider
- {
- get { return (ChatProvider)Convert.ToInt32(DataFields[ProviderIndex]); }
- set { DataFields[ProviderIndex] = Convert.ToString((int)value); }
- }
- }
-
- ///
- /// Chat provider for IRC. Admin entries should be user nicknames in normal mode or required channel flags in special mode
- ///
- [DataContract]
- public sealed class IRCSetupInfo : ChatSetupInfo
- {
- const int URLIndex = 0;
- const int PortIndex = 1;
- const int NickIndex = 2;
- const int AuthTargetIndex = 3;
- const int AuthMessageIndex = 4;
- const int AuthLevelIndex = 5;
- const int FieldsLen = 6;
-
- ///
- /// Construct IRC setup info from optional generic info. Defaults to TGS3 on rizons IRC server
- ///
- /// Optional generic info
- public IRCSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.IRC, baseInfo, FieldsLen)
- {
- if (!InitializeFields)
- return;
-
- Nickname = "TGS3";
- URL = "irc.rizon.net";
- Port = 6667;
- AuthTarget = "";
- AuthMessage = "";
- AdminsAreSpecial = true;
- AuthLevel = IRCMode.Op;
- }
-
- ///
- protected override string SanitizeChannelName(string working)
- {
- if (working[0] != '#')
- return "#" + working;
- return working;
- }
-
- ///
- /// The port of the IRC server
- ///
- public ushort Port
- {
- get { return Convert.ToUInt16(DataFields[BaseIndex + PortIndex]); }
- set { DataFields[BaseIndex + PortIndex] = value.ToString(); }
- }
- ///
- /// The URL of the IRC server
- ///
- public string URL
- {
- get { return DataFields[BaseIndex + URLIndex]; }
- set { DataFields[BaseIndex + URLIndex] = value; }
- }
- ///
- /// The nickname of the IRC bot
- ///
- public string Nickname
- {
- get { return DataFields[BaseIndex + NickIndex]; }
- set { DataFields[BaseIndex + NickIndex] = value; }
- }
- ///
- /// The target for sending authentication messages
- ///
- public string AuthTarget
- {
- get { return DataFields[BaseIndex + AuthTargetIndex]; }
- set { DataFields[BaseIndex + AuthTargetIndex] = value; }
- }
- ///
- /// The authentication message
- ///
- public string AuthMessage
- {
- get { return DataFields[BaseIndex + AuthMessageIndex]; }
- set { DataFields[BaseIndex + AuthMessageIndex] = value; }
- }
- ///
- /// The minimum mode required to use admin bot commands when in special auth mode
- ///
- public IRCMode AuthLevel
- {
- get { return (IRCMode)Convert.ToInt32(DataFields[BaseIndex + AuthLevelIndex]); }
- set { DataFields[BaseIndex + AuthLevelIndex] = Convert.ToString((int)value); }
- }
- }
-
- ///
- /// Chat provider for Discord. Admin entires should be user ids in normal mode or group ids in special mode
- ///
- [DataContract]
- public sealed class DiscordSetupInfo : ChatSetupInfo
- {
- const int BotTokenIndex = 0;
- const int FieldsLen = 1;
- ///
- /// Construct Discord setup info from optional generic info. Default is not a valid discord bot tokent
- ///
- /// Optional generic info
- public DiscordSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.Discord, baseInfo, FieldsLen)
- {
- if (!InitializeFields)
- return;
- BotToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //needless to say, this is fake
- }
- ///
- protected override string SanitizeChannelName(string working)
- {
- working = working.Replace("<", "").Replace(">", "").Replace("&", ""); //filter out some stuff that can come in the copypasta
- try
- {
- Convert.ToUInt64(working);
- }
- catch
- {
- throw new Exception("Invalid Discord channel ID!");
- }
- return working;
- }
-
- ///
- /// The Discord bot token to use. See https://discordapp.com/developers/applications/me for registering bot accounts
- ///
- public string BotToken
- {
- get { return DataFields[BaseIndex + BotTokenIndex]; }
- set { DataFields[BaseIndex + BotTokenIndex] = value; }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Web.Script.Serialization;
+
+namespace TGS.Interface
+{
+ ///
+ /// For setting up authentication no matter the chat provider
+ ///
+ [DataContract]
+ [KnownType(typeof(IRCSetupInfo))]
+ [KnownType(typeof(DiscordSetupInfo))]
+ public class ChatSetupInfo
+ {
+ const int AdminListIndex = 0;
+ const int AdminModeIndex = 1;
+ const int AdminChannelIndex = 2;
+ const int DevChannelIndex = 3;
+ const int WDChannelIndex = 4;
+ const int GameChannelIndex = 5;
+ const int ProviderIndex = 6;
+ const int EnabledIndex = 7;
+ ///
+ /// Starting index of which child classes should use to write their custom data to
+ ///
+ protected const int BaseIndex = 8;
+ ///
+ /// Set to if a child constructor should use the baseInfo parameter of to initialize it's property fields, otherwise
+ ///
+ protected readonly bool InitializeFields;
+
+ ///
+ /// Raw access to the underlying data
+ ///
+ [DataMember]
+ public IList DataFields { get; protected set; }
+
+ ///
+ /// Constructs a from optional
+ ///
+ /// The that this is for
+ /// Optional past data
+ /// The number of fields in this chat provider
+ protected internal ChatSetupInfo(ChatProvider provider, ChatSetupInfo baseInfo, int numFields)
+ {
+ numFields += BaseIndex;
+ InitializeFields = baseInfo == null || baseInfo.DataFields.Count != numFields;
+
+ if (InitializeFields)
+ {
+ DataFields = new List(numFields);
+ for (var I = 0; I < numFields; ++I)
+ DataFields.Add(null);
+
+ AdminList = new List();
+ AdminChannels = new List();
+ DevChannels = new List();
+ GameChannels = new List();
+ WatchdogChannels = new List();
+ AdminsAreSpecial = false;
+ Enabled = false;
+ }
+ else
+ DataFields = baseInfo.DataFields;
+ Provider = provider;
+ Specialize(true); //to check we have a valid provider
+ }
+
+ ///
+ /// Recreates as the correct child
+ ///
+ /// If , is returned provided is a valid
+ /// A new based on the type
+ ChatSetupInfo Specialize(bool checkOnly)
+ {
+ switch (Provider)
+ {
+ case ChatProvider.IRC:
+ if (!checkOnly)
+ return new IRCSetupInfo(this);
+ break;
+ case ChatProvider.Discord:
+ if (!checkOnly)
+ return new DiscordSetupInfo(this);
+ break;
+ default:
+ throw new Exception("Invalid provider!");
+ }
+ return null;
+ }
+
+ ///
+ /// Properly formats a name for the
+ ///
+ /// The to format
+ /// The formatted
+ protected virtual string SanitizeChannelName(string channel)
+ {
+ return Specialize(false).SanitizeChannelName(channel);
+ }
+
+ ///
+ /// Sanitizes a list of
+ ///
+ /// A of strings
+ void SanitizeChannelNames(IList channelnames)
+ {
+ for (var I = 0; I < channelnames.Count; ++I)
+
+ if (String.IsNullOrWhiteSpace(channelnames[I]))
+ {
+ channelnames.RemoveAt(I);
+ --I;
+ }
+ else
+ channelnames[I] = SanitizeChannelName(channelnames[I].Trim());
+ }
+
+ ///
+ /// Constructs a from a data list
+ ///
+ /// The data
+ public ChatSetupInfo(IList DeserializedData)
+ {
+ DataFields = DeserializedData;
+ Specialize(false); //ensure provider type is valid
+ }
+ ///
+ /// The list of admin entries
+ ///
+ public List AdminList
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminListIndex]); }
+ set { DataFields[AdminListIndex] = new JavaScriptSerializer().Serialize(value); }
+ }
+ ///
+ /// If AdminList corresponds to a Provider specific recognization method
+ ///
+ public bool AdminsAreSpecial
+ {
+ get { return Convert.ToBoolean(DataFields[AdminModeIndex]); }
+ set { DataFields[AdminModeIndex] = Convert.ToString(value); }
+ }
+ ///
+ /// The channels from which admin commands/messages can be sent/received
+ ///
+ public List AdminChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[AdminChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// The channels to which repo and compile messages are sent
+ ///
+ public List DevChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[DevChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[DevChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// The channels to which watchdog messages are sent
+ ///
+ public List WatchdogChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[WDChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[WDChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// The channels to which game messages are sent
+ ///
+ public List GameChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[GameChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[GameChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// If this chat provider is enabled
+ ///
+ public bool Enabled
+ {
+ get { return Convert.ToBoolean(DataFields[EnabledIndex]); }
+ set { DataFields[EnabledIndex] = Convert.ToString(value); }
+ }
+
+ ///
+ /// The type of provider
+ ///
+ public ChatProvider Provider
+ {
+ get { return (ChatProvider)Convert.ToInt32(DataFields[ProviderIndex]); }
+ set { DataFields[ProviderIndex] = Convert.ToString((int)value); }
+ }
+ }
+
+ ///
+ /// Chat provider for IRC. Admin entries should be user nicknames in normal mode or required channel flags in special mode
+ ///
+ [DataContract]
+ public sealed class IRCSetupInfo : ChatSetupInfo
+ {
+ const int URLIndex = 0;
+ const int PortIndex = 1;
+ const int NickIndex = 2;
+ const int AuthTargetIndex = 3;
+ const int AuthMessageIndex = 4;
+ const int AuthLevelIndex = 5;
+ const int FieldsLen = 6;
+
+ ///
+ /// Construct IRC setup info from optional generic info. Defaults to TGS3 on rizons IRC server
+ ///
+ /// Optional generic info
+ public IRCSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.IRC, baseInfo, FieldsLen)
+ {
+ if (!InitializeFields)
+ return;
+
+ Nickname = "TGS3";
+ URL = "irc.rizon.net";
+ Port = 6667;
+ AuthTarget = "";
+ AuthMessage = "";
+ AdminsAreSpecial = true;
+ AuthLevel = IRCMode.Op;
+ }
+
+ ///
+ protected override string SanitizeChannelName(string working)
+ {
+ if (working[0] != '#')
+ return "#" + working;
+ return working;
+ }
+
+ ///
+ /// The port of the IRC server
+ ///
+ public ushort Port
+ {
+ get { return Convert.ToUInt16(DataFields[BaseIndex + PortIndex]); }
+ set { DataFields[BaseIndex + PortIndex] = value.ToString(); }
+ }
+ ///
+ /// The URL of the IRC server
+ ///
+ public string URL
+ {
+ get { return DataFields[BaseIndex + URLIndex]; }
+ set { DataFields[BaseIndex + URLIndex] = value; }
+ }
+ ///
+ /// The nickname of the IRC bot
+ ///
+ public string Nickname
+ {
+ get { return DataFields[BaseIndex + NickIndex]; }
+ set { DataFields[BaseIndex + NickIndex] = value; }
+ }
+ ///
+ /// The target for sending authentication messages
+ ///
+ public string AuthTarget
+ {
+ get { return DataFields[BaseIndex + AuthTargetIndex]; }
+ set { DataFields[BaseIndex + AuthTargetIndex] = value; }
+ }
+ ///
+ /// The authentication message
+ ///
+ public string AuthMessage
+ {
+ get { return DataFields[BaseIndex + AuthMessageIndex]; }
+ set { DataFields[BaseIndex + AuthMessageIndex] = value; }
+ }
+ ///
+ /// The minimum mode required to use admin bot commands when in special auth mode
+ ///
+ public IRCMode AuthLevel
+ {
+ get { return (IRCMode)Convert.ToInt32(DataFields[BaseIndex + AuthLevelIndex]); }
+ set { DataFields[BaseIndex + AuthLevelIndex] = Convert.ToString((int)value); }
+ }
+ }
+
+ ///
+ /// Chat provider for Discord. Admin entires should be user ids in normal mode or group ids in special mode
+ ///
+ [DataContract]
+ public sealed class DiscordSetupInfo : ChatSetupInfo
+ {
+ const int BotTokenIndex = 0;
+ const int FieldsLen = 1;
+ ///
+ /// Construct Discord setup info from optional generic info. Default is not a valid discord bot tokent
+ ///
+ /// Optional generic info
+ public DiscordSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.Discord, baseInfo, FieldsLen)
+ {
+ if (!InitializeFields)
+ return;
+ BotToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //needless to say, this is fake
+ }
+ ///
+ protected override string SanitizeChannelName(string working)
+ {
+ working = working.Replace("<", "").Replace(">", "").Replace("&", ""); //filter out some stuff that can come in the copypasta
+ try
+ {
+ Convert.ToUInt64(working);
+ }
+ catch
+ {
+ throw new Exception("Invalid Discord channel ID!");
+ }
+ return working;
+ }
+
+ ///
+ /// The Discord bot token to use. See https://discordapp.com/developers/applications/me for registering bot accounts
+ ///
+ public string BotToken
+ {
+ get { return DataFields[BaseIndex + BotTokenIndex]; }
+ set { DataFields[BaseIndex + BotTokenIndex] = value; }
+ }
+ }
+}
diff --git a/TGServiceInterface/Command.cs b/TGS.Interface/Command.cs
similarity index 99%
rename from TGServiceInterface/Command.cs
rename to TGS.Interface/Command.cs
index 5355a0d55e..ac64ab1914 100644
--- a/TGServiceInterface/Command.cs
+++ b/TGS.Interface/Command.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Threading;
-namespace TGServiceInterface
+namespace TGS.Interface
{
///
/// Helper for creating a text tree
diff --git a/TGServiceInterface/Components/Administration.cs b/TGS.Interface/Components/Administration.cs
similarity index 97%
rename from TGServiceInterface/Components/Administration.cs
rename to TGS.Interface/Components/Administration.cs
index b177312820..884c5b725a 100644
--- a/TGServiceInterface/Components/Administration.cs
+++ b/TGS.Interface/Components/Administration.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Manage the group that is used to access the service, can only be used by an administrator
diff --git a/TGServiceInterface/Components/Byond.cs b/TGS.Interface/Components/Byond.cs
similarity index 97%
rename from TGServiceInterface/Components/Byond.cs
rename to TGS.Interface/Components/Byond.cs
index d640179d6c..7563000999 100644
--- a/TGServiceInterface/Components/Byond.cs
+++ b/TGS.Interface/Components/Byond.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
diff --git a/TGServiceInterface/Components/Chat.cs b/TGS.Interface/Components/Chat.cs
similarity index 97%
rename from TGServiceInterface/Components/Chat.cs
rename to TGS.Interface/Components/Chat.cs
index e52659d3f7..5333e4e649 100644
--- a/TGServiceInterface/Components/Chat.cs
+++ b/TGS.Interface/Components/Chat.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Interface for handling chat bot
diff --git a/TGServiceInterface/Components/Compiler.cs b/TGS.Interface/Components/Compiler.cs
similarity index 98%
rename from TGServiceInterface/Components/Compiler.cs
rename to TGS.Interface/Components/Compiler.cs
index f5b261fb62..ce87ff125e 100644
--- a/TGServiceInterface/Components/Compiler.cs
+++ b/TGS.Interface/Components/Compiler.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// For managing the Game A/B/Live folders, compiling, and hotswapping them
diff --git a/TGServiceInterface/Components/Config.cs b/TGS.Interface/Components/Config.cs
similarity index 98%
rename from TGServiceInterface/Components/Config.cs
rename to TGS.Interface/Components/Config.cs
index 1055352aad..5b33051d0d 100644
--- a/TGServiceInterface/Components/Config.cs
+++ b/TGS.Interface/Components/Config.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// For modifying the in game config
diff --git a/TGServiceInterface/Components/Connectivity.cs b/TGS.Interface/Components/Connectivity.cs
similarity index 91%
rename from TGServiceInterface/Components/Connectivity.cs
rename to TGS.Interface/Components/Connectivity.cs
index d3077d3dd9..d7c5b57f64 100644
--- a/TGServiceInterface/Components/Connectivity.cs
+++ b/TGS.Interface/Components/Connectivity.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Used for testing connections to the service without authentication
diff --git a/TGServiceInterface/Components/DreamDaemon.cs b/TGS.Interface/Components/DreamDaemon.cs
similarity index 99%
rename from TGServiceInterface/Components/DreamDaemon.cs
rename to TGS.Interface/Components/DreamDaemon.cs
index b21fdda493..0892e3f8a1 100644
--- a/TGServiceInterface/Components/DreamDaemon.cs
+++ b/TGS.Interface/Components/DreamDaemon.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
diff --git a/TGServiceInterface/Components/Instance.cs b/TGS.Interface/Components/Instance.cs
similarity index 93%
rename from TGServiceInterface/Components/Instance.cs
rename to TGS.Interface/Components/Instance.cs
index c4c771d4ef..1cc79e153b 100644
--- a/TGServiceInterface/Components/Instance.cs
+++ b/TGS.Interface/Components/Instance.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Metadata for a server instance
diff --git a/TGServiceInterface/Components/InstanceManager.cs b/TGS.Interface/Components/InstanceManager.cs
similarity index 98%
rename from TGServiceInterface/Components/InstanceManager.cs
rename to TGS.Interface/Components/InstanceManager.cs
index 3467c009c1..f148acb644 100644
--- a/TGServiceInterface/Components/InstanceManager.cs
+++ b/TGS.Interface/Components/InstanceManager.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Used for managing s
diff --git a/TGServiceInterface/Components/Interop.cs b/TGS.Interface/Components/Interop.cs
similarity index 93%
rename from TGServiceInterface/Components/Interop.cs
rename to TGS.Interface/Components/Interop.cs
index e57e74cb08..80dc2c7c7c 100644
--- a/TGServiceInterface/Components/Interop.cs
+++ b/TGS.Interface/Components/Interop.cs
@@ -1,6 +1,6 @@
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Used by DreamDaemon to access the interop API with call()(). Restrictions are in place so that only a DreamDaemon instance launched by the service can use this API
diff --git a/TGServiceInterface/Components/Landing.cs b/TGS.Interface/Components/Landing.cs
similarity index 94%
rename from TGServiceInterface/Components/Landing.cs
rename to TGS.Interface/Components/Landing.cs
index a1d18c8c88..da7cd28b9e 100644
--- a/TGServiceInterface/Components/Landing.cs
+++ b/TGS.Interface/Components/Landing.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Used for general authentication and listing s
diff --git a/TGServiceInterface/Components/Repository.cs b/TGS.Interface/Components/Repository.cs
similarity index 99%
rename from TGServiceInterface/Components/Repository.cs
rename to TGS.Interface/Components/Repository.cs
index 9e0f83105e..f9a395a915 100644
--- a/TGServiceInterface/Components/Repository.cs
+++ b/TGS.Interface/Components/Repository.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Interface for managing the code repository
diff --git a/TGServiceInterface/Components/Service.cs b/TGS.Interface/Components/Service.cs
similarity index 97%
rename from TGServiceInterface/Components/Service.cs
rename to TGS.Interface/Components/Service.cs
index d9fecd397f..17fc5f7096 100644
--- a/TGServiceInterface/Components/Service.cs
+++ b/TGS.Interface/Components/Service.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.ServiceModel;
-namespace TGServiceInterface.Components
+namespace TGS.Interface.Components
{
///
/// Interface for managing the service
diff --git a/TGServiceInterface/Enumerations.cs b/TGS.Interface/Enumerations.cs
similarity index 99%
rename from TGServiceInterface/Enumerations.cs
rename to TGS.Interface/Enumerations.cs
index 5f65b463b0..b1d9586769 100644
--- a/TGServiceInterface/Enumerations.cs
+++ b/TGS.Interface/Enumerations.cs
@@ -1,6 +1,6 @@
using System;
-namespace TGServiceInterface
+namespace TGS.Interface
{
///
/// Description of the connectivity level to an or the
diff --git a/TGServiceInterface/Helpers.cs b/TGS.Interface/Helpers.cs
similarity index 98%
rename from TGServiceInterface/Helpers.cs
rename to TGS.Interface/Helpers.cs
index 471d84ccfd..a7780a1aba 100644
--- a/TGServiceInterface/Helpers.cs
+++ b/TGS.Interface/Helpers.cs
@@ -2,7 +2,7 @@
using System.Security.Cryptography;
using System.Text;
-namespace TGServiceInterface
+namespace TGS.Interface
{
///
/// Helper functions used across the server suite
diff --git a/TGServiceInterface/InstanceMetadata.cs b/TGS.Interface/InstanceMetadata.cs
similarity index 83%
rename from TGServiceInterface/InstanceMetadata.cs
rename to TGS.Interface/InstanceMetadata.cs
index 5a08e5b355..8b3e73fa6e 100644
--- a/TGServiceInterface/InstanceMetadata.cs
+++ b/TGS.Interface/InstanceMetadata.cs
@@ -1,11 +1,12 @@
using System.Runtime.Serialization;
-namespace TGServiceInterface
+namespace TGS.Interface
{
///
/// Metadata about an
///
- [DataContract]
+ //Namespace required for compatibility reasons
+ [DataContract(Namespace = "http://schemas.datacontract.org/2004/07/TGServiceInterface")]
public sealed class InstanceMetadata
{
///
diff --git a/TGServiceInterface/Properties/AssemblyInfo.cs b/TGS.Interface/Properties/AssemblyInfo.cs
similarity index 98%
rename from TGServiceInterface/Properties/AssemblyInfo.cs
rename to TGS.Interface/Properties/AssemblyInfo.cs
index 1e86b8b310..c9d6fe7641 100644
--- a/TGServiceInterface/Properties/AssemblyInfo.cs
+++ b/TGS.Interface/Properties/AssemblyInfo.cs
@@ -1,16 +1,16 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TGStation Server Service Interface")]
-[assembly: AssemblyDescription("Used by user programs to access the TGStation Server Service")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab")]
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TGStation Server Service Interface")]
+[assembly: AssemblyDescription("Used by user programs to access the TGStation Server Service")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab")]
diff --git a/TGServiceInterface/PullRequestInfo.cs b/TGS.Interface/PullRequestInfo.cs
similarity index 97%
rename from TGServiceInterface/PullRequestInfo.cs
rename to TGS.Interface/PullRequestInfo.cs
index 6f6635ab7b..58eab112ff 100644
--- a/TGServiceInterface/PullRequestInfo.cs
+++ b/TGS.Interface/PullRequestInfo.cs
@@ -1,6 +1,6 @@
using System.Runtime.Serialization;
-namespace TGServiceInterface
+namespace TGS.Interface
{
///
/// Information about a pull request
diff --git a/TGServiceInterface/RootCommand.cs b/TGS.Interface/RootCommand.cs
similarity index 99%
rename from TGServiceInterface/RootCommand.cs
rename to TGS.Interface/RootCommand.cs
index 90b26f352e..129c772478 100644
--- a/TGServiceInterface/RootCommand.cs
+++ b/TGS.Interface/RootCommand.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace TGServiceInterface
+namespace TGS.Interface
{
///
/// Helper for creating commands that contain sub commands
diff --git a/TGServiceInterface/Interface.cs b/TGS.Interface/ServerInterface.cs
similarity index 88%
rename from TGServiceInterface/Interface.cs
rename to TGS.Interface/ServerInterface.cs
index 15823014d8..e92e630e19 100644
--- a/TGServiceInterface/Interface.cs
+++ b/TGS.Interface/ServerInterface.cs
@@ -1,500 +1,500 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Net;
-using System.Net.Security;
-using System.Reflection;
-using System.Security.Principal;
-using System.ServiceModel;
-using TGServiceInterface.Components;
-
-namespace TGServiceInterface
-{
- ///
- /// Main for communicating the
- ///
- public interface IInterface : IDisposable
- {
- ///
- /// The name of the current instance in use. Defaults to
- ///
- string InstanceName { get; }
-
- ///
- /// If this is set, we will try and connect to an HTTPS server running at this address
- ///
- string HTTPSURL { get; }
-
- ///
- /// The port used to connect to the
- ///
- ushort HTTPSPort { get; }
-
- ///
- /// Checks if the is setup for a remote connection
- ///
- bool IsRemoteConnection { get; }
-
- ///
- /// Targets as the instance to use with . Closes all connections to any previous instance
- ///
- /// The name of the instance to connect to
- /// If set to , skips the connectivity and authentication checks, sets , and returns
- /// The apporopriate
- ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false);
-
- ///
- /// Returns if the interface being used to connect to a service does not have the same release version as the service
- ///
- /// An error message to display to the user should this function return
- /// if the interface being used to connect to a service does not have the same release version as the service
- bool VersionMismatch(out string errorMessage);
-
- ///
- /// Returns the requested component for the instance . This does not guarantee a successful connection.
- ///
- /// The component to retrieve
- /// The correct component
- T GetComponent();
-
- ///
- /// Returns a root service component
- ///
- /// The component for the service
- T GetServiceComponent();
-
- ///
- /// Used to test if the is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors
- ///
- /// on successful connection, error message on failure
- ConnectivityLevel ConnectionStatus();
-
- ///
- /// Used to test if the is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors
- ///
- /// String of the error that prevented an elevated connectivity level
- /// The apporopriate
- ConnectivityLevel ConnectionStatus(out string error);
- }
-
- ///
- sealed public class Interface : IInterface
- {
- ///
- /// List of s that can be used with
- ///
- public static readonly IList ValidServiceInterfaces = new List { typeof(ITGSService), typeof(ITGInstanceManager), typeof(ITGConnectivity), typeof(ITGLanding) };
-
- ///
- /// List of s that can be used with
- ///
- public static readonly IList ValidInstanceInterfaces = CollectComponents();
-
- ///
- /// The maximum message size to and from a local server
- ///
- public const long TransferLimitLocal = Int32.MaxValue; //2GB can't go higher
-
- ///
- /// The maximum message size to and from a remote server
- ///
- public const long TransferLimitRemote = 10485760; //10 MB
-
- ///
- /// Base name of communication URLs
- ///
- public const string MasterInterfaceName = "TGStationServerService";
- ///
- /// Base name of instance URLs
- ///
- public const string InstanceInterfaceName = MasterInterfaceName + "/Instance";
-
- ///
- public string InstanceName { get; private set; }
-
- ///
- /// If this is set, we will try and connect to an HTTPS server running at this address
- ///
- readonly string _HTTPSURL;
-
- ///
- public string HTTPSURL { get { return _HTTPSURL; } }
-
- ///
- /// The port used to connect to the
- ///
- readonly ushort _HTTPSPort;
-
- ///
- public ushort HTTPSPort { get { return _HTTPSPort; } }
-
- ///
- /// Username for remote operations
- ///
- readonly string HTTPSUsername;
-
- ///
- /// Password for remote operations
- ///
- readonly string HTTPSPassword;
-
- ///
- /// Associated list of open s keyed by type name. A in this list may close or fault at any time. Must be locked before being accessed
- ///
- IDictionary ChannelFactoryCache = new Dictionary();
-
- ///
- /// Returns a of s that can be used with the service
- ///
- /// A of s that can be used with the service
- static IList CollectComponents()
- {
- var ConnectivityComponent = typeof(ITGConnectivity);
- //find all interfaces in this assembly in this namespace that have the service contract attribute
- var query = from t in Assembly.GetExecutingAssembly().GetTypes()
- where t.IsInterface
- && t.Namespace == ConnectivityComponent.Namespace
- && t.GetCustomAttribute(typeof(ServiceContractAttribute)) != null
- && (t == ConnectivityComponent || !ValidServiceInterfaces.Contains(t))
- select t;
- return query.ToList();
- }
-
- ///
- /// Sets the function called when a remote login fails due to the server having an invalid SSL cert
- ///
- /// The to be called when a remote login is attempted while the server posesses a bad certificate. Passed a of error information about the and should return if it the connection should be made anyway
- public static void SetBadCertificateHandler(Func handler)
- {
- ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
- {
- string ErrorMessage;
- switch (error)
- {
- case SslPolicyErrors.None:
- return true;
- case SslPolicyErrors.RemoteCertificateChainErrors:
- ErrorMessage = "There are certificate chain errors.";
- break;
- case SslPolicyErrors.RemoteCertificateNameMismatch:
- ErrorMessage = "The certificate name does not match.";
- break;
- case SslPolicyErrors.RemoteCertificateNotAvailable:
- ErrorMessage = "The certificate doesn't exist in the trust store.";
- break;
- default:
- ErrorMessage = "An unknown error occurred.";
- break;
- }
- ErrorMessage = String.Format("The server's certificate failed to verify! Error: {0} Cert: {1}", ErrorMessage, cert.ToString());
- return handler(ErrorMessage);
- };
- }
-
- ///
- /// Construct an for a local connection
- ///
- public Interface() { }
-
- ///
- /// Construct an for a remote connection
- ///
- /// The address of the remote server
- /// The port the remote server runs on
- /// Windows account username for the remote server
- /// Windows account password for the remote server
- public Interface(string address, ushort port, string username, string password)
- {
- _HTTPSURL = address;
- _HTTPSPort = port;
- HTTPSUsername = username;
- HTTPSPassword = password;
- }
-
- ///
- /// Constructs an that connects to the same as some
- ///
- /// Another to copy settings from
- public Interface(Interface other) : this(other.HTTPSURL, other.HTTPSPort, other.HTTPSUsername, other.HTTPSPassword) { }
-
- ///
- public ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false)
- {
- if (instanceName == null)
- instanceName = InstanceName;
- if (!skipChecks && !ConnectionStatus().HasFlag(ConnectivityLevel.Connected))
- return ConnectivityLevel.None;
- var prevInstance = InstanceName;
- if (prevInstance != instanceName)
- CloseAllChannels(false);
- InstanceName = instanceName;
- if (skipChecks)
- return ConnectivityLevel.Connected;
- try
- {
- GetComponent().VerifyConnection();
- }
- catch
- {
- InstanceName = prevInstance;
- return ConnectivityLevel.None;
- }
- try
- {
- GetComponent().ServerDirectory();
- }
- catch
- {
- return ConnectivityLevel.Connected;
- }
- try
- {
- GetComponent().GetCurrentAuthorizedGroup();
- return ConnectivityLevel.Administrator;
- }
- catch
- {
- return ConnectivityLevel.Authenticated;
- }
- }
-
- ///
- public bool IsRemoteConnection { get { return HTTPSURL != null; } }
-
- ///
- /// Closes all s stored in and clears it
- ///
- /// If set to , doesn't clear the channels that are used by
- void CloseAllChannels(bool includingRoot)
- {
- string[] RootThings = { typeof(ITGSService).Name, 'S' + typeof(ITGConnectivity).Name };
- lock (ChannelFactoryCache)
- {
- var toRemove = new List();
- foreach (var I in ChannelFactoryCache)
- {
- if (RootThings.Contains(I.Key))
- continue;
- var cf = I.Value;
- try
- {
- cf.Closed += ChannelFactory_Closed;
- cf.Close();
- }
- catch
- {
- cf.Abort();
- }
- toRemove.Add(I.Key);
- }
- foreach (var I in toRemove)
- ChannelFactoryCache.Remove(I);
- }
- }
-
- ///
- public bool VersionMismatch(out string errorMessage)
- {
- var splits = GetServiceComponent().Version().Split(' ');
- var theirs = new Version(splits[splits.Length - 1].Substring(1));
- var ours = new Version(FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion);
- if(theirs.Major != ours.Major || theirs.Minor != ours.Minor || theirs.Revision != ours.Revision) //don't care about the patch level
- {
- errorMessage = String.Format("Version mismatch between interface version ({0}) and service version ({1}). Some functionality may crash this program.", ours, theirs);
- return true;
- }
- errorMessage = null;
- return false;
- }
-
- ///
- /// Disposes a closed
- ///
- /// The channel factory that was closed
- /// The event arguments
- static void ChannelFactory_Closed(object sender, EventArgs e)
- {
- (sender as IDisposable).Dispose();
- }
-
- ///
- public T GetComponent()
- {
- var ToT = typeof(T);
- if (!ValidInstanceInterfaces.Contains(ToT))
- throw new Exception("Invalid type!");
- return GetComponentImpl(true);
- }
-
- ///
- /// Returns the requested component for the instance . This does not guarantee a successful connection. s created this way are recycled for minimum latency and bandwidth usage
- ///
- /// The component to retrieve
- /// If should be used to connect
- /// The correct component
- T GetComponentImpl(bool useInstanceName)
- {
- if (useInstanceName & InstanceName == null)
- throw new Exception("Instance not selected!");
- var actualToT = typeof(T);
- var tot = actualToT.Name;
- if (actualToT == typeof(ITGConnectivity) && !useInstanceName)
- tot = 'S' + tot;
- ChannelFactory cf;
-
- lock (ChannelFactoryCache)
- {
- if (ChannelFactoryCache.ContainsKey(tot))
- try
- {
- cf = ((ChannelFactory)ChannelFactoryCache[tot]);
- if (cf.State != CommunicationState.Opened)
- throw new Exception();
- return cf.CreateChannel();
- }
- catch
- {
- ChannelFactoryCache[tot].Abort();
- ChannelFactoryCache.Remove(tot);
- }
- cf = CreateChannel(useInstanceName ? InstanceName : null);
- ChannelFactoryCache[tot] = cf;
- }
- return cf.CreateChannel();
- }
-
- ///
- public T GetServiceComponent()
- {
- var ToT = typeof(T);
- if (!ValidServiceInterfaces.Contains(ToT))
- throw new Exception("Invalid type!");
- return GetComponentImpl(false);
- }
-
- ///
- /// Directly creates a for without caching. This should be eventually closed by the caller
- ///
- /// The component of the channel to be created
- /// The correct
- /// Thrown if isn't a valid component
- ChannelFactory CreateChannel(string instanceName)
- {
- var accessPath = instanceName == null ? MasterInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName);
-
- var InterfaceName = typeof(T).Name;
- if (!IsRemoteConnection)
- {
- var res2 = new ChannelFactory(
- new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = TransferLimitLocal }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", accessPath, InterfaceName))); //10 megs
- res2.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
- return res2;
- }
-
- //okay we're going over
- var binding = new WSHttpBinding()
- {
- SendTimeout = new TimeSpan(0, 0, 40),
- MaxReceivedMessageSize = TransferLimitRemote
- };
- var requireAuth = InterfaceName != typeof(ITGConnectivity).Name;
- binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
- binding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check
- binding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None;
- var address = new EndpointAddress(String.Format("https://{0}:{1}/{2}/{3}", HTTPSURL, HTTPSPort, accessPath, InterfaceName));
- var res = new ChannelFactory(binding, address);
- if (requireAuth)
- {
- res.Credentials.UserName.UserName = HTTPSUsername;
- res.Credentials.UserName.Password = HTTPSPassword;
- res.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
- }
- return res;
- }
-
- ///
- public ConnectivityLevel ConnectionStatus()
- {
- return ConnectionStatus(out string unused);
- }
-
- ///
- public ConnectivityLevel ConnectionStatus(out string error)
- {
- try
- {
- GetComponentImpl(false).VerifyConnection();
- }
- catch (CommunicationException e)
- {
- error = e.ToString();
- return ConnectivityLevel.None;
- }
- try
- {
- GetServiceComponent().Version();
- }
- catch(Exception e)
- {
- error = e.ToString();
- return ConnectivityLevel.Connected;
- }
- try
- {
- GetServiceComponent().Version();
- error = null;
- return ConnectivityLevel.Administrator;
- }
- catch(Exception e)
- {
- error = e.ToString();
- return ConnectivityLevel.Authenticated;
- }
- }
-
- #region IDisposable Support
- ///
- /// To detect redundant calls
- ///
- private bool disposedValue = false;
-
- ///
- /// Implements the pattern. Calls
- ///
- /// if was called manually, if it was from the finalizer
- void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- CloseAllChannels(true);
- }
-
- // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
- // TODO: set large fields to null.
-
- disposedValue = true;
- }
- }
-
- // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
- // ~Interface() {
- // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- // Dispose(false);
- // }
-
- ///
- /// Implements the pattern
- ///
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- Dispose(true);
- // TODO: uncomment the following line if the finalizer is overridden above.
- // GC.SuppressFinalize(this);
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Reflection;
+using System.Security.Principal;
+using System.ServiceModel;
+using TGS.Interface.Components;
+
+namespace TGS.Interface
+{
+ ///
+ /// Main for communicating the
+ ///
+ public interface IServerInterface : IDisposable
+ {
+ ///
+ /// The name of the current instance in use. Defaults to
+ ///
+ string InstanceName { get; }
+
+ ///
+ /// If this is set, we will try and connect to an HTTPS server running at this address
+ ///
+ string HTTPSURL { get; }
+
+ ///
+ /// The port used to connect to the
+ ///
+ ushort HTTPSPort { get; }
+
+ ///
+ /// Checks if the is setup for a remote connection
+ ///
+ bool IsRemoteConnection { get; }
+
+ ///
+ /// Targets as the instance to use with . Closes all connections to any previous instance
+ ///
+ /// The name of the instance to connect to
+ /// If set to , skips the connectivity and authentication checks, sets , and returns
+ /// The apporopriate
+ ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false);
+
+ ///
+ /// Returns if the interface being used to connect to a service does not have the same release version as the service
+ ///
+ /// An error message to display to the user should this function return
+ /// if the interface being used to connect to a service does not have the same release version as the service
+ bool VersionMismatch(out string errorMessage);
+
+ ///
+ /// Returns the requested component for the instance . This does not guarantee a successful connection.
+ ///
+ /// The component to retrieve
+ /// The correct component
+ T GetComponent();
+
+ ///
+ /// Returns a root service component
+ ///
+ /// The component for the service
+ T GetServiceComponent();
+
+ ///
+ /// Used to test if the is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors
+ ///
+ /// on successful connection, error message on failure
+ ConnectivityLevel ConnectionStatus();
+
+ ///
+ /// Used to test if the is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors
+ ///
+ /// String of the error that prevented an elevated connectivity level
+ /// The apporopriate
+ ConnectivityLevel ConnectionStatus(out string error);
+ }
+
+ ///
+ sealed public class ServerInterface : IServerInterface
+ {
+ ///
+ /// List of s that can be used with
+ ///
+ public static readonly IList ValidServiceInterfaces = new List { typeof(ITGSService), typeof(ITGInstanceManager), typeof(ITGConnectivity), typeof(ITGLanding) };
+
+ ///
+ /// List of s that can be used with
+ ///
+ public static readonly IList ValidInstanceInterfaces = CollectComponents();
+
+ ///
+ /// The maximum message size to and from a local server
+ ///
+ public const long TransferLimitLocal = Int32.MaxValue; //2GB can't go higher
+
+ ///
+ /// The maximum message size to and from a remote server
+ ///
+ public const long TransferLimitRemote = 10485760; //10 MB
+
+ ///
+ /// Base name of communication URLs
+ ///
+ public const string MasterInterfaceName = "TGStationServerService";
+ ///
+ /// Base name of instance URLs
+ ///
+ public const string InstanceInterfaceName = MasterInterfaceName + "/Instance";
+
+ ///
+ public string InstanceName { get; private set; }
+
+ ///
+ /// If this is set, we will try and connect to an HTTPS server running at this address
+ ///
+ readonly string _HTTPSURL;
+
+ ///
+ public string HTTPSURL { get { return _HTTPSURL; } }
+
+ ///
+ /// The port used to connect to the
+ ///
+ readonly ushort _HTTPSPort;
+
+ ///
+ public ushort HTTPSPort { get { return _HTTPSPort; } }
+
+ ///
+ /// Username for remote operations
+ ///
+ readonly string HTTPSUsername;
+
+ ///
+ /// Password for remote operations
+ ///
+ readonly string HTTPSPassword;
+
+ ///
+ /// Associated list of open s keyed by type name. A in this list may close or fault at any time. Must be locked before being accessed
+ ///
+ IDictionary ChannelFactoryCache = new Dictionary();
+
+ ///
+ /// Returns a of s that can be used with the service
+ ///
+ /// A of s that can be used with the service
+ static IList CollectComponents()
+ {
+ var ConnectivityComponent = typeof(ITGConnectivity);
+ //find all interfaces in this assembly in this namespace that have the service contract attribute
+ var query = from t in Assembly.GetExecutingAssembly().GetTypes()
+ where t.IsInterface
+ && t.Namespace == ConnectivityComponent.Namespace
+ && t.GetCustomAttribute(typeof(ServiceContractAttribute)) != null
+ && (t == ConnectivityComponent || !ValidServiceInterfaces.Contains(t))
+ select t;
+ return query.ToList();
+ }
+
+ ///
+ /// Sets the function called when a remote login fails due to the server having an invalid SSL cert
+ ///
+ /// The to be called when a remote login is attempted while the server posesses a bad certificate. Passed a of error information about the and should return if it the connection should be made anyway
+ public static void SetBadCertificateHandler(Func handler)
+ {
+ ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) =>
+ {
+ string ErrorMessage;
+ switch (error)
+ {
+ case SslPolicyErrors.None:
+ return true;
+ case SslPolicyErrors.RemoteCertificateChainErrors:
+ ErrorMessage = "There are certificate chain errors.";
+ break;
+ case SslPolicyErrors.RemoteCertificateNameMismatch:
+ ErrorMessage = "The certificate name does not match.";
+ break;
+ case SslPolicyErrors.RemoteCertificateNotAvailable:
+ ErrorMessage = "The certificate doesn't exist in the trust store.";
+ break;
+ default:
+ ErrorMessage = "An unknown error occurred.";
+ break;
+ }
+ ErrorMessage = String.Format("The server's certificate failed to verify! Error: {0} Cert: {1}", ErrorMessage, cert.ToString());
+ return handler(ErrorMessage);
+ };
+ }
+
+ ///
+ /// Construct an for a local connection
+ ///
+ public ServerInterface() { }
+
+ ///
+ /// Construct an for a remote connection
+ ///
+ /// The address of the remote server
+ /// The port the remote server runs on
+ /// Windows account username for the remote server
+ /// Windows account password for the remote server
+ public ServerInterface(string address, ushort port, string username, string password)
+ {
+ _HTTPSURL = address;
+ _HTTPSPort = port;
+ HTTPSUsername = username;
+ HTTPSPassword = password;
+ }
+
+ ///
+ /// Constructs an that connects to the same as some
+ ///
+ /// Another to copy settings from
+ public ServerInterface(ServerInterface other) : this(other.HTTPSURL, other.HTTPSPort, other.HTTPSUsername, other.HTTPSPassword) { }
+
+ ///
+ public ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false)
+ {
+ if (instanceName == null)
+ instanceName = InstanceName;
+ if (!skipChecks && !ConnectionStatus().HasFlag(ConnectivityLevel.Connected))
+ return ConnectivityLevel.None;
+ var prevInstance = InstanceName;
+ if (prevInstance != instanceName)
+ CloseAllChannels(false);
+ InstanceName = instanceName;
+ if (skipChecks)
+ return ConnectivityLevel.Connected;
+ try
+ {
+ GetComponent().VerifyConnection();
+ }
+ catch
+ {
+ InstanceName = prevInstance;
+ return ConnectivityLevel.None;
+ }
+ try
+ {
+ GetComponent().ServerDirectory();
+ }
+ catch
+ {
+ return ConnectivityLevel.Connected;
+ }
+ try
+ {
+ GetComponent().GetCurrentAuthorizedGroup();
+ return ConnectivityLevel.Administrator;
+ }
+ catch
+ {
+ return ConnectivityLevel.Authenticated;
+ }
+ }
+
+ ///
+ public bool IsRemoteConnection { get { return HTTPSURL != null; } }
+
+ ///
+ /// Closes all s stored in and clears it
+ ///
+ /// If set to , doesn't clear the channels that are used by
+ void CloseAllChannels(bool includingRoot)
+ {
+ string[] RootThings = { typeof(ITGSService).Name, 'S' + typeof(ITGConnectivity).Name };
+ lock (ChannelFactoryCache)
+ {
+ var toRemove = new List();
+ foreach (var I in ChannelFactoryCache)
+ {
+ if (RootThings.Contains(I.Key))
+ continue;
+ var cf = I.Value;
+ try
+ {
+ cf.Closed += ChannelFactory_Closed;
+ cf.Close();
+ }
+ catch
+ {
+ cf.Abort();
+ }
+ toRemove.Add(I.Key);
+ }
+ foreach (var I in toRemove)
+ ChannelFactoryCache.Remove(I);
+ }
+ }
+
+ ///
+ public bool VersionMismatch(out string errorMessage)
+ {
+ var splits = GetServiceComponent().Version().Split(' ');
+ var theirs = new Version(splits[splits.Length - 1].Substring(1));
+ var ours = new Version(FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion);
+ if(theirs.Major != ours.Major || theirs.Minor != ours.Minor || theirs.Revision != ours.Revision) //don't care about the patch level
+ {
+ errorMessage = String.Format("Version mismatch between interface version ({0}) and service version ({1}). Some functionality may crash this program.", ours, theirs);
+ return true;
+ }
+ errorMessage = null;
+ return false;
+ }
+
+ ///
+ /// Disposes a closed
+ ///
+ /// The channel factory that was closed
+ /// The event arguments
+ static void ChannelFactory_Closed(object sender, EventArgs e)
+ {
+ (sender as IDisposable).Dispose();
+ }
+
+ ///
+ public T GetComponent()
+ {
+ var ToT = typeof(T);
+ if (!ValidInstanceInterfaces.Contains(ToT))
+ throw new Exception("Invalid type!");
+ return GetComponentImpl(true);
+ }
+
+ ///
+ /// Returns the requested component for the instance . This does not guarantee a successful connection. s created this way are recycled for minimum latency and bandwidth usage
+ ///
+ /// The component to retrieve
+ /// If should be used to connect
+ /// The correct component
+ T GetComponentImpl(bool useInstanceName)
+ {
+ if (useInstanceName & InstanceName == null)
+ throw new Exception("Instance not selected!");
+ var actualToT = typeof(T);
+ var tot = actualToT.Name;
+ if (actualToT == typeof(ITGConnectivity) && !useInstanceName)
+ tot = 'S' + tot;
+ ChannelFactory cf;
+
+ lock (ChannelFactoryCache)
+ {
+ if (ChannelFactoryCache.ContainsKey(tot))
+ try
+ {
+ cf = ((ChannelFactory)ChannelFactoryCache[tot]);
+ if (cf.State != CommunicationState.Opened)
+ throw new Exception();
+ return cf.CreateChannel();
+ }
+ catch
+ {
+ ChannelFactoryCache[tot].Abort();
+ ChannelFactoryCache.Remove(tot);
+ }
+ cf = CreateChannel(useInstanceName ? InstanceName : null);
+ ChannelFactoryCache[tot] = cf;
+ }
+ return cf.CreateChannel();
+ }
+
+ ///
+ public T GetServiceComponent()
+ {
+ var ToT = typeof(T);
+ if (!ValidServiceInterfaces.Contains(ToT))
+ throw new Exception("Invalid type!");
+ return GetComponentImpl(false);
+ }
+
+ ///
+ /// Directly creates a for without caching. This should be eventually closed by the caller
+ ///
+ /// The component of the channel to be created
+ /// The correct
+ /// Thrown if isn't a valid component
+ ChannelFactory CreateChannel(string instanceName)
+ {
+ var accessPath = instanceName == null ? MasterInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName);
+
+ var InterfaceName = typeof(T).Name;
+ if (!IsRemoteConnection)
+ {
+ var res2 = new ChannelFactory(
+ new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = TransferLimitLocal }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", accessPath, InterfaceName))); //10 megs
+ res2.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
+ return res2;
+ }
+
+ //okay we're going over
+ var binding = new WSHttpBinding()
+ {
+ SendTimeout = new TimeSpan(0, 0, 40),
+ MaxReceivedMessageSize = TransferLimitRemote
+ };
+ var requireAuth = InterfaceName != typeof(ITGConnectivity).Name;
+ binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
+ binding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check
+ binding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None;
+ var address = new EndpointAddress(String.Format("https://{0}:{1}/{2}/{3}", HTTPSURL, HTTPSPort, accessPath, InterfaceName));
+ var res = new ChannelFactory(binding, address);
+ if (requireAuth)
+ {
+ res.Credentials.UserName.UserName = HTTPSUsername;
+ res.Credentials.UserName.Password = HTTPSPassword;
+ res.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
+ }
+ return res;
+ }
+
+ ///
+ public ConnectivityLevel ConnectionStatus()
+ {
+ return ConnectionStatus(out string unused);
+ }
+
+ ///
+ public ConnectivityLevel ConnectionStatus(out string error)
+ {
+ try
+ {
+ GetComponentImpl(false).VerifyConnection();
+ }
+ catch (CommunicationException e)
+ {
+ error = e.ToString();
+ return ConnectivityLevel.None;
+ }
+ try
+ {
+ GetServiceComponent().Version();
+ }
+ catch(Exception e)
+ {
+ error = e.ToString();
+ return ConnectivityLevel.Connected;
+ }
+ try
+ {
+ GetServiceComponent().Version();
+ error = null;
+ return ConnectivityLevel.Administrator;
+ }
+ catch(Exception e)
+ {
+ error = e.ToString();
+ return ConnectivityLevel.Authenticated;
+ }
+ }
+
+ #region IDisposable Support
+ ///
+ /// To detect redundant calls
+ ///
+ private bool disposedValue = false;
+
+ ///
+ /// Implements the pattern. Calls
+ ///
+ /// if was called manually, if it was from the finalizer
+ void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ CloseAllChannels(true);
+ }
+
+ // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
+ // TODO: set large fields to null.
+
+ disposedValue = true;
+ }
+ }
+
+ // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
+ // ~Interface() {
+ // // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ // Dispose(false);
+ // }
+
+ ///
+ /// Implements the pattern
+ ///
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(true);
+ // TODO: uncomment the following line if the finalizer is overridden above.
+ // GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/TGServiceInterface/TGServiceInterface.csproj b/TGS.Interface/TGS.Interface.csproj
similarity index 93%
rename from TGServiceInterface/TGServiceInterface.csproj
rename to TGS.Interface/TGS.Interface.csproj
index 1c5769d1ba..fa07f5838f 100644
--- a/TGServiceInterface/TGServiceInterface.csproj
+++ b/TGS.Interface/TGS.Interface.csproj
@@ -7,7 +7,7 @@
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}
Library
Properties
- TGServiceInterface
+ TGS.Interface
TGServiceInterface
v4.5.2
512
@@ -27,7 +27,7 @@
bin\Release\
TRACE
- bin\x86\Release\TGServiceInterface.xml
+ bin\x86\Release\TGS.Interface.xml
true
true
pdbonly
@@ -66,7 +66,7 @@
-
+
@@ -75,7 +75,7 @@
-
+
\ No newline at end of file
diff --git a/TGServiceInterface/TGServiceInterface.nuspec b/TGS.Interface/TGS.Interface.nuspec
similarity index 96%
rename from TGServiceInterface/TGServiceInterface.nuspec
rename to TGS.Interface/TGS.Interface.nuspec
index 44637c7556..80bbf50f80 100644
--- a/TGServiceInterface/TGServiceInterface.nuspec
+++ b/TGS.Interface/TGS.Interface.nuspec
@@ -1,7 +1,7 @@
- $id$
+ TGServiceInterface
$version$
Cyberboss
https://github.com/tgstation/tgstation-server/blob/master/LICENSE
diff --git a/TGServerService/tgs.ico b/TGS.Interface/tgs.ico
similarity index 100%
rename from TGServerService/tgs.ico
rename to TGS.Interface/tgs.ico
diff --git a/TGS.Server.Console/App.config b/TGS.Server.Console/App.config
new file mode 100644
index 0000000000..8227adb989
--- /dev/null
+++ b/TGS.Server.Console/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/TGS.Server.Console/Console.cs b/TGS.Server.Console/Console.cs
new file mode 100644
index 0000000000..9641e5d625
--- /dev/null
+++ b/TGS.Server.Console/Console.cs
@@ -0,0 +1,73 @@
+using System;
+
+namespace TGS.Server.Console
+{
+ ///
+ /// Console runner for a
+ ///
+ sealed class Console : ILogger
+ {
+ ///
+ /// Entry point to the
+ ///
+ ///
+ static void Main(string[] args) => new Console(args);
+
+ ///
+ /// Construct and run a
+ ///
+ /// Command line arguments
+ Console(string[] args)
+ {
+ try
+ {
+ System.Console.WriteLine("Starting server...");
+ var server = new Server(args, this); //no using to avoid including more references
+ try
+ {
+ System.Console.WriteLine("Server started!");
+ ExitPrompt();
+ }
+ finally
+ {
+ server.Dispose();
+ }
+ }
+ catch (Exception e)
+ {
+ System.Console.WriteLine(String.Format("Unhandled exception: {0}", e.ToString()));
+ ExitPrompt();
+ }
+ }
+
+ void ExitPrompt()
+ {
+ System.Console.WriteLine("Press any key to exit...");
+ System.Console.ReadKey();
+ }
+
+ ///
+ public void WriteAccess(string username, bool authSuccess, byte loggingID)
+ {
+ System.Console.WriteLine(String.Format("[{0}]: {1}-{4}: Authentication {3} from {2}", DateTime.UtcNow.ToString(), EventID.Authentication, username, authSuccess ? "success" : "fail", loggingID));
+ }
+
+ ///
+ public void WriteError(string message, EventID id, byte loggingID)
+ {
+ System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: ERROR: {2}", DateTime.Now.ToString(), id, message, loggingID));
+ }
+
+ ///
+ public void WriteInfo(string message, EventID id, byte loggingID)
+ {
+ System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: {2}", DateTime.Now.ToString(), id, message, loggingID));
+ }
+
+ ///
+ public void WriteWarning(string message, EventID id, byte loggingID)
+ {
+ System.Console.WriteLine(String.Format("[{0}]: {1}-{3}: Warning: {2}", DateTime.Now.ToString(), id, message, loggingID));
+ }
+ }
+}
diff --git a/TGS.Server.Console/Properties/AssemblyInfo.cs b/TGS.Server.Console/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..0ce360e6d0
--- /dev/null
+++ b/TGS.Server.Console/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TGStation Server Console")]
+[assembly: AssemblyDescription("Console adapter for TGStation Server")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("509433f6-aefb-44ca-bfe3-c782166d2cc3")]
diff --git a/TGS.Server.Console/TGS.Server.Console.csproj b/TGS.Server.Console/TGS.Server.Console.csproj
new file mode 100644
index 0000000000..37d49bf3a8
--- /dev/null
+++ b/TGS.Server.Console/TGS.Server.Console.csproj
@@ -0,0 +1,89 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {509433F6-AEFB-44CA-BFE3-C782166D2CC3}
+ Exe
+ TGS.Server.Console
+ TGS.Server.Console
+ v4.5.2
+ 512
+ true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ app.manifest
+
+
+ tgs.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {f32eda25-0855-411c-af5e-f0d042917e2d}
+ TGS.Server
+
+
+
+
+ False
+ Microsoft .NET Framework 4.6.1 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TGS.Server.Console/app.manifest b/TGS.Server.Console/app.manifest
new file mode 100644
index 0000000000..467015914e
--- /dev/null
+++ b/TGS.Server.Console/app.manifest
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TGServiceInterface/tgs.ico b/TGS.Server.Console/tgs.ico
similarity index 100%
rename from TGServiceInterface/tgs.ico
rename to TGS.Server.Console/tgs.ico
diff --git a/TGS.Server.Service/App.config b/TGS.Server.Service/App.config
new file mode 100644
index 0000000000..8227adb989
--- /dev/null
+++ b/TGS.Server.Service/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/TGServerService/ProjectInstaller.cs b/TGS.Server.Service/ProjectInstaller.cs
similarity index 96%
rename from TGServerService/ProjectInstaller.cs
rename to TGS.Server.Service/ProjectInstaller.cs
index f5c0f1a911..10c319e3d0 100644
--- a/TGServerService/ProjectInstaller.cs
+++ b/TGS.Server.Service/ProjectInstaller.cs
@@ -2,7 +2,7 @@
using System.Configuration.Install;
using System.ServiceProcess;
-namespace TGServerService
+namespace TGS.Server.Service
{
///
/// This tells the .msi there is a Windows in this that needs installation
diff --git a/TGS.Server.Service/Properties/AssemblyInfo.cs b/TGS.Server.Service/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..e4e22f2673
--- /dev/null
+++ b/TGS.Server.Service/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TGStation Server Service")]
+[assembly: AssemblyDescription("Windows service adapter for TGStation Server")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3f81e398-b223-4006-b40c-c2800714ce29")]
diff --git a/TGS.Server.Service/Service.cs b/TGS.Server.Service/Service.cs
new file mode 100644
index 0000000000..af88d24b50
--- /dev/null
+++ b/TGS.Server.Service/Service.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Diagnostics;
+using System.ServiceProcess;
+
+namespace TGS.Server.Service
+{
+ ///
+ /// Windows adapter for
+ ///
+ public sealed class Service : ServiceBase, ILogger
+ {
+ ///
+ /// The entry point for the program. Calls with a new as a parameter
+ ///
+ public static void Main() => Run(new Service());
+
+ ///
+ /// The the manages
+ ///
+ Server activeServer;
+
+ ///
+ public void WriteAccess(string username, bool authSuccess, byte loggingID)
+ {
+ EventLog.WriteEntry(String.Format("Access from: {0}", username), authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit , (int)EventID.Authentication + loggingID);
+ }
+
+ ///
+ public void WriteError(string message, EventID id, byte loggingID)
+ {
+ EventLog.WriteEntry(message, EventLogEntryType.Error, (int)id + loggingID);
+ }
+
+ ///
+ public void WriteInfo(string message, EventID id, byte loggingID)
+ {
+ EventLog.WriteEntry(message, EventLogEntryType.Information, (int)id + loggingID);
+ }
+
+ ///
+ public void WriteWarning(string message, EventID id, byte loggingID)
+ {
+ EventLog.WriteEntry(message, EventLogEntryType.Warning, (int)id + loggingID);
+ }
+
+ ///
+ /// Called when the is started. Creates a new
+ ///
+ /// The service start arguments
+ protected override void OnStart(string[] args)
+ {
+ activeServer = new Server(args, this);
+ }
+
+ ///
+ /// Called when the is stopped. Calls on
+ ///
+ protected override void OnStop()
+ {
+ activeServer.Dispose();
+ }
+ }
+}
diff --git a/TGS.Server.Service/TGS.Server.Service.csproj b/TGS.Server.Service/TGS.Server.Service.csproj
new file mode 100644
index 0000000000..79fb1a5a22
--- /dev/null
+++ b/TGS.Server.Service/TGS.Server.Service.csproj
@@ -0,0 +1,69 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {3F81E398-B223-4006-B40C-C2800714CE29}
+ WinExe
+ TGS.Server.Service
+ TGServerService
+ v4.5.2
+ 512
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ TGS.Server.Service.Service
+
+
+ tgs.ico
+
+
+
+
+
+
+
+
+ Component
+
+
+ Component
+
+
+
+
+
+
+
+
+
+ {f32eda25-0855-411c-af5e-f0d042917e2d}
+ TGS.Server
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TGS.Server.Service/tgs.ico b/TGS.Server.Service/tgs.ico
new file mode 100644
index 0000000000..6ed69fadfc
Binary files /dev/null and b/TGS.Server.Service/tgs.ico differ
diff --git a/TGS.Server/App.config b/TGS.Server/App.config
new file mode 100644
index 0000000000..892916e112
--- /dev/null
+++ b/TGS.Server/App.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/TGServerService/ChatCommands/ByondCommand.cs b/TGS.Server/ChatCommands/ByondCommand.cs
similarity index 93%
rename from TGServerService/ChatCommands/ByondCommand.cs
rename to TGS.Server/ChatCommands/ByondCommand.cs
index 27cd19dadf..b983339816 100644
--- a/TGServerService/ChatCommands/ByondCommand.cs
+++ b/TGS.Server/ChatCommands/ByondCommand.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// Retrieve the installed, staged, or latest availab
diff --git a/TGServerService/ChatCommands/ChatCommand.cs b/TGS.Server/ChatCommands/ChatCommand.cs
similarity index 89%
rename from TGServerService/ChatCommands/ChatCommand.cs
rename to TGS.Server/ChatCommands/ChatCommand.cs
index 17794613fa..96d5803ca1 100644
--- a/TGServerService/ChatCommands/ChatCommand.cs
+++ b/TGS.Server/ChatCommands/ChatCommand.cs
@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Threading;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// A command heard by a
@@ -20,7 +20,7 @@ namespace TGServerService.ChatCommands
///
/// Shorthand for accessing
///
- protected ServerInstance Instance { get { return CommandInfo.Value.Server; } }
+ protected Instance Instance { get { return CommandInfo.Value.Server; } }
///
public override ExitCode DoRun(IList parameters)
diff --git a/TGServerService/ChatCommands/CommandInfo.cs b/TGS.Server/ChatCommands/CommandInfo.cs
similarity index 70%
rename from TGServerService/ChatCommands/CommandInfo.cs
rename to TGS.Server/ChatCommands/CommandInfo.cs
index 913bd50e70..4108fd051f 100644
--- a/TGServerService/ChatCommands/CommandInfo.cs
+++ b/TGS.Server/ChatCommands/CommandInfo.cs
@@ -1,4 +1,4 @@
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// Metadata about the currently running
@@ -18,8 +18,8 @@
///
public string Speaker { get; set; }
///
- /// A reference to the that runs the that heard the
+ /// A reference to the that runs the that heard the
///
- public ServerInstance Server { get; set; }
+ public Instance Server { get; set; }
}
}
diff --git a/TGServerService/ChatCommands/KekCommand.cs b/TGS.Server/ChatCommands/KekCommand.cs
similarity index 92%
rename from TGServerService/ChatCommands/KekCommand.cs
rename to TGS.Server/ChatCommands/KekCommand.cs
index 1c2eda51c6..1826bf1876 100644
--- a/TGServerService/ChatCommands/KekCommand.cs
+++ b/TGS.Server/ChatCommands/KekCommand.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// kek
diff --git a/TGServerService/ChatCommands/PullRequestsCommand.cs b/TGS.Server/ChatCommands/PullRequestsCommand.cs
similarity index 95%
rename from TGServerService/ChatCommands/PullRequestsCommand.cs
rename to TGS.Server/ChatCommands/PullRequestsCommand.cs
index 50495174c5..e03d426c04 100644
--- a/TGServerService/ChatCommands/PullRequestsCommand.cs
+++ b/TGS.Server/ChatCommands/PullRequestsCommand.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// Retrieve the list of test-merged github pull requests
diff --git a/TGServerService/ChatCommands/RevisionCommand.cs b/TGS.Server/ChatCommands/RevisionCommand.cs
similarity index 95%
rename from TGServerService/ChatCommands/RevisionCommand.cs
rename to TGS.Server/ChatCommands/RevisionCommand.cs
index 18b28b96ac..7fd99c0f28 100644
--- a/TGServerService/ChatCommands/RevisionCommand.cs
+++ b/TGS.Server/ChatCommands/RevisionCommand.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// Retrieves the git SHA of the live DreamDaemon code
diff --git a/TGServerService/ChatCommands/RootChatCommand.cs b/TGS.Server/ChatCommands/RootChatCommand.cs
similarity index 91%
rename from TGServerService/ChatCommands/RootChatCommand.cs
rename to TGS.Server/ChatCommands/RootChatCommand.cs
index 82bb3e172e..800147a412 100644
--- a/TGServerService/ChatCommands/RootChatCommand.cs
+++ b/TGS.Server/ChatCommands/RootChatCommand.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// The main root chat command
diff --git a/TGServerService/ChatCommands/ServerChatCommand.cs b/TGS.Server/ChatCommands/ServerChatCommand.cs
similarity index 93%
rename from TGServerService/ChatCommands/ServerChatCommand.cs
rename to TGS.Server/ChatCommands/ServerChatCommand.cs
index f7551e60af..fee9f70eb5 100644
--- a/TGServerService/ChatCommands/ServerChatCommand.cs
+++ b/TGS.Server/ChatCommands/ServerChatCommand.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// s generated by DreamDaemon via the API
@@ -37,7 +37,7 @@ namespace TGServerService.ChatCommands
///
protected override ExitCode Run(IList parameters)
{
- var res = Instance.SendCommand(String.Format("{0};sender={1};custom={2}", Keyword, CommandInfo.Value.Speaker, Program.SanitizeTopicString(String.Join(" ", parameters))));
+ var res = Instance.SendCommand(String.Format("{0};sender={1};custom={2}", Keyword, CommandInfo.Value.Speaker, Helpers.SanitizeTopicString(String.Join(" ", parameters))));
if (res != "SUCCESS" && !String.IsNullOrWhiteSpace(res))
OutputProc(res);
return ExitCode.Normal;
diff --git a/TGServerService/ChatCommands/VersionCommand.cs b/TGS.Server/ChatCommands/VersionCommand.cs
similarity index 93%
rename from TGServerService/ChatCommands/VersionCommand.cs
rename to TGS.Server/ChatCommands/VersionCommand.cs
index d066d83971..538bcb4e7f 100644
--- a/TGServerService/ChatCommands/VersionCommand.cs
+++ b/TGS.Server/ChatCommands/VersionCommand.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace TGServerService.ChatCommands
+namespace TGS.Server.ChatCommands
{
///
/// Retrieve the current service version
diff --git a/TGServerService/ChatProviders/ChatProvider.cs b/TGS.Server/ChatProviders/ChatProvider.cs
similarity index 97%
rename from TGServerService/ChatProviders/ChatProvider.cs
rename to TGS.Server/ChatProviders/ChatProvider.cs
index da6ff62999..974d79eaf8 100644
--- a/TGServerService/ChatProviders/ChatProvider.cs
+++ b/TGS.Server/ChatProviders/ChatProvider.cs
@@ -1,7 +1,7 @@
using System;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGServerService.ChatProviders
+namespace TGS.Server.ChatProviders
{
///
/// Callback for the chat provider recieving a
diff --git a/TGServerService/ChatProviders/DiscordChatProvider.cs b/TGS.Server/ChatProviders/DiscordChatProvider.cs
similarity index 98%
rename from TGServerService/ChatProviders/DiscordChatProvider.cs
rename to TGS.Server/ChatProviders/DiscordChatProvider.cs
index 1b347b0de2..7809df8af9 100644
--- a/TGServerService/ChatProviders/DiscordChatProvider.cs
+++ b/TGS.Server/ChatProviders/DiscordChatProvider.cs
@@ -4,9 +4,9 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
-using TGServiceInterface;
+using TGS.Interface;
-namespace TGServerService.ChatProviders
+namespace TGS.Server.ChatProviders
{
///
/// for Discord: https://discordapp.com/
@@ -179,7 +179,6 @@ namespace TGServerService.ChatProviders
lock (DiscordLock)
{
var tasks = new List();
- var Config = Properties.Settings.Default;
foreach (var I in client.Guilds)
foreach (var J in I.TextChannels)
{
@@ -208,7 +207,6 @@ namespace TGServerService.ChatProviders
lock (DiscordLock)
{
var tasks = new List();
- var Config = Properties.Settings.Default;
var channel = Convert.ToUInt64(channelname);
if (SeenPrivateChannels.ContainsKey(channel))
SeenPrivateChannels[channel].SendMessageAsync(message).Wait();
diff --git a/TGServerService/ChatProviders/IRCChatProvider.cs b/TGS.Server/ChatProviders/IRCChatProvider.cs
similarity index 98%
rename from TGServerService/ChatProviders/IRCChatProvider.cs
rename to TGS.Server/ChatProviders/IRCChatProvider.cs
index a41a7fd72b..9074219cec 100644
--- a/TGServerService/ChatProviders/IRCChatProvider.cs
+++ b/TGS.Server/ChatProviders/IRCChatProvider.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
-using TGServiceInterface;
+using TGS.Interface;
using Meebey.SmartIrc4net;
-namespace TGServerService.ChatProviders
+namespace TGS.Server.ChatProviders
{
///
/// for internet relay chat
@@ -48,7 +48,7 @@ namespace TGServerService.ChatProviders
irc = new IrcFeatures()
{
SupportNonRfc = true,
- CtcpUserInfo = Service.VersionString,
+ CtcpUserInfo = Server.VersionString,
AutoRejoin = true,
AutoRejoinOnKick = true,
AutoRelogin = true,
diff --git a/TGServerService/DeprecatedInstanceConfig.cs b/TGS.Server/DeprecatedInstanceConfig.cs
similarity index 92%
rename from TGServerService/DeprecatedInstanceConfig.cs
rename to TGS.Server/DeprecatedInstanceConfig.cs
index 9eff86cc04..3297e7423b 100644
--- a/TGServerService/DeprecatedInstanceConfig.cs
+++ b/TGS.Server/DeprecatedInstanceConfig.cs
@@ -1,7 +1,7 @@
using System;
using System.Configuration;
-namespace TGServerService
+namespace TGS.Server
{
///
/// Used to migrate old config settings
@@ -9,7 +9,7 @@ namespace TGServerService
class DeprecatedInstanceConfig : InstanceConfig
{
///
- /// The default directory
+ /// The default directory
///
const string DefaultInstallationPath = "C:\\tgstation-server-3";
@@ -20,7 +20,7 @@ namespace TGServerService
public static IInstanceConfig CreateFromNETSettings()
{
var Config = Properties.Settings.Default;
- var result = new DeprecatedInstanceConfig(Program.NormalizePath(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3")));
+ var result = new DeprecatedInstanceConfig(Helpers.NormalizePath(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3")));
// using nameof for sanity where possible
result.ProjectName = LoadPreviousNetPropertyOrDefault(nameof(ProjectName), result.ProjectName);
result.Port = LoadPreviousNetPropertyOrDefault("ServerPort", result.Port);
@@ -66,7 +66,7 @@ namespace TGServerService
//Which is fucking retarded
//This hooks into the settings provider and forces it to load it anyway
var Config = Properties.Settings.Default;
- var Provider = Config.Properties[nameof(Config.SettingsVersion)].Provider; //nameof for sanity
+ var Provider = Config.Properties["SettingsVersion"].Provider;
var sp = new SettingsProperty(property)
{
@@ -94,9 +94,9 @@ namespace TGServerService
public DeprecatedInstanceConfig() : base(DefaultInstallationPath) { }
///
- /// Construct a for a at
+ /// Construct a for a at
///
- /// The path to the
+ /// The path to the
public DeprecatedInstanceConfig(string path) : base(path) { }
///
diff --git a/TGServerService/EventID.cs b/TGS.Server/EventID.cs
similarity index 59%
rename from TGServerService/EventID.cs
rename to TGS.Server/EventID.cs
index dab2bca4dd..5fd0a44696 100644
--- a/TGServerService/EventID.cs
+++ b/TGS.Server/EventID.cs
@@ -1,9 +1,9 @@
using System;
-namespace TGServerService
+namespace TGS.Server
{
///
- /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults
+ /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults
///
public enum EventID : int
{
@@ -20,7 +20,7 @@ namespace TGServerService
///
ChatProviderStartFail = 300,
///
- /// Error: When a bad is passed
+ /// Error: When a bad is passed
///
InvalidChatProvider = 400,
///
@@ -33,7 +33,7 @@ namespace TGServerService
///
BYONDUpdateFail = 600,
///
- /// Info: When the BYOND updater successfully staged a revision but could not apply it due to the being active
+ /// Info: When the BYOND updater successfully staged a revision but could not apply it due to the being active
///
BYONDUpdateStaged = 700,
///
@@ -41,46 +41,46 @@ namespace TGServerService
///
BYONDUpdateComplete = 800,
///
- /// Error: Failed to move the with TGServiceInterface.Components.ITGAdministration.MoveServer(string)
+ /// Error: Failed to move the with TGS.Interface.Components.ITGAdministration.MoveServer(string)
///
[Obsolete("Not in use anymore", true)]
ServerMoveFailed = 900,
///
- /// Warning: Failed to delete the old directory during a TGServiceInterface.Components.ITGAdministration.MoveServer(string) operation
+ /// Warning: Failed to delete the old directory during a TGS.Interface.Components.ITGAdministration.MoveServer(string) operation
///
[Obsolete("Not in use anymore", true)]
ServerMovePartial = 1000,
///
- /// Info: Successful completion of a TGServiceInterface.Components.ITGAdministration.MoveServer(string) operation
+ /// Info: Successful completion of a TGS.Interface.Components.ITGAdministration.MoveServer(string) operation
///
[Obsolete("Not in use anymore", true)]
ServerMoveComplete = 1100,
///
- /// Error: An internal error occurred during a operation
+ /// Error: An internal error occurred during a operation
///
DMCompileCrash = 1200,
///
- /// Error: An internal error occurred during a operation
+ /// Error: An internal error occurred during a operation
///
DMInitializeCrash = 1300,
///
- /// Warning: Compile failure of the target .dme in a operation
+ /// Warning: Compile failure of the target .dme in a operation
///
DMCompileError = 1400,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
DMCompileSuccess = 1500,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
DMCompileCancel = 1600,
///
- /// Error: Failed to reattach the watchdog to a running DreamDaemon instance after a update
+ /// Error: Failed to reattach the watchdog to a running DreamDaemon instance after a update
///
DDReattachFail = 1700,
///
- /// Info: Successfully reattached the watchdog to a running DreamDaemon instance after a update
+ /// Info: Successfully reattached the watchdog to a running DreamDaemon instance after a update
///
DDReattachSuccess = 1800,
///
@@ -88,7 +88,7 @@ namespace TGServerService
///
DDWatchdogCrash = 1900,
///
- /// Info: The watchdog has exited, either for an or , or operation
+ /// Info: The watchdog has exited, either for an or , or operation
///
DDWatchdogExit = 2000,
///
@@ -101,15 +101,15 @@ namespace TGServerService
///
DDWatchdogRebootingServer = 2200,
///
- /// Info: The watchdog is performing a operation
+ /// Info: The watchdog is performing a operation
///
DDWatchdogRestart = 2300,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
DDWatchdogRestarted = 2400,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
DDWatchdogStarted = 2500,
///
@@ -143,7 +143,7 @@ namespace TGServerService
[Obsolete("Not in use anymore", true)]
TopicFailed = 3100,
///
- /// Info: When the has been generated
+ /// Info: When the has been generated
///
CommsKeySet = 3200,
///
@@ -157,35 +157,35 @@ namespace TGServerService
[Obsolete("Not in use anymore", true)]
NudgeCrash = 3400,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
RepoClone = 3500,
///
- /// Warning: An error occurred during a operation
+ /// Warning: An error occurred during a operation
///
RepoCloneFail = 3600,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
RepoCheckout = 3700,
///
- /// Warning: An error occurred during a operation
+ /// Warning: An error occurred during a operation
///
RepoCheckoutFail = 3800,
///
- /// Info: Successful completion of a operation with a parameter
+ /// Info: Successful completion of a operation with a parameter
///
RepoHardUpdate = 3900,
///
- /// Warning: An error occurred during a operation with a parameter
+ /// Warning: An error occurred during a operation with a parameter
///
RepoHardUpdateFail = 4000,
///
- /// Info: Successful completion of a operation with a parameter
+ /// Info: Successful completion of a operation with a parameter
///
RepoMergeUpdate = 4100,
///
- /// Warning: An error occurred during a operation with a parameter
+ /// Warning: An error occurred during a operation with a parameter
///
RepoMergeUpdateFail = 4200,
///
@@ -197,19 +197,19 @@ namespace TGServerService
///
RepoBackupTagFail = 4400,
///
- /// Info: Successful completion of a operation with a parameter
+ /// Info: Successful completion of a operation with a parameter
///
RepoResetTracked = 4500,
///
- /// Warning: An error occurred during a operation with a parameter
+ /// Warning: An error occurred during a operation with a parameter
///
RepoResetTrackedFail = 4600,
///
- /// Info: Successful completion of a operation with a parameter
+ /// Info: Successful completion of a operation with a parameter
///
RepoReset = 4700,
///
- /// Warning: An error occurred during a operation with a parameter
+ /// Warning: An error occurred during a operation with a parameter
///
RepoResetFail = 4800,
///
@@ -217,63 +217,63 @@ namespace TGServerService
///
RepoPRListError = 4900,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
RepoPRMerge = 5000,
///
- /// Warning: An error occurred during a operation
+ /// Warning: An error occurred during a operation
///
RepoPRMergeFail = 5100,
///
- /// Info: Successfully committed the paths specified in the synchronize_directories field of the 's TGS3.json
+ /// Info: Successfully committed the paths specified in the synchronize_directories field of the 's TGS3.json
///
RepoCommit = 5200,
///
- /// Warning: An error occurred while committing the paths specified in the synchronize_directories field of the 's TGS3.json
+ /// Warning: An error occurred while committing the paths specified in the synchronize_directories field of the 's TGS3.json
///
RepoCommitFail = 5300,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
RepoPush = 5400,
///
- /// Warning: An error occurred during a operation
+ /// Warning: An error occurred during a operation
///
RepoPushFail = 5500,
///
- /// Info: Successful completion of a operation
+ /// Info: Successful completion of a operation
///
RepoChangelog = 5600,
///
- /// Warning: An error occurred during a operation
+ /// Warning: An error occurred during a operation
///
RepoChangelogFail = 5700,
///
- /// Info: When the dll is updated for the
+ /// Info: When the dll is updated for the
///
BridgeDLLUpdated = 5800,
///
- /// Error: An error occurred while updating the dll for the
+ /// Error: An error occurred while updating the dll for the
///
BridgeDLLUpdateFail = 5900,
///
- /// Error: An error occurred while starting the
+ /// Error: An error occurred while starting the
///
InstanceInitializationFailure = 6000,
///
- /// Error: When an exception occurs while the is stopping
+ /// Error: When an exception occurs while the is stopping
///
ServiceShutdownFail = 6100,
///
- /// Info: When the reboots in BYOND
+ /// Info: When the reboots in BYOND
///
WorldReboot = 6200,
///
- /// Info: When the output of is applied to the live
+ /// Info: When the output of is applied to the live
///
ServerUpdateApplied = 6300,
///
- /// Warning: When an exception occurs during a operation
+ /// Warning: When an exception occurs during a operation
///
ChatBroadcastFail = 6400,
///
@@ -287,7 +287,7 @@ namespace TGServerService
///
Submodule = 6600,
///
- /// This event is of type or . It occurs when a user different from the previous one tries and either succeeds or fails to access a . DreamDaemon itself successfully accessing will not trigger this
+ /// This event is of type or . It occurs when a user different from the previous one tries and either succeeds or fails to access a . DreamDaemon itself successfully accessing will not trigger this
///
Authentication = 6700,
///
@@ -299,11 +299,11 @@ namespace TGServerService
///
PreactionFail = 6900,
///
- /// Warning: When a command from DreamDaemon fails
+ /// Warning: When a command from DreamDaemon fails
///
InteropCallException = 7000,
///
- /// Warning: When the running DreamDaemon code does not have the correct API to talk to the
+ /// Warning: When the running DreamDaemon code does not have the correct API to talk to the
///
APIVersionMismatch = 7100,
///
diff --git a/TGServerService/Program.cs b/TGS.Server/Helpers.cs
similarity index 97%
rename from TGServerService/Program.cs
rename to TGS.Server/Helpers.cs
index 1394802800..7cff312bca 100644
--- a/TGServerService/Program.cs
+++ b/TGS.Server/Helpers.cs
@@ -1,21 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.ServiceProcess;
using System.Threading.Tasks;
-namespace TGServerService
+namespace TGS.Server
{
- static class Program
+ ///
+ /// Generic helpers for the
+ ///
+ static class Helpers
{
- ///
- /// Entry point to the program
- ///
- static void Main() {
- using (var S = new Service())
- ServiceBase.Run(S);
- }
-
///
/// Copy a file from to , but first ensure the destination directory exists
///
diff --git a/TGS.Server/ILogger.cs b/TGS.Server/ILogger.cs
new file mode 100644
index 0000000000..9615b133b7
--- /dev/null
+++ b/TGS.Server/ILogger.cs
@@ -0,0 +1,40 @@
+namespace TGS.Server
+{
+ ///
+ /// Used for writing logs to a provider
+ ///
+ public interface ILogger
+ {
+ ///
+ /// Writes information to the log
+ ///
+ /// The log message
+ /// The of the message
+ /// The 0-99 ID of the log source
+ void WriteInfo(string message, EventID id, byte loggingID);
+
+ ///
+ /// Writes an error to the log
+ ///
+ /// The log message
+ /// The of the message
+ /// The 0-99 ID of the log source
+ void WriteError(string message, EventID id, byte loggingID);
+
+ ///
+ /// Writes a warning to the log
+ ///
+ /// The log message
+ /// The of the message
+ /// The 0-99 ID of the log source
+ void WriteWarning(string message, EventID id, byte loggingID);
+
+ ///
+ /// Writes an access event to the log
+ ///
+ /// The (un)authenticated Windows user's name
+ /// if authenticated sucessfully, otherwise
+ /// The 0-99 ID of the log source
+ void WriteAccess(string username, bool authSuccess, byte loggingID);
+ }
+}
diff --git a/TGServerService/ServerInstance/Administration.cs b/TGS.Server/Instance/Administration.cs
similarity index 93%
rename from TGServerService/ServerInstance/Administration.cs
rename to TGS.Server/Instance/Administration.cs
index affe43a2b7..7c795857c1 100644
--- a/TGServerService/ServerInstance/Administration.cs
+++ b/TGS.Server/Instance/Administration.cs
@@ -3,17 +3,17 @@ using System.DirectoryServices.AccountManagement;
using System.Security.Principal;
using System.ServiceModel;
using System.Threading;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
//note this only works with MACHINE LOCAL groups and admins for now
//if someone wants AD shit, code it yourself
- sealed partial class ServerInstance : ServiceAuthorizationManager, ITGAdministration
+ sealed partial class Instance : ServiceAuthorizationManager, ITGAdministration
{
///
- /// The of the Windows group authorized to access the
+ /// The of the Windows group authorized to access the
///
SecurityIdentifier TheDroidsWereLookingFor;
///
@@ -21,12 +21,12 @@ namespace TGServerService
///
object authLock = new object();
///
- /// The of the last to attempt to access the
+ /// The of the last to attempt to access the
///
string LastSeenUser;
///
- /// The of the account the is running as
+ /// The of the account the is running as
///
readonly SecurityIdentifier ServiceSID = WindowsIdentity.GetCurrent().User;
@@ -70,7 +70,7 @@ namespace TGServerService
///
/// The name of the group to search for
/// Recursive parameter used to check for the group using instead of
- /// The name of the group allowed to access the if it could be found, otherwise
+ /// The name of the group allowed to access the if it could be found, otherwise
string FindTheDroidsWereLookingFor(string search = null, bool useDomain = false)
{
RootAuthorizationManager.InstanceAuthManagers.Add(this);
diff --git a/TGServerService/ServerInstance/Byond.cs b/TGS.Server/Instance/Byond.cs
similarity index 93%
rename from TGServerService/ServerInstance/Byond.cs
rename to TGS.Server/Instance/Byond.cs
index 2b902a52f6..643a896292 100644
--- a/TGServerService/ServerInstance/Byond.cs
+++ b/TGS.Server/Instance/Byond.cs
@@ -5,12 +5,12 @@ using System.IO.Compression;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
- sealed partial class ServerInstance : ITGByond
+ sealed partial class Instance : ITGByond
{
///
/// The instance directory to store the BYOND installation
@@ -72,7 +72,7 @@ namespace TGServerService
Thread RevisionStaging;
///
- /// Called when the is setup. Prepares the BYOND updater
+ /// Called when the is setup. Prepares the BYOND updater
///
void InitByond()
{
@@ -88,11 +88,11 @@ namespace TGServerService
//linger not
if (File.Exists(rrdp))
File.Delete(rrdp);
- Program.DeleteDirectory(RelativePath(StagingDirectory));
+ Helpers.DeleteDirectory(RelativePath(StagingDirectory));
}
///
- /// Called when the is shutdown
+ /// Called when the is shutdown
///
void DisposeByond()
{
@@ -194,7 +194,7 @@ namespace TGServerService
}
///
- /// Downloads and unzips a BYOND revision. Calls afterwards if the isn't running, otherwise, calls . Sets on failure
+ /// Downloads and unzips a BYOND revision. Calls afterwards if the isn't running, otherwise, calls . Sets on failure
///
/// Stringified BYOND revision
public void UpdateToVersionImpl(object param)
@@ -326,9 +326,9 @@ namespace TGServerService
try
{
var rbd = RelativePath(ByondDirectory);
- Program.DeleteDirectory(rbd);
+ Helpers.DeleteDirectory(rbd);
Directory.Move(RelativePath(StagingDirectoryInner), rbd);
- Program.DeleteDirectory(RelativePath(StagingDirectory));
+ Helpers.DeleteDirectory(RelativePath(StagingDirectory));
lastError = null;
SendMessage("BYOND: Update completed!", MessageType.DeveloperInfo);
WriteInfo(String.Format("BYOND update {0} completed!", GetVersion(ByondVersion.Installed)), EventID.BYONDUpdateComplete);
diff --git a/TGServerService/ServerInstance/Chat.cs b/TGS.Server/Instance/Chat.cs
similarity index 91%
rename from TGServerService/ServerInstance/Chat.cs
rename to TGS.Server/Instance/Chat.cs
index ede8605480..7c37b4ec35 100644
--- a/TGServerService/ServerInstance/Chat.cs
+++ b/TGS.Server/Instance/Chat.cs
@@ -1,15 +1,15 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Linq;
using System.Collections.Generic;
-using System.Web.Script.Serialization;
-using TGServerService.ChatCommands;
-using TGServerService.ChatProviders;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Server.ChatCommands;
+using TGS.Server.ChatProviders;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
- sealed partial class ServerInstance : ITGChat
+ sealed partial class Instance : ITGChat
{
///
/// Used for indicating unintialized encrypted data
@@ -17,7 +17,7 @@ namespace TGServerService
public const string UninitializedString = "NEEDS INITIALIZING";
///
- /// List of s for the
+ /// List of s for the
///
IList ChatProviders;
///
@@ -26,7 +26,7 @@ namespace TGServerService
object ChatLock = new object();
///
- /// Set up the for the
+ /// Set up the for the
///
public void InitChat()
{
@@ -112,9 +112,9 @@ namespace TGServerService
}
ChatProviders = null;
- var rawdata = new JavaScriptSerializer().Serialize(infosList);
+ var rawdata = JsonConvert.SerializeObject(infosList);
- Config.ChatProviderData = Helpers.EncryptData(rawdata, out string entrp);
+ Config.ChatProviderData = Interface.Helpers.EncryptData(rawdata, out string entrp);
Config.ChatProviderEntropy = entrp;
}
@@ -142,9 +142,9 @@ namespace TGServerService
string plaintext;
try
{
- plaintext = Helpers.DecryptData(rawdata, Config.ChatProviderEntropy);
+ plaintext = Interface.Helpers.DecryptData(rawdata, Config.ChatProviderEntropy);
- var lists = new JavaScriptSerializer().Deserialize>>(plaintext);
+ var lists = JsonConvert.DeserializeObject>>(plaintext);
var output = new List(lists.Count);
var foundirc = 0;
var founddiscord = 0;
diff --git a/TGServerService/ServerInstance/Compiler.cs b/TGS.Server/Instance/Compiler.cs
similarity index 97%
rename from TGServerService/ServerInstance/Compiler.cs
rename to TGS.Server/Instance/Compiler.cs
index cff03130b5..3ce9971504 100644
--- a/TGServerService/ServerInstance/Compiler.cs
+++ b/TGS.Server/Instance/Compiler.cs
@@ -6,12 +6,12 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
- sealed partial class ServerInstance : ITGCompiler
+ sealed partial class Instance : ITGCompiler
{
#region Win32 Shit
[DllImport("kernel32.dll", SetLastError = true)]
@@ -119,7 +119,7 @@ namespace TGServerService
//what is says on the tin
CompilerStatus IsInitialized()
{
- if (File.Exists(RelativePath(Path.Combine(GameDirLive, BridgeDLLName))) || File.Exists(RelativePath(Path.Combine(GameDirLive, Assembly.GetAssembly(typeof(IInterface)).GetName().Name + ".dll")))) //its a good tell, jim
+ if (File.Exists(RelativePath(Path.Combine(GameDirLive, BridgeDLLName))) || File.Exists(RelativePath(Path.Combine(GameDirLive, Assembly.GetAssembly(typeof(IServerInterface)).GetName().Name + ".dll")))) //its a good tell, jim
return CompilerStatus.Initialized;
return CompilerStatus.Uninitialized;
}
@@ -178,7 +178,7 @@ namespace TGServerService
{
SendMessage("DM: Setting up symlinks...", MessageType.DeveloperInfo);
CleanGameFolder();
- Program.DeleteDirectory(RelativePath(GameDir));
+ Helpers.DeleteDirectory(RelativePath(GameDir));
Directory.CreateDirectory(RelativePath(GameDirA));
Directory.CreateDirectory(RelativePath(GameDirB));
@@ -350,7 +350,7 @@ namespace TGServerService
var deleteExcludeList = new List { BridgeDLLName };
deleteExcludeList.AddRange(Config.StaticDirectoryPaths);
deleteExcludeList.AddRange(Config.DLLPaths);
- Program.DeleteDirectory(resurrectee, true, deleteExcludeList);
+ Helpers.DeleteDirectory(resurrectee, true, deleteExcludeList);
Directory.CreateDirectory(resurrectee + "/.git/logs");
@@ -372,11 +372,11 @@ namespace TGServerService
CreateSymlink(Path.Combine(resurrectee, BridgeDLLName), RelativePath(BridgeDLLName));
deleteExcludeList.Add(".git");
- Program.CopyDirectory(RelativePath(RepoPath), resurrectee, deleteExcludeList);
+ Helpers.CopyDirectory(RelativePath(RepoPath), resurrectee, deleteExcludeList);
CurrentSha = GetHead(false, out string error);
//just the tip
const string GitLogsDir = "/.git/logs";
- Program.CopyDirectory(RelativePath(RepoPath + GitLogsDir), resurrectee + GitLogsDir);
+ Helpers.CopyDirectory(RelativePath(RepoPath + GitLogsDir), resurrectee + GitLogsDir);
try
{
File.Copy(RelativePath(PRJobFile), Path.Combine(resurrectee, PRJobFile));
diff --git a/TGServerService/ServerInstance/Config.cs b/TGS.Server/Instance/Config.cs
similarity index 94%
rename from TGServerService/ServerInstance/Config.cs
rename to TGS.Server/Instance/Config.cs
index d59fef5909..57968b54cd 100644
--- a/TGServerService/ServerInstance/Config.cs
+++ b/TGS.Server/Instance/Config.cs
@@ -2,12 +2,12 @@
using System.Collections.Generic;
using System.IO;
using System.ServiceModel;
-using TGServiceInterface.Components;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
//knobs and such
- sealed partial class ServerInstance : ITGConfig
+ sealed partial class Instance : ITGConfig
{
///
/// Used for multithreading safety
@@ -75,7 +75,7 @@ namespace TGServerService
}
var output = File.ReadAllText(path);
- Service.CancelImpersonation();
+ Server.CancelImpersonation();
WriteInfo("Read of " + path, EventID.StaticRead);
error = null;
unauthorized = false;
@@ -92,7 +92,7 @@ namespace TGServerService
catch (Exception e)
{
error = e.ToString();
- Service.CancelImpersonation();
+ Server.CancelImpersonation();
WriteWarning(String.Format("Read of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead);
unauthorized = false;
return null;
@@ -131,7 +131,7 @@ namespace TGServerService
Directory.CreateDirectory(destdir);
File.WriteAllText(path, data);
- Service.CancelImpersonation();
+ Server.CancelImpersonation();
WriteInfo("Write to " + path, EventID.StaticWrite);
unauthorized = false;
return null;
@@ -146,7 +146,7 @@ namespace TGServerService
catch (Exception e)
{
unauthorized = false;
- Service.CancelImpersonation();
+ Server.CancelImpersonation();
WriteWarning(String.Format("Write of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead);
return e.ToString();
}
@@ -184,8 +184,8 @@ namespace TGServerService
if (fi.Exists)
File.Delete(path);
else if (Directory.Exists(path))
- Program.DeleteDirectory(path);
- Service.CancelImpersonation();
+ Helpers.DeleteDirectory(path);
+ Server.CancelImpersonation();
WriteInfo("Delete of " + path, EventID.StaticDelete);
unauthorized = false;
return null;
@@ -200,7 +200,7 @@ namespace TGServerService
catch (Exception e)
{
unauthorized = false;
- Service.CancelImpersonation();
+ Server.CancelImpersonation();
WriteWarning(String.Format("Delete of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead);
return e.ToString();
}
diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGS.Server/Instance/DreamDaemon.cs
similarity index 96%
rename from TGServerService/ServerInstance/DreamDaemon.cs
rename to TGS.Server/Instance/DreamDaemon.cs
index 113797efe9..a6846ab2ac 100644
--- a/TGServerService/ServerInstance/DreamDaemon.cs
+++ b/TGS.Server/Instance/DreamDaemon.cs
@@ -5,14 +5,14 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Timers;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
//manages the dd window.
//It's not possible to actually click it while starting it in CL mode, so in order to change visibility, security, etc. It restarts the process when the world reboots
- sealed partial class ServerInstance : ITGDreamDaemon
+ sealed partial class Instance : ITGDreamDaemon
{
enum ShutdownRequestPhase
{
@@ -519,9 +519,9 @@ namespace TGServerService
}
///
- /// Copies from the program directory to the the directory
+ /// Copies from the program directory to the the directory
///
- /// If , overwrites the 's current interface .dll if it exists
+ /// If , overwrites the 's current interface .dll if it exists
void UpdateBridgeDll(bool overwrite)
{
var rbdlln = RelativePath(BridgeDLLName);
@@ -530,19 +530,19 @@ namespace TGServerService
return;
//Copy the interface dll to the static dir
- var InterfacePath = Assembly.GetAssembly(typeof(IInterface)).Location;
+ var InterfacePath = Assembly.GetAssembly(typeof(IServerInterface)).Location;
//bridge is installed next to the interface
var BridgePath = Path.Combine(Path.GetDirectoryName(InterfacePath), BridgeDLLName);
#if DEBUG
//We could be debugging from the project directory
if (!File.Exists(BridgePath))
//A little hackish debug mode doctoring never hurt anyone
- BridgePath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(InterfacePath)))), "TGDreamDaemonBridge/bin/x86/Debug", BridgeDLLName);
+ BridgePath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(InterfacePath)))), "TGS.Interface.Bridge/bin/x86/Debug", BridgeDLLName);
#endif
try
{
//Use reflection to ensure these are the droids we're looking for
- Assembly.ReflectionOnlyLoadFrom(BridgePath).GetType(DreamDaemonBridgeType, true);
+ Assembly.ReflectionOnlyLoadFrom(BridgePath).GetType(String.Format("{0}.{1}.{2}.{3}", nameof(TGS), nameof(Interface), DreamDaemonBridgeNamespace, DreamDaemonBridgeType), true);
}
catch (Exception e)
{
@@ -721,7 +721,7 @@ namespace TGServerService
///
public string WorldAnnounce(string message)
{
- var res = SendCommand(SCWorldAnnounce + ";message=" + Program.SanitizeTopicString(message));
+ var res = SendCommand(SCWorldAnnounce + ";message=" + Helpers.SanitizeTopicString(message));
if (res == "SUCCESS")
return null;
return res;
diff --git a/TGServerService/ServerInstance/ServerInstance.cs b/TGS.Server/Instance/Instance.cs
similarity index 85%
rename from TGServerService/ServerInstance/ServerInstance.cs
rename to TGS.Server/Instance/Instance.cs
index dca0af9150..aaf98ef39a 100644
--- a/TGServerService/ServerInstance/ServerInstance.cs
+++ b/TGS.Server/Instance/Instance.cs
@@ -2,9 +2,9 @@
using System.Diagnostics;
using System.IO;
using System.ServiceModel;
-using TGServiceInterface.Components;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
//I know the fact that this is one massive partial class is gonna trigger everyone
//There really was no other succinct way to do it (<= He's lying through his teeth, don't listen to him)
@@ -15,7 +15,7 @@ namespace TGServerService
/// The class which holds all interface components. There are no safeguards for call race conditions so these must be guarded against internally
///
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
- sealed partial class ServerInstance : IDisposable, ITGConnectivity, ITGInstance
+ sealed partial class Instance : IDisposable, ITGConnectivity, ITGInstance
{
///
/// Used to assign the instance to event IDs
@@ -26,9 +26,9 @@ namespace TGServerService
///
readonly IInstanceConfig Config;
///
- /// Constructs and a
+ /// Constructs and a
///
- public ServerInstance(IInstanceConfig config, byte logID)
+ public Instance(IInstanceConfig config, byte logID)
{
LoggingID = logID;
Config = config;
@@ -42,7 +42,7 @@ namespace TGServerService
}
///
- /// Cleans up the
+ /// Cleans up the
///
void RunDisposals()
{
@@ -62,7 +62,7 @@ namespace TGServerService
/// The of the message
void WriteInfo(string message, EventID id)
{
- Service.WriteEntry(message, id, EventLogEntryType.Information, LoggingID);
+ Server.Logger.WriteInfo(message, id, LoggingID);
}
///
@@ -72,7 +72,7 @@ namespace TGServerService
/// The of the message
void WriteError(string message, EventID id)
{
- Service.WriteEntry(message, id, EventLogEntryType.Error, LoggingID);
+ Server.Logger.WriteError(message, id, LoggingID);
}
///
@@ -82,7 +82,7 @@ namespace TGServerService
/// The of the message
void WriteWarning(string message, EventID id)
{
- Service.WriteEntry(message, id, EventLogEntryType.Warning, LoggingID);
+ Server.Logger.WriteWarning(message, id, LoggingID);
}
///
@@ -92,11 +92,11 @@ namespace TGServerService
/// if authenticated sucessfully, otherwise
void WriteAccess(string username, bool authSuccess)
{
- Service.WriteEntry(String.Format("Access from: {0}", username), EventID.Authentication, authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, LoggingID);
+ Server.Logger.WriteAccess(String.Format("Access from: {0}", username), authSuccess, LoggingID);
}
///
- /// Converts relative paths to full directory paths
+ /// Converts relative paths to full directory paths
///
///
string RelativePath(string path)
@@ -107,7 +107,7 @@ namespace TGServerService
///
public string Version()
{
- return Service.VersionString;
+ return Server.VersionString;
}
///
diff --git a/TGServerService/ServerInstance/Interop.cs b/TGS.Server/Instance/Interop.cs
similarity index 94%
rename from TGServerService/ServerInstance/Interop.cs
rename to TGS.Server/Instance/Interop.cs
index ba64d4a372..3d934d4322 100644
--- a/TGServerService/ServerInstance/Interop.cs
+++ b/TGS.Server/Instance/Interop.cs
@@ -1,19 +1,19 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
-using System.Web.Script.Serialization;
using System.Web.Security;
-using TGServerService.ChatCommands;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Server.ChatCommands;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
//handles talking between the world and us
- sealed partial class ServerInstance : ITGInterop
+ sealed partial class Instance : ITGInterop
{
object topicLock = new object();
@@ -56,11 +56,11 @@ namespace TGServerService
///
/// The namespace that contains the bridge class. Used for reflection
///
- const string DreamDaemonBridgeNamespace = "TGDreamDaemonBridge";
+ const string DreamDaemonBridgeNamespace = "Bridge";
///
/// The bridge class. Used for reflection
///
- const string DreamDaemonBridgeType = DreamDaemonBridgeNamespace + ".DreamDaemonBridge";
+ const string DreamDaemonBridgeType = "DreamDaemonBridge";
List ServerChatCommands;
@@ -74,7 +74,7 @@ namespace TGServerService
List tmp = new List();
try
{
- foreach(var I in new JavaScriptSerializer().Deserialize>>(json))
+ foreach(var I in JsonConvert.DeserializeObject>>(json))
tmp.Add(new ServerChatCommand(I.Key, (string)I.Value[CCPHelpText], ((int)I.Value[CCPAdminOnly]) == 1, (int)I.Value[CCPRequiredParameters]));
ServerChatCommands = tmp;
}
diff --git a/TGServerService/ServerInstance/PreactionHandler.cs b/TGS.Server/Instance/PreactionHandler.cs
similarity index 97%
rename from TGServerService/ServerInstance/PreactionHandler.cs
rename to TGS.Server/Instance/PreactionHandler.cs
index 84bc7d8ff9..8fc1d14792 100644
--- a/TGServerService/ServerInstance/PreactionHandler.cs
+++ b/TGS.Server/Instance/PreactionHandler.cs
@@ -2,10 +2,10 @@
using System.Diagnostics;
using System.IO;
-namespace TGServerService
+namespace TGS.Server
{
// Some useful functions for triggering pre action events
- sealed partial class ServerInstance
+ sealed partial class Instance
{
///
/// The instance directory for Preaction handlers
diff --git a/TGServerService/ServerInstance/Repository.cs b/TGS.Server/Instance/Repository.cs
similarity index 95%
rename from TGServerService/ServerInstance/Repository.cs
rename to TGS.Server/Instance/Repository.cs
index fcf15b57f5..1b19efaec2 100644
--- a/TGServerService/ServerInstance/Repository.cs
+++ b/TGS.Server/Instance/Repository.cs
@@ -1,4 +1,6 @@
using LibGit2Sharp;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -6,16 +8,15 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
-using System.Web.Script.Serialization;
-using TGServiceInterface;
-using TGServiceInterface.Components;
+using TGS.Interface;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
- sealed partial class ServerInstance : ITGRepository, IDisposable
+ sealed partial class Instance : ITGRepository, IDisposable
{
///
- /// The directory for the repository
+ /// The directory for the repository
///
const string RepoPath = "Repository";
///
@@ -27,7 +28,7 @@ namespace TGServerService
///
const string RepoTGS3SettingsPath = RepoPath + "/TGS3.json";
///
- /// Path to the 's json
+ /// Path to the 's json
///
const string CachedTGS3SettingsPath = "TGS3.json";
///
@@ -39,7 +40,7 @@ namespace TGServerService
///
const string SSHPushRemote = "ssh_push_target";
///
- /// The directory for the repository SSH keys
+ /// The directory for the repository SSH keys
///
const string RepoKeyDir = "RepoKey/";
///
@@ -81,12 +82,12 @@ namespace TGServerService
///
Repository Repo;
///
- /// Used for reporting operation progress to the
+ /// Used for reporting operation progress to the
///
int currentProgress = -1;
///
- /// Used for automatically updating the
+ /// Used for automatically updating the
///
System.Timers.Timer autoUpdateTimer = new System.Timers.Timer()
{
@@ -231,7 +232,7 @@ namespace TGServerService
try
{
DisposeRepo();
- Program.DeleteDirectory(RelativePath(RepoPath));
+ Helpers.DeleteDirectory(RelativePath(RepoPath));
DeletePRList();
lock (configLock)
{
@@ -292,7 +293,7 @@ namespace TGServerService
}
///
- /// Copies the Static directory to the first available Static_BACKUP path in the then deleted the old directory
+ /// Copies the Static directory to the first available Static_BACKUP path in the then deleted the old directory
///
void BackupAndDeleteStaticDirectory()
{
@@ -311,9 +312,9 @@ namespace TGServerService
newFullPath = Path.Combine(path, tempDirName);
}
- Program.CopyDirectory(rsd, newFullPath);
+ Helpers.CopyDirectory(rsd, newFullPath);
}
- Program.DeleteDirectory(rsd);
+ Helpers.DeleteDirectory(rsd);
}
///
@@ -352,7 +353,7 @@ namespace TGServerService
var source = Path.Combine(RelativePath(RepoPath), I);
var dest = Path.Combine(RelativePath(StaticDirs), I);
if (Directory.Exists(source))
- Program.CopyDirectory(source, dest);
+ Helpers.CopyDirectory(source, dest);
else
Directory.CreateDirectory(dest);
}
@@ -372,7 +373,7 @@ namespace TGServerService
continue;
}
var dest = Path.Combine(RelativePath(StaticDirs), I);
- Program.CopyFileForceDirectories(source, dest, false);
+ Helpers.CopyFileForceDirectories(source, dest, false);
}
catch
{
@@ -712,7 +713,7 @@ namespace TGServerService
//kill off the modules/ folder in .git and try again
try
{
- Program.DeleteDirectory(String.Format("{0}/.git/modules/{1}", RepoPath, I.Path));
+ Helpers.DeleteDirectory(String.Format("{0}/.git/modules/{1}", RepoPath, I.Path));
}
catch
{
@@ -769,7 +770,7 @@ namespace TGServerService
}
///
- /// Lists tags in the repository created by the
+ /// Lists tags in the repository created by the
///
/// on success, error message on failure
/// A dictionary of tag title -> commit SHA on success, on failure
@@ -826,7 +827,7 @@ namespace TGServerService
}
///
- /// Deletes the 's
+ /// Deletes the 's
///
void DeletePRList()
{
@@ -850,8 +851,7 @@ namespace TGServerService
if (!File.Exists(RelativePath(PRJobFile)))
return new Dictionary>();
var rawdata = File.ReadAllText(RelativePath(PRJobFile));
- var Deserializer = new JavaScriptSerializer();
- return Deserializer.Deserialize>>(rawdata);
+ return JsonConvert.DeserializeObject>>(rawdata);
}
///
@@ -860,8 +860,7 @@ namespace TGServerService
///
void SetCurrentPRList(IDictionary> list)
{
- var Serializer = new JavaScriptSerializer();
- var rawdata = Serializer.Serialize(list);
+ var rawdata = JsonConvert.SerializeObject(list);
File.WriteAllText(RelativePath(PRJobFile), rawdata);
}
@@ -959,13 +958,12 @@ namespace TGServerService
string json;
using (var wc = new WebClient())
{
- wc.Headers.Add("user-agent", "TGStationServerService");
+ wc.Headers.Add("user-agent", "TGS.Server");
json = wc.DownloadString(prAPI);
}
- var Deserializer = new JavaScriptSerializer();
- var dick = Deserializer.DeserializeObject(json) as IDictionary;
- var user = dick["user"] as IDictionary;
+ var dick = JsonConvert.DeserializeObject>(json);
+ var user = ((JObject)dick["user"]).ToObject>();
newPR.Add("commit", atSHA ?? branch.Tip.Sha);
newPR.Add("author", (string)user["login"]);
@@ -1193,9 +1191,9 @@ namespace TGServerService
}
///
- /// Check if the is configured for SSH pushing
+ /// Check if the is configured for SSH pushing
///
- /// if the see cref="ServerInstance"/> is configured for SSH pushing, otherwise
+ /// if the see cref="Instance"/> is configured for SSH pushing, otherwise
bool SSHAuth()
{
return File.Exists(RelativePath(PrivateKeyPath)) && File.Exists(RelativePath(PublicKeyPath));
@@ -1271,9 +1269,8 @@ namespace TGServerService
return null;
}
- var Config = Properties.Settings.Default;
-
- var PythonFile = Path.Combine(Config.PythonPath, "python.exe");
+ var pp = Server.Config.PythonPath;
+ var PythonFile = Path.Combine(pp, "python.exe");
if (!File.Exists(PythonFile))
{
error = "Cannot locate python!";
@@ -1308,7 +1305,7 @@ namespace TGServerService
}
//update pip deps and try again
- string PipFile = Config.PythonPath + "/scripts/pip.exe";
+ string PipFile = Path.Combine(pp, "scripts", "pip.exe");
foreach(var I in RConfig.PipDependancies)
using (var pip = new Process())
{
@@ -1365,7 +1362,7 @@ namespace TGServerService
}
///
- /// Runs on the configured of and tries to and the
+ /// Runs on the configured of and tries to and the
///
/// A
/// The event arguments
diff --git a/TGServerService/InstanceConfig.cs b/TGS.Server/InstanceConfig.cs
similarity index 78%
rename from TGServerService/InstanceConfig.cs
rename to TGS.Server/InstanceConfig.cs
index a7afc8ab5f..6714e9052f 100644
--- a/TGServerService/InstanceConfig.cs
+++ b/TGS.Server/InstanceConfig.cs
@@ -1,16 +1,16 @@
-using System.IO;
-using System.Web.Script.Serialization;
-using TGServiceInterface;
+using Newtonsoft.Json;
+using System.IO;
+using TGS.Interface;
-namespace TGServerService
+namespace TGS.Server
{
///
- /// Configuration settings for a
+ /// Configuration settings for a
///
public interface IInstanceConfig
{
///
- /// The directory this is for
+ /// The directory this is for
///
string Directory { get; }
@@ -20,32 +20,32 @@ namespace TGServerService
ulong Version { get; }
///
- /// The name of the
+ /// The name of the
///
string Name { get; set; }
///
- /// If the is active
+ /// If the is active
///
bool Enabled { get; set; }
///
- /// The name of the .dme/.dmb the uses
+ /// The name of the .dme/.dmb the uses
///
string ProjectName { get; set; }
///
- /// The port the runs on
+ /// The port the runs on
///
ushort Port { get; set; }
///
- /// The level for the
+ /// The level for the
///
DreamDaemonSecurity Security { get; set; }
///
- /// Whether or not the should immediately start DreamDaemon when activated
+ /// Whether or not the should immediately start DreamDaemon when activated
///
bool Autostart { get; set; }
@@ -74,7 +74,7 @@ namespace TGServerService
string ChatProviderEntropy { get; set; }
///
- /// If the should reattach to a running DreamDaemon
+ /// If the should reattach to a running DreamDaemon
///
bool ReattachRequired { get; set; }
@@ -99,12 +99,12 @@ namespace TGServerService
string ReattachAPIVersion { get; set; }
///
- /// The user group allowed to use the
+ /// The user group allowed to use the
///
string AuthorizedUserGroupSID { get; set; }
///
- /// The auto update interval for the
+ /// The auto update interval for the
///
ulong AutoUpdateInterval { get; set; }
@@ -114,7 +114,7 @@ namespace TGServerService
bool PushTestmergeCommits { get; set; }
///
- /// Saves the to it's
+ /// Saves the to it's
///
void Save();
}
@@ -125,17 +125,17 @@ namespace TGServerService
///
/// The name the file is saved as in the
///
- [ScriptIgnore]
+ [JsonIgnore]
public const string JSONFilename = "Instance.json";
///
/// The current version of the config
///
- [ScriptIgnore]
+ [JsonIgnore]
protected const ulong CurrentVersion = 0; //Literally any time you add/deprecated a field, this number needs to be bumped
///
- [ScriptIgnore]
+ [JsonIgnore]
public string Directory { get; private set; }
///
@@ -169,7 +169,7 @@ namespace TGServerService
public string CommitterEmail { get; set; } = "tgstation-server@tgstation13.org";
///
- public string ChatProviderData { get; set; } = ServerInstance.UninitializedString;
+ public string ChatProviderData { get; set; } = Instance.UninitializedString;
///
public string ChatProviderEntropy { get; set; }
@@ -199,9 +199,9 @@ namespace TGServerService
public bool PushTestmergeCommits { get; set; } = false;
///
- /// Construct a for a at
+ /// Construct a for a at
///
- /// The path to the
+ /// The path to the
public InstanceConfig(string path)
{
Directory = path;
@@ -210,20 +210,20 @@ namespace TGServerService
///
public void Save()
{
- var data = new JavaScriptSerializer().Serialize(this);
+ var data = JsonConvert.SerializeObject(this);
var path = Path.Combine(Directory, JSONFilename);
File.WriteAllText(path, data);
}
///
- /// Loads and migrates an from a at
+ /// Loads and migrates an from a at
///
- /// The path to the directory
+ /// The path to the directory
/// The migrated
public static IInstanceConfig Load(string path)
{
var configtext = File.ReadAllText(Path.Combine(path, JSONFilename));
- var res = new JavaScriptSerializer().Deserialize(configtext);
+ var res = JsonConvert.DeserializeObject(configtext);
res.Directory = path;
res.MigrateToCurrentVersion();
return res;
diff --git a/TGServerService/MessageType.cs b/TGS.Server/MessageType.cs
similarity index 95%
rename from TGServerService/MessageType.cs
rename to TGS.Server/MessageType.cs
index 8db0cf2298..72d930bb0e 100644
--- a/TGServerService/MessageType.cs
+++ b/TGS.Server/MessageType.cs
@@ -1,6 +1,6 @@
using System;
-namespace TGServerService
+namespace TGS.Server
{
///
/// Type of chat message, these may be OR'd together
diff --git a/TGServerService/ProcessExtension.cs b/TGS.Server/ProcessExtension.cs
similarity index 98%
rename from TGServerService/ProcessExtension.cs
rename to TGS.Server/ProcessExtension.cs
index ecf336a9a0..0d24a8351c 100644
--- a/TGServerService/ProcessExtension.cs
+++ b/TGS.Server/ProcessExtension.cs
@@ -2,7 +2,7 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
-namespace TGServerService
+namespace TGS.Server
{
///
/// Helpers to ing and a . Lightly massaged code from https://stackoverflow.com/a/13109774. Documentation linked from MSDN on 20/10/2017
diff --git a/TGServerService/Properties/AssemblyInfo.cs b/TGS.Server/Properties/AssemblyInfo.cs
similarity index 81%
rename from TGServerService/Properties/AssemblyInfo.cs
rename to TGS.Server/Properties/AssemblyInfo.cs
index e9ebd6fc8c..5dc00523b0 100644
--- a/TGServerService/Properties/AssemblyInfo.cs
+++ b/TGS.Server/Properties/AssemblyInfo.cs
@@ -1,16 +1,16 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TGStation Server Service")]
-[assembly: AssemblyDescription("Server Service for running BYOND games")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f32eda25-0855-411c-af5e-f0d042917e2d")]
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TGStation Server")]
+[assembly: AssemblyDescription("Server management suite for running BYOND games")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f32eda25-0855-411c-af5e-f0d042917e2d")]
diff --git a/TGS.Server/Properties/Settings.Designer.cs b/TGS.Server/Properties/Settings.Designer.cs
new file mode 100644
index 0000000000..c667781590
--- /dev/null
+++ b/TGS.Server/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TGS.Server.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/TGS.Server/Properties/Settings.settings b/TGS.Server/Properties/Settings.settings
new file mode 100644
index 0000000000..8e615f25fd
--- /dev/null
+++ b/TGS.Server/Properties/Settings.settings
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/TGServerService/RepoConfig.cs b/TGS.Server/RepoConfig.cs
similarity index 90%
rename from TGServerService/RepoConfig.cs
rename to TGS.Server/RepoConfig.cs
index d406e658ff..8096c6783f 100644
--- a/TGServerService/RepoConfig.cs
+++ b/TGS.Server/RepoConfig.cs
@@ -1,18 +1,19 @@
-using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Web.Script.Serialization;
-namespace TGServerService
+namespace TGS.Server
{
///
- /// Repository specific information for a
+ /// Repository specific information for a
///
sealed class RepoConfig : IEquatable
{
///
- /// If this json is setup to support
+ /// If this json is setup to support
///
public readonly bool ChangelogSupport;
///
@@ -32,7 +33,7 @@ namespace TGServerService
///
public readonly IList PathsToStage = new List();
///
- /// Directory's whose contents should not be touched when the updates
+ /// Directory's whose contents should not be touched when the updates
///
public readonly IList StaticDirectoryPaths = new List();
///
@@ -49,11 +50,10 @@ namespace TGServerService
if (!File.Exists(path))
return;
var rawdata = File.ReadAllText(path);
- var Deserializer = new JavaScriptSerializer();
- var json = Deserializer.Deserialize>(rawdata);
+ var json = JsonConvert.DeserializeObject>(rawdata);
try
{
- var details = (IDictionary)json["changelog"];
+ var details = ((JObject)json["changelog"]).ToObject>();
PathToChangelogPy = (string)details["script"];
ChangelogPyArguments = (string)details["arguments"];
ChangelogSupport = true;
diff --git a/TGServerService/RootAuthorizationManager.cs b/TGS.Server/RootAuthorizationManager.cs
similarity index 81%
rename from TGServerService/RootAuthorizationManager.cs
rename to TGS.Server/RootAuthorizationManager.cs
index f3f45d0983..8d80dc48ed 100644
--- a/TGServerService/RootAuthorizationManager.cs
+++ b/TGS.Server/RootAuthorizationManager.cs
@@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Security.Principal;
using System.ServiceModel;
-using TGServiceInterface.Components;
+using TGS.Interface.Components;
-namespace TGServerService
+namespace TGS.Server
{
///
/// A used to determine only if the caller is an admin
@@ -33,7 +32,7 @@ namespace TGServerService
if (LastSeenUser != user)
{
LastSeenUser = user;
- Service.WriteEntry(String.Format("Root access from: {0}", user), EventID.Authentication, authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, Service.LoggingID);
+ Server.Logger.WriteAccess(String.Format("Root access from: {0}", user), authSuccess, Server.LoggingID);
}
return authSuccess;
}
diff --git a/TGServerService/Service.cs b/TGS.Server/Server.cs
similarity index 63%
rename from TGServerService/Service.cs
rename to TGS.Server/Server.cs
index 0486e7c5de..5098a590d7 100644
--- a/TGServerService/Service.cs
+++ b/TGS.Server/Server.cs
@@ -1,693 +1,690 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Diagnostics;
-using System.IO;
-using System.Security.Principal;
-using System.ServiceModel;
-using System.ServiceProcess;
-using TGServiceInterface;
-using TGServiceInterface.Components;
-
-namespace TGServerService
-{
- ///
- /// The windows service the application runs as
- ///
- [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
- class Service : ServiceBase, ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager
- {
- ///
- /// The logging ID used for events
- ///
- public const byte LoggingID = 0;
-
- ///
- /// The service version based on the
- ///
- public static readonly string VersionString = "/tg/station 13 Server Service v" + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion;
-
- ///
- /// Singleton instance
- ///
- static Service ActiveService;
-
- ///
- /// Cancels WCF's user impersonation to allow clean access to writing log files
- ///
- public static void CancelImpersonation()
- {
- WindowsIdentity.Impersonate(IntPtr.Zero);
- }
-
- ///
- /// Writes an event to Windows the event log
- ///
- /// The log message
- /// The of the message
- /// The of the event
- /// The logging source ID for the event
- public static void WriteEntry(string message, EventID id, EventLogEntryType eventType, byte loggingID)
- {
- ActiveService.EventLog.WriteEntry(message, eventType, (int)id + loggingID);
- }
-
- ///
- /// Checks an for illegal characters
- ///
- /// The name to check
- /// if contains no illegal characters, error message otherwise
- static string CheckInstanceName(string instanceName)
- {
- char[] bannedCharacters = { ';', '&', '=', '%' };
- foreach (var I in bannedCharacters)
- if (instanceName.Contains(I.ToString()))
- return "Instance names may not contain the following characters: ';', '&', '=', or '%'";
- return null;
- }
-
- ///
- /// Sets up ServiceName and
- ///
- public Service()
- {
- ServiceName = "TG Station Server";
- if (ActiveService != null)
- throw new Exception("There is already a Service instance running!");
- ActiveService = this;
- }
-
- ///
- /// Clears
- ///
- /// if this method was invoked from , otherwise it was invoked by the finalizer
- protected override void Dispose(bool disposing)
- {
- ActiveService = null;
- base.Dispose(disposing);
- }
-
- ///
- /// The WCF host that contains connects to
- ///
- ServiceHost serviceHost;
- ///
- /// Map of to the respective hosting the
- ///
- IDictionary hosts;
- ///
- /// List of s in use
- ///
- IList UsedLoggingIDs = new List();
-
- ///
- /// Migrates the .NET config from to + 1
- ///
- /// The version to migrate from
- void MigrateSettings(int oldVersion)
- {
- var Config = Properties.Settings.Default;
- switch (oldVersion)
- {
- case 6: //switch to per-instance configs
- var IC = DeprecatedInstanceConfig.CreateFromNETSettings();
- IC.Save();
- Config.InstancePaths.Add(IC.Directory);
- break;
- }
- }
-
- ///
- /// Enumerates configured s. Detaches those that fail to load
- ///
- /// Each configured
- IEnumerable GetInstanceConfigs()
- {
- var pathsToRemove = new List();
- lock (this)
- {
- var IPS = Properties.Settings.Default.InstancePaths;
- foreach (var I in IPS)
- {
- IInstanceConfig ic;
- try
- {
- ic = InstanceConfig.Load(I);
- }
- catch (Exception e)
- {
- WriteEntry(String.Format("Unable load instance config at path {0}. Error: {1} Detaching...", I, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID);
- pathsToRemove.Add(I);
- continue;
- }
- yield return ic;
- }
- foreach (var I in pathsToRemove)
- IPS.Remove(I);
- }
- }
-
- ///
- /// Overrides and saves the configured if requested by command line parameters
- ///
- /// The command line parameters for the
- void ChangePortFromCommandLine(string[] args)
- {
- var Config = Properties.Settings.Default;
-
- for (var I = 0; I < args.Length - 1; ++I)
- if (args[I].ToLower() == "-port")
- {
- try
- {
- var res = Convert.ToUInt16(args[I + 1]);
- if (res == 0)
- throw new Exception("Cannot bind to port 0");
- Config.RemoteAccessPort = res;
- }
- catch (Exception e)
- {
- throw new Exception("Invalid argument for \"-port\"", e);
- }
- Config.Save();
- break;
- }
- }
-
- ///
- /// Called by the Windows service manager. Initializes and starts configured s
- ///
- /// Command line arguments for the
- protected override void OnStart(string[] args)
- {
- Environment.CurrentDirectory = Directory.CreateDirectory(Path.GetTempPath() + "/TGStationServerService").FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png
-
- SetupConfig();
-
- ChangePortFromCommandLine(args);
-
- SetupService();
-
- SetupInstances();
-
- OnlineAllHosts();
- }
-
- ///
- /// Writes some changes to the that always need to be done.
- ///
- void PrePrepConfig()
- {
- var Config = Properties.Settings.Default;
-
- if (Config.InstancePaths == null)
- Config.InstancePaths = new StringCollection();
- }
-
- ///
- /// Upgrades up the service configuration
- ///
- void SetupConfig()
- {
- var Config = Properties.Settings.Default;
- if (Config.UpgradeRequired)
- {
- var newVersion = Config.SettingsVersion;
- Config.Upgrade();
-
- PrePrepConfig();
-
- for (var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion)
- MigrateSettings(oldVersion);
-
- Config.SettingsVersion = newVersion;
-
- Config.UpgradeRequired = false;
- Config.Save();
- }
- else
- PrePrepConfig();
- }
-
- ///
- /// Creates the for
- ///
- void SetupService()
- {
- serviceHost = CreateHost(this, Interface.MasterInterfaceName);
- foreach (var I in Interface.ValidServiceInterfaces)
- AddEndpoint(serviceHost, I);
- serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us
- }
-
- ///
- /// Opens all created s
- ///
- void OnlineAllHosts()
- {
- serviceHost.Open();
- foreach (var I in hosts)
- I.Value.Open();
- }
-
- ///
- /// Creates a for using the default pipe, CloseTimeout for the , and the configured
- ///
- /// The
- /// The URL to access components on the
- /// The created
- static ServiceHost CreateHost(object singleton, string endpointPostfix)
- {
- return new ServiceHost(singleton, new Uri[] { new Uri(String.Format("net.pipe://localhost/{0}", endpointPostfix)), new Uri(String.Format("https://localhost:{0}/{1}", Properties.Settings.Default.RemoteAccessPort, endpointPostfix)) })
- {
- CloseTimeout = new TimeSpan(0, 0, 5)
- };
- }
-
- ///
- /// Creates s for all s as listed in , detaches bad ones
- ///
- void SetupInstances()
- {
- hosts = new Dictionary();
- var pathsToRemove = new List();
- var seenNames = new List();
- foreach (var I in GetInstanceConfigs())
- {
- if (seenNames.Contains(I.Name))
- {
- WriteEntry(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID);
- pathsToRemove.Add(I.Directory);
- }
- if (I.Enabled && SetupInstance(I) == null)
- pathsToRemove.Add(I.Directory);
- else
- seenNames.Add(I.Name);
- }
- foreach (var I in pathsToRemove)
- Properties.Settings.Default.InstancePaths.Remove(I);
- }
-
- ///
- /// Unlocks a acquired with
- ///
- /// The to unlock
- void UnlockLoggingID(byte ID)
- {
- lock (UsedLoggingIDs)
- {
- UsedLoggingIDs.Remove(ID);
- }
- }
-
- ///
- /// Gets and locks a
- ///
- /// A logging ID for the must be released using
- byte LockLoggingID()
- {
- lock (UsedLoggingIDs)
- {
- for (byte I = 1; I < 100; ++I)
- if (!UsedLoggingIDs.Contains(I))
- {
- UsedLoggingIDs.Add(I);
- return I;
- }
- }
- throw new Exception("All logging IDs in use!");
- }
-
- ///
- /// Creates and starts a for a at
- ///
- /// The for the
- /// The inactive on success, on failure
- ServiceHost SetupInstance(IInstanceConfig config)
- {
- ServerInstance instance;
- string instanceName;
- try
- {
- if (hosts.ContainsKey(config.Directory))
- {
- var datInstance = ((ServerInstance)hosts[config.Directory].SingletonInstance);
- WriteEntry(String.Format("Unable to start instance at path {0}. Has the same name as instance at path {1}. Detaching...", config.Directory, datInstance.ServerDirectory()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID);
- return null;
- }
- if (!config.Enabled)
- return null;
- var ID = LockLoggingID();
- WriteEntry(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, config.Directory, ID), EventID.InstanceIDAssigned, EventLogEntryType.Information, ID);
- instanceName = config.Name;
- instance = new ServerInstance(config, ID);
- }
- catch (Exception e)
- {
- WriteEntry(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", config.Directory, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID);
- return null;
- }
-
- var host = CreateHost(instance, String.Format("{0}/{1}", Interface.InstanceInterfaceName, instanceName));
- hosts.Add(instanceName, host);
-
- foreach (var J in Interface.ValidInstanceInterfaces)
- AddEndpoint(host, J);
-
- host.Authorization.ServiceAuthorizationManager = instance;
- return host;
- }
-
- ///
- /// Adds a WCF endpoint for a component
- ///
- /// The service host to add the component to
- /// The type of the component
- void AddEndpoint(ServiceHost host, Type typetype)
- {
- var bindingName = typetype.Name;
- host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = Interface.TransferLimitLocal }, bindingName);
- var httpsBinding = new WSHttpBinding()
- {
- SendTimeout = new TimeSpan(0, 0, 40),
- MaxReceivedMessageSize = Interface.TransferLimitRemote
- };
- var requireAuth = typetype.Name != typeof(ITGConnectivity).Name;
- httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
- httpsBinding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check
- httpsBinding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None;
- host.AddServiceEndpoint(typetype, httpsBinding, bindingName);
- }
-
- ///
- /// Shuts down all active s and calls on it's
- ///
- protected override void OnStop()
- {
- lock (this)
- {
- try
- {
- foreach (var I in hosts)
- {
- var host = I.Value;
- var instance = (ServerInstance)host.SingletonInstance;
- host.Close();
- instance.Dispose();
- UnlockLoggingID(instance.LoggingID);
- }
- }
- catch (Exception e)
- {
- WriteEntry(e.ToString(), EventID.ServiceShutdownFail, EventLogEntryType.Error, LoggingID);
- }
- serviceHost.Close();
- }
- Properties.Settings.Default.Save();
- ActiveService = null;
- }
-
- ///
- public void VerifyConnection() { }
-
- ///
- public void PrepareForUpdate()
- {
- foreach (var I in hosts)
- ((ServerInstance)I.Value.SingletonInstance).Reattach(false);
- }
-
- ///
- public ushort RemoteAccessPort()
- {
- return Properties.Settings.Default.RemoteAccessPort;
- }
-
- ///
- public string SetRemoteAccessPort(ushort port)
- {
- if (port == 0)
- return "Cannot bind to port 0";
- Properties.Settings.Default.RemoteAccessPort = port;
- return null;
- }
-
- ///
- public string Version()
- {
- return VersionString;
- }
-
- ///
- public bool SetPythonPath(string path)
- {
- if (!Directory.Exists(path))
- return false;
- Properties.Settings.Default.PythonPath = Path.GetFullPath(path);
- return true;
- }
-
- ///
- public string PythonPath()
- {
- return Properties.Settings.Default.PythonPath;
- }
-
- ///
- public IList ListInstances()
- {
- var result = new List();
- lock (this)
- foreach (var ic in GetInstanceConfigs())
- result.Add(new InstanceMetadata
- {
- Name = ic.Name,
- Path = ic.Directory,
- Enabled = ic.Enabled,
- LoggingID = (byte)(ic.Enabled ? ((ServerInstance)hosts[ic.Name].SingletonInstance).LoggingID : 0)
- });
- return result;
- }
-
- ///
- public string CreateInstance(string Name, string path)
- {
- path = Program.NormalizePath(path);
- var res = CheckInstanceName(Name);
- if (res != null)
- return res;
- if (File.Exists(path) || Directory.Exists(path))
- return "Cannot create instance at pre-existing path!";
- var Config = Properties.Settings.Default;
- lock (this)
- {
- if (Config.InstancePaths.Contains(path))
- return String.Format("Instance at {0} already exists!", path);
- foreach (var oic in GetInstanceConfigs())
- if (Name == oic.Name)
- return String.Format("Instance named {0} already exists!", oic.Name);
- IInstanceConfig ic;
- try
- {
- ic = new InstanceConfig(path)
- {
- Name = Name
- };
- Directory.CreateDirectory(path);
- ic.Save();
- Properties.Settings.Default.InstancePaths.Add(path);
- }
- catch (Exception e)
- {
- return e.ToString();
- }
- return SetupOneInstance(ic);
- }
- }
-
- ///
- /// Starts and onlines an instance located at
- ///
- /// The for the
- /// on success, error message on failure
- string SetupOneInstance(IInstanceConfig config)
- {
- if (!config.Enabled)
- return null;
- try
- {
- var host = SetupInstance(config);
- if (host != null)
- host.Open();
- else
- lock (this)
- Properties.Settings.Default.InstancePaths.Remove(config.Directory);
- return null;
- }
- catch (Exception e)
- {
- return "Instance set up but an error occurred while starting it: " + e.ToString();
- }
- }
-
- ///
- public string ImportInstance(string path)
- {
- path = Program.NormalizePath(path);
- var Config = Properties.Settings.Default;
- lock (this)
- {
- if (Config.InstancePaths.Contains(path))
- return String.Format("Instance at {0} already exists!", path);
- if(!Directory.Exists(path))
- return String.Format("There is no instance located at {0}!", path);
- IInstanceConfig ic;
- try
- {
- ic = InstanceConfig.Load(path);
- foreach(var oic in GetInstanceConfigs())
- if(ic.Name == oic.Name)
- return String.Format("Instance named {0} already exists!", oic.Name);
- ic.Save();
- Properties.Settings.Default.InstancePaths.Add(path);
- }
- catch (Exception e)
- {
- return e.ToString();
- }
- return SetupOneInstance(ic);
- }
- }
-
- ///
- public bool InstanceEnabled(string Name)
- {
- lock(this)
- {
- return hosts.ContainsKey(Name);
- }
- }
-
- ///
- public string SetInstanceEnabled(string Name, bool enabled)
- {
- return SetInstanceEnabledImpl(Name, enabled, out string path);
- }
-
-
- ///
- /// Sets a 's enabled status
- ///
- /// The whom's status should be changed
- /// to enable the , to disable it
- /// The path to the modified
- /// on success, error message on failure
- string SetInstanceEnabledImpl(string Name, bool enabled, out string path)
- {
- path = null;
- lock (this)
- {
- var hostIsOnline = hosts.ContainsKey(Name);
- if (enabled)
- {
- if (hostIsOnline)
- return null;
- foreach (var ic in GetInstanceConfigs())
- if (ic.Name == Name)
- {
- path = ic.Directory;
- ic.Enabled = true;
- ic.Save();
- return SetupOneInstance(ic);
- }
- return String.Format("Instance {0} does not exist!", Name);
- }
- else
- {
- if (!hostIsOnline)
- return null;
- var host = hosts[Name];
- hosts.Remove(Name);
- var inst = (ServerInstance)host.SingletonInstance;
- host.Close();
- path = inst.ServerDirectory();
- inst.Offline();
- inst.Dispose();
- UnlockLoggingID(inst.LoggingID);
- return null;
- }
- }
- }
-
- ///
- public string RenameInstance(string name, string new_name)
- {
- if (name == new_name)
- return null;
- var res = CheckInstanceName(new_name);
- if (res != null)
- return res;
- lock (this)
- {
- //we have to check em all anyway
- IInstanceConfig the_droid_were_looking_for = null;
- foreach (var ic in GetInstanceConfigs())
- if (ic.Name == name)
- {
- the_droid_were_looking_for = ic;
- break;
- }
- else if (ic.Name == new_name)
- return String.Format("There is already another instance named {0}!", new_name);
- if (the_droid_were_looking_for == null)
- return String.Format("There is no instance named {0}!", name);
- var ie = InstanceEnabled(name);
- if(ie)
- SetInstanceEnabled(name, false);
- the_droid_were_looking_for.Name = new_name;
- string result = "";
- try
- {
- the_droid_were_looking_for.Save();
- result = null;
- }
- catch(Exception e)
- {
- result = "Could not save instance config! Error: " + e.ToString();
- }
- finally
- {
- if (ie)
- {
- var resRestore = SetInstanceEnabled(new_name, true);
- if (resRestore != null)
- result = (result + " " + resRestore).Trim();
- }
- }
- return result;
- }
- }
-
- ///
- public string DetachInstance(string name)
- {
- lock (this)
- {
- var res = SetInstanceEnabledImpl(name, false, out string path);
- if (res != null)
- return res;
- if (path == null) //gotta find it ourselves
- foreach (var ic in GetInstanceConfigs())
- if (ic.Name == name)
- {
- path = ic.Directory;
- break;
- }
- if (path == null)
- return String.Format("No instance named {0} exists!", name);
- Properties.Settings.Default.InstancePaths.Remove(path);
- return null;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Security.Principal;
+using System.ServiceModel;
+using TGS.Interface;
+using TGS.Interface.Components;
+
+namespace TGS.Server
+{
+ ///
+ /// The windows service the application runs as
+ ///
+ [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
+ public sealed class Server : ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager, IDisposable
+ {
+ ///
+ /// The logging ID used for events
+ ///
+ public const byte LoggingID = 0;
+
+ ///
+ /// The directory to use when importing a .NET settings based config
+ ///
+ public const string MigrationConfigDirectory = "C:\\TGSSettingUpgradeTempDir";
+
+ ///
+ /// The service version based on the
+ ///
+ public static readonly string VersionString = "/tg/station 13 Server v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
+
+ ///
+ /// Singleton
+ ///
+ public static ILogger Logger { get; private set; }
+
+ ///
+ /// The for the
+ ///
+ public static ServerConfig Config { get; private set; }
+
+ ///
+ /// The directory to load and save s to
+ ///
+ static readonly string DefaultConfigDirectory = Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TGS.Server")).FullName;
+
+ ///
+ /// Cancels WCF's user impersonation to allow clean access to writing log files
+ ///
+ public static void CancelImpersonation()
+ {
+ WindowsIdentity.Impersonate(IntPtr.Zero);
+ }
+
+ ///
+ /// Checks an for illegal characters
+ ///
+ /// The name to check
+ /// if contains no illegal characters, error message otherwise
+ static string CheckInstanceName(string instanceName)
+ {
+ char[] bannedCharacters = { ';', '&', '=', '%' };
+ foreach (var I in bannedCharacters)
+ if (instanceName.Contains(I.ToString()))
+ return "Instance names may not contain the following characters: ';', '&', '=', or '%'";
+ return null;
+ }
+
+ ///
+ /// The WCF host that contains connects to
+ ///
+ ServiceHost serviceHost;
+ ///
+ /// Map of to the respective hosting the
+ ///
+ IDictionary hosts;
+ ///
+ /// List of s in use
+ ///
+ IList UsedLoggingIDs = new List();
+
+ ///
+ /// Construct a
+ ///
+ /// Command line arguments for the
+ /// The to use
+ public Server(string[] args, ILogger logger)
+ {
+ Logger = logger;
+
+ Environment.CurrentDirectory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name)).FullName; //MOVE THIS POINTER BECAUSE ONE TIME I ALMOST ACCIDENTALLY NUKED MYSELF BY REFACTORING! http://imgur.com/zvGEpJD.png
+
+ SetupConfig();
+
+ ChangePortFromCommandLine(args);
+
+ SetupService();
+
+ SetupInstances();
+
+ OnlineAllHosts();
+ }
+
+ ///
+ /// Enumerates configured s. Detaches those that fail to load
+ ///
+ /// Each configured
+ IEnumerable GetInstanceConfigs()
+ {
+ var pathsToRemove = new List();
+ lock (this)
+ {
+ var IPS = Config.InstancePaths;
+ foreach (var I in IPS)
+ {
+ IInstanceConfig ic;
+ try
+ {
+ ic = InstanceConfig.Load(I);
+ }
+ catch (Exception e)
+ {
+ Logger.WriteError(String.Format("Unable load instance config at path {0}. Error: {1} Detaching...", I, e.ToString()), EventID.InstanceInitializationFailure, LoggingID);
+ pathsToRemove.Add(I);
+ continue;
+ }
+ yield return ic;
+ }
+ foreach (var I in pathsToRemove)
+ IPS.Remove(I);
+ }
+ }
+
+ ///