mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-25 22:17:51 +01:00
Merge upstream
This commit is contained in:
@@ -8,7 +8,7 @@ namespace TGCommandLine
|
||||
{
|
||||
public CLICommand()
|
||||
{
|
||||
var tmp = new List<Command> { new UpdateCommand(), new TestmergeCommand(), new RepoCommand(), new BYONDCommand(), new DMCommand(), new DDCommand(), new ConfigCommand(), new IRCCommand(), new DiscordCommand() };
|
||||
var tmp = new List<Command> { new UpdateCommand(), new TestmergeCommand(), new RepoCommand(), new BYONDCommand(), new DMCommand(), new DDCommand(), new ConfigCommand(), new IRCCommand(), new DiscordCommand(), new AutoUpdateCommand(), new SetAutoUpdateCommand() };
|
||||
if (Server.VerifyConnection() == null && Server.Authenticate() && Server.AuthenticateAdmin())
|
||||
tmp.Add(new AdminCommand());
|
||||
Children = tmp.ToArray();
|
||||
@@ -20,6 +20,64 @@ namespace TGCommandLine
|
||||
base.PrintHelp();
|
||||
}
|
||||
}
|
||||
class AutoUpdateCommand : Command
|
||||
{
|
||||
public AutoUpdateCommand()
|
||||
{
|
||||
Keyword = "auto-update";
|
||||
}
|
||||
|
||||
public override string GetHelpText()
|
||||
{
|
||||
return "Get the interval in minutes that the server automatically updates";
|
||||
}
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
var res = Server.GetComponent<ITGRepository>().AutoUpdateInterval();
|
||||
OutputProc(res == 0 ? "OFF" : String.Format("Auto updating every {0} minutes", res));
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
}
|
||||
class SetAutoUpdateCommand : Command
|
||||
{
|
||||
public SetAutoUpdateCommand()
|
||||
{
|
||||
Keyword = "set-auto-update";
|
||||
RequiredParameters = 1;
|
||||
}
|
||||
|
||||
public override string GetArgumentString()
|
||||
{
|
||||
return "<off|interval in minutes>";
|
||||
}
|
||||
|
||||
public override string GetHelpText()
|
||||
{
|
||||
return "Set the interval in minutes that the server automatically updates";
|
||||
}
|
||||
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
ulong NewInterval;
|
||||
if (parameters[0].ToLower() == "off")
|
||||
NewInterval = 0;
|
||||
else
|
||||
try
|
||||
{
|
||||
NewInterval = Convert.ToUInt64(parameters[0]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
OutputProc("Invalid interval specified!");
|
||||
return ExitCode.BadCommand;
|
||||
}
|
||||
|
||||
Server.GetComponent<ITGRepository>().SetAutoUpdateInterval(NewInterval);
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
|
||||
}
|
||||
class UpdateCommand : Command
|
||||
{
|
||||
public UpdateCommand()
|
||||
|
||||
Generated
+70
-5
@@ -70,6 +70,9 @@
|
||||
this.AdminModeSpecial = new System.Windows.Forms.RadioButton();
|
||||
this.AdminModeNormal = new System.Windows.Forms.RadioButton();
|
||||
this.ServerPanel = new System.Windows.Forms.TabPage();
|
||||
this.AutoUpdateMLabel = new System.Windows.Forms.Label();
|
||||
this.AutoUpdateInterval = new System.Windows.Forms.NumericUpDown();
|
||||
this.AutoUpdateCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.ServerPageRefreshButton = new System.Windows.Forms.Button();
|
||||
this.AutostartCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.WebclientCheckBox = new System.Windows.Forms.CheckBox();
|
||||
@@ -160,6 +163,7 @@
|
||||
this.ChatProviderSelectorPanel.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.ServerPanel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.AutoUpdateInterval)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.PortSelector)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.ServerTestmergeInput)).BeginInit();
|
||||
this.BYONDPanel.SuspendLayout();
|
||||
@@ -631,6 +635,9 @@
|
||||
// ServerPanel
|
||||
//
|
||||
this.ServerPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(40)))), ((int)(((byte)(34)))));
|
||||
this.ServerPanel.Controls.Add(this.AutoUpdateMLabel);
|
||||
this.ServerPanel.Controls.Add(this.AutoUpdateInterval);
|
||||
this.ServerPanel.Controls.Add(this.AutoUpdateCheckbox);
|
||||
this.ServerPanel.Controls.Add(this.ServerPageRefreshButton);
|
||||
this.ServerPanel.Controls.Add(this.AutostartCheckbox);
|
||||
this.ServerPanel.Controls.Add(this.WebclientCheckBox);
|
||||
@@ -671,6 +678,60 @@
|
||||
this.ServerPanel.TabIndex = 2;
|
||||
this.ServerPanel.Text = "Server";
|
||||
//
|
||||
// AutoUpdateMLabel
|
||||
//
|
||||
this.AutoUpdateMLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.AutoUpdateMLabel.AutoSize = true;
|
||||
this.AutoUpdateMLabel.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.AutoUpdateMLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(242)))));
|
||||
this.AutoUpdateMLabel.Location = new System.Drawing.Point(433, 136);
|
||||
this.AutoUpdateMLabel.Name = "AutoUpdateMLabel";
|
||||
this.AutoUpdateMLabel.Size = new System.Drawing.Size(21, 18);
|
||||
this.AutoUpdateMLabel.TabIndex = 47;
|
||||
this.AutoUpdateMLabel.Text = "M";
|
||||
this.AutoUpdateMLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
this.AutoUpdateMLabel.Visible = false;
|
||||
//
|
||||
// AutoUpdateInterval
|
||||
//
|
||||
this.AutoUpdateInterval.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.AutoUpdateInterval.Location = new System.Drawing.Point(365, 135);
|
||||
this.AutoUpdateInterval.Maximum = new decimal(new int[] {
|
||||
276447231,
|
||||
23283,
|
||||
0,
|
||||
0});
|
||||
this.AutoUpdateInterval.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.AutoUpdateInterval.Name = "AutoUpdateInterval";
|
||||
this.AutoUpdateInterval.Size = new System.Drawing.Size(62, 20);
|
||||
this.AutoUpdateInterval.TabIndex = 46;
|
||||
this.AutoUpdateInterval.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.AutoUpdateInterval.Visible = false;
|
||||
this.AutoUpdateInterval.ValueChanged += new System.EventHandler(this.AutoUpdateInterval_ValueChanged);
|
||||
//
|
||||
// AutoUpdateCheckbox
|
||||
//
|
||||
this.AutoUpdateCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.AutoUpdateCheckbox.AutoSize = true;
|
||||
this.AutoUpdateCheckbox.Font = new System.Drawing.Font("Verdana", 12F);
|
||||
this.AutoUpdateCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(242)))));
|
||||
this.AutoUpdateCheckbox.Location = new System.Drawing.Point(228, 134);
|
||||
this.AutoUpdateCheckbox.Name = "AutoUpdateCheckbox";
|
||||
this.AutoUpdateCheckbox.Size = new System.Drawing.Size(131, 22);
|
||||
this.AutoUpdateCheckbox.TabIndex = 45;
|
||||
this.AutoUpdateCheckbox.Text = "Auto-Update";
|
||||
this.AutoUpdateCheckbox.UseVisualStyleBackColor = true;
|
||||
this.AutoUpdateCheckbox.Visible = false;
|
||||
this.AutoUpdateCheckbox.CheckedChanged += new System.EventHandler(this.AutoUpdateCheckbox_CheckedChanged);
|
||||
//
|
||||
// ServerPageRefreshButton
|
||||
//
|
||||
this.ServerPageRefreshButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
@@ -713,7 +774,7 @@
|
||||
// WorldAnnounceButton
|
||||
//
|
||||
this.WorldAnnounceButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.WorldAnnounceButton.Location = new System.Drawing.Point(785, 136);
|
||||
this.WorldAnnounceButton.Location = new System.Drawing.Point(785, 133);
|
||||
this.WorldAnnounceButton.Name = "WorldAnnounceButton";
|
||||
this.WorldAnnounceButton.Size = new System.Drawing.Size(77, 20);
|
||||
this.WorldAnnounceButton.TabIndex = 41;
|
||||
@@ -724,7 +785,7 @@
|
||||
// WorldAnnounceField
|
||||
//
|
||||
this.WorldAnnounceField.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.WorldAnnounceField.Location = new System.Drawing.Point(566, 136);
|
||||
this.WorldAnnounceField.Location = new System.Drawing.Point(566, 134);
|
||||
this.WorldAnnounceField.Name = "WorldAnnounceField";
|
||||
this.WorldAnnounceField.Size = new System.Drawing.Size(213, 20);
|
||||
this.WorldAnnounceField.TabIndex = 40;
|
||||
@@ -751,7 +812,7 @@
|
||||
this.WorldAnnounceLabel.AutoSize = true;
|
||||
this.WorldAnnounceLabel.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.WorldAnnounceLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(242)))));
|
||||
this.WorldAnnounceLabel.Location = new System.Drawing.Point(466, 139);
|
||||
this.WorldAnnounceLabel.Location = new System.Drawing.Point(466, 135);
|
||||
this.WorldAnnounceLabel.Name = "WorldAnnounceLabel";
|
||||
this.WorldAnnounceLabel.Size = new System.Drawing.Size(94, 18);
|
||||
this.WorldAnnounceLabel.TabIndex = 39;
|
||||
@@ -766,7 +827,7 @@
|
||||
"Trusted",
|
||||
"Safe",
|
||||
"Ultrasafe"});
|
||||
this.SecuritySelector.Location = new System.Drawing.Point(136, 136);
|
||||
this.SecuritySelector.Location = new System.Drawing.Point(101, 134);
|
||||
this.SecuritySelector.Name = "SecuritySelector";
|
||||
this.SecuritySelector.Size = new System.Drawing.Size(121, 21);
|
||||
this.SecuritySelector.TabIndex = 38;
|
||||
@@ -777,7 +838,7 @@
|
||||
this.SecurityTitle.AutoSize = true;
|
||||
this.SecurityTitle.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.SecurityTitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(242)))));
|
||||
this.SecurityTitle.Location = new System.Drawing.Point(44, 139);
|
||||
this.SecurityTitle.Location = new System.Drawing.Point(15, 139);
|
||||
this.SecurityTitle.Name = "SecurityTitle";
|
||||
this.SecurityTitle.Size = new System.Drawing.Size(80, 18);
|
||||
this.SecurityTitle.TabIndex = 37;
|
||||
@@ -1758,6 +1819,7 @@
|
||||
this.panel1.PerformLayout();
|
||||
this.ServerPanel.ResumeLayout(false);
|
||||
this.ServerPanel.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.AutoUpdateInterval)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.PortSelector)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.ServerTestmergeInput)).EndInit();
|
||||
this.BYONDPanel.ResumeLayout(false);
|
||||
@@ -1901,5 +1963,8 @@
|
||||
private System.Windows.Forms.Button BYONDRefreshButton;
|
||||
private System.Windows.Forms.Button ServerPageRefreshButton;
|
||||
private System.Windows.Forms.Button RecreateStaticButton;
|
||||
private System.Windows.Forms.NumericUpDown AutoUpdateInterval;
|
||||
private System.Windows.Forms.CheckBox AutoUpdateCheckbox;
|
||||
private System.Windows.Forms.Label AutoUpdateMLabel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace TGControlPanel
|
||||
{
|
||||
switch (Panels.SelectedIndex)
|
||||
{
|
||||
case 0: //repo
|
||||
PopulateRepoFields();
|
||||
break;
|
||||
case 1: //byond
|
||||
UpdateBYONDButtons();
|
||||
break;
|
||||
|
||||
@@ -107,6 +107,7 @@ namespace TGControlPanel
|
||||
{
|
||||
var RepoExists = Server.GetComponent<ITGRepository>().Exists();
|
||||
compileButton.Visible = RepoExists;
|
||||
AutoUpdateCheckbox.Visible = RepoExists;
|
||||
initializeButton.Visible = RepoExists;
|
||||
AutostartCheckbox.Visible = RepoExists;
|
||||
WebclientCheckBox.Visible = RepoExists;
|
||||
@@ -133,12 +134,13 @@ namespace TGControlPanel
|
||||
WorldAnnounceButton.Visible = RepoExists;
|
||||
WorldAnnounceLabel.Visible = RepoExists;
|
||||
|
||||
if (updatingFields)
|
||||
return;
|
||||
|
||||
var DM = Server.GetComponent<ITGCompiler>();
|
||||
var DD = Server.GetComponent<ITGDreamDaemon>();
|
||||
var Config = Server.GetComponent<ITGConfig>();
|
||||
|
||||
if (updatingFields)
|
||||
return;
|
||||
var Repo = Server.GetComponent<ITGRepository>();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -152,6 +154,14 @@ namespace TGControlPanel
|
||||
if (!RepoExists)
|
||||
return;
|
||||
|
||||
var interval = Repo.AutoUpdateInterval();
|
||||
var interval_not_zero = interval != 0;
|
||||
AutoUpdateCheckbox.Checked = interval_not_zero;
|
||||
AutoUpdateInterval.Visible = interval_not_zero;
|
||||
AutoUpdateMLabel.Visible = interval_not_zero;
|
||||
if (interval_not_zero)
|
||||
AutoUpdateInterval.Value = interval;
|
||||
|
||||
var DaeStat = DD.DaemonStatus();
|
||||
var Online = DaeStat == TGDreamDaemonStatus.Online;
|
||||
ServerStartButton.Enabled = !Online;
|
||||
@@ -473,5 +483,24 @@ namespace TGControlPanel
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetWebclient(WebclientCheckBox.Checked);
|
||||
}
|
||||
|
||||
private void AutoUpdateInterval_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGRepository>().SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value);
|
||||
}
|
||||
|
||||
private void AutoUpdateCheckbox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (updatingFields)
|
||||
return;
|
||||
var on = AutoUpdateCheckbox.Visible && AutoUpdateCheckbox.Checked;
|
||||
AutoUpdateInterval.Visible = on;
|
||||
AutoUpdateMLabel.Visible = on;
|
||||
if (!on)
|
||||
Server.GetComponent<ITGRepository>().SetAutoUpdateInterval(0);
|
||||
else
|
||||
Server.GetComponent<ITGRepository>().SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers>
|
||||
<Costura />
|
||||
</Weavers>
|
||||
Generated
+8
-3
@@ -1,4 +1,8 @@
|
||||
namespace TGInstallerWrapper
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace TGInstallerWrapper
|
||||
{
|
||||
partial class Main
|
||||
{
|
||||
@@ -127,7 +131,7 @@
|
||||
this.VersionLabel.Name = "VersionLabel";
|
||||
this.VersionLabel.Size = new System.Drawing.Size(228, 18);
|
||||
this.VersionLabel.TabIndex = 8;
|
||||
this.VersionLabel.Text = "None (No Service Running)";
|
||||
this.VersionLabel.Text = "Unknown (No service running)";
|
||||
//
|
||||
// InstallButton
|
||||
//
|
||||
@@ -160,7 +164,7 @@
|
||||
this.TargetVersionLabel.Name = "TargetVersionLabel";
|
||||
this.TargetVersionLabel.Size = new System.Drawing.Size(132, 18);
|
||||
this.TargetVersionLabel.TabIndex = 11;
|
||||
this.TargetVersionLabel.Text = "Target Version:";
|
||||
this.TargetVersionLabel.Text = "Target Version: v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
|
||||
//
|
||||
// InstallCancelButton
|
||||
//
|
||||
@@ -179,6 +183,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(40)))), ((int)(((byte)(34)))));
|
||||
this.ClientSize = new System.Drawing.Size(537, 153);
|
||||
this.FormClosing += Main_FormClosing;
|
||||
this.Controls.Add(this.InstallCancelButton);
|
||||
this.Controls.Add(this.TargetVersionLabel);
|
||||
this.Controls.Add(this.ShowLogCheckbox);
|
||||
|
||||
+102
-36
@@ -3,36 +3,122 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using TGServiceInterface;
|
||||
|
||||
namespace TGInstallerWrapper
|
||||
{
|
||||
public partial class Main : Form
|
||||
{
|
||||
const string InstallDir = "TG Station Server"; //keep this in sync with the msi installer
|
||||
const string DefaultInstallDir = "TG Station Server"; //keep this in sync with the msi installer
|
||||
|
||||
//reflection shit, make sure it matches
|
||||
const string InterfaceDLL = "TGServiceInterface.dll";
|
||||
const string InterfaceNamespace = "TGServiceInterface";
|
||||
const string InterfaceClass = InterfaceNamespace + ".Server";
|
||||
const string InterfaceServiceInterface = InterfaceNamespace + ".ITGSService"; //fuck this typo
|
||||
const string InterfaceClassVerifyConnection = "VerifyConnection";
|
||||
const string InterfaceClassGetComponent = "GetComponent";
|
||||
const string InterfaceServiceInterfaceVersion = "Version";
|
||||
const string InterfaceServiceInterfacePrepareForUpdate = "PrepareForUpdate";
|
||||
|
||||
Assembly InterfaceAssembly;
|
||||
Type Server, ITGSService;
|
||||
MethodInfo VerifyConnection, GetComponentITGSService, Version, PrepareForUpdate;
|
||||
|
||||
string tempDir;
|
||||
bool installing = false;
|
||||
bool cancelled = false;
|
||||
bool pathIsDefault = true;
|
||||
|
||||
public Main()
|
||||
{
|
||||
InitializeComponent();
|
||||
FormClosing += Main_FormClosing;
|
||||
PathTextBox.Text = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + Path.DirectorySeparatorChar + InstallDir;
|
||||
var verifiedConnection = Server.VerifyConnection() == null;
|
||||
SetupTempDir();
|
||||
LoadInterfaceFromReflection();
|
||||
CheckForExistingVersion();
|
||||
PathTextBox.Text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), DefaultInstallDir);
|
||||
}
|
||||
|
||||
void SetupTempDir()
|
||||
{
|
||||
tempDir = Path.Combine(Path.GetTempPath(), "TGS3InstallerTempDir");
|
||||
try
|
||||
{
|
||||
VersionLabel.Text = Server.GetComponent<ITGSService>().Version();
|
||||
if (File.Exists(tempDir))
|
||||
File.Delete(tempDir);
|
||||
else if (Directory.Exists(tempDir))
|
||||
Directory.Delete(tempDir);
|
||||
}
|
||||
catch { }
|
||||
if (File.Exists(tempDir) || Directory.Exists(tempDir))
|
||||
{
|
||||
tempDir = Path.GetTempFileName();
|
||||
File.Delete(tempDir); //we want a dir not a file
|
||||
}
|
||||
Directory.CreateDirectory(tempDir);
|
||||
}
|
||||
|
||||
void LoadInterfaceFromReflection()
|
||||
{
|
||||
//so this is where we expect to find the interface dll
|
||||
try
|
||||
{
|
||||
var tmppath = Path.Combine(tempDir, InterfaceDLL);
|
||||
File.WriteAllBytes(tmppath, Properties.Resources.TGServiceInterface);
|
||||
InterfaceAssembly = Assembly.LoadFrom(tmppath); //we can't link to it, or load the bytes directly because the thing will complain about mixing the DLLExport code and IL code
|
||||
Server = InterfaceAssembly.GetType(InterfaceClass);
|
||||
ITGSService = InterfaceAssembly.GetType(InterfaceServiceInterface);
|
||||
VerifyConnection = Server.GetMethod(InterfaceClassVerifyConnection);
|
||||
GetComponentITGSService = Server.GetMethod(InterfaceClassGetComponent).MakeGenericMethod(ITGSService);
|
||||
Version = ITGSService.GetMethod(InterfaceServiceInterfaceVersion);
|
||||
PrepareForUpdate = ITGSService.GetMethod(InterfaceServiceInterfacePrepareForUpdate);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if(verifiedConnection)
|
||||
InterfaceAssembly = null;
|
||||
VersionLabel.Text = "Error: (Could not load interface dll)";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckForExistingVersion() {
|
||||
if (InterfaceAssembly == null)
|
||||
return;
|
||||
var verifiedConnection = VerifyConnection.Invoke(null, null) == null;
|
||||
try
|
||||
{
|
||||
VersionLabel.Text = (string)Version.Invoke(GetComponentITGSService.Invoke(null, null), null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (verifiedConnection)
|
||||
VersionLabel.Text = "< v3.0.85.0 (Missing ITGService.Version())";
|
||||
}
|
||||
TargetVersionLabel.Text += " v" + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion;
|
||||
}
|
||||
|
||||
bool ConfirmDangerousUpgrade()
|
||||
{
|
||||
return MessageBox.Show("Unable connect to service! Existing DreamDaemon instances will be terminated. Continue?", "Warning", MessageBoxButtons.YesNo) == DialogResult.Yes;
|
||||
}
|
||||
|
||||
bool TellServiceWereComingForThem()
|
||||
{
|
||||
if (InterfaceAssembly == null)
|
||||
return ConfirmDangerousUpgrade();
|
||||
var connectionVerified = VerifyConnection.Invoke(null, null) == null;
|
||||
try
|
||||
{
|
||||
PrepareForUpdate.Invoke(GetComponentITGSService.Invoke(null, null), null);
|
||||
Thread.Sleep(3000); //chat messages
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return ConfirmDangerousUpgrade();
|
||||
}
|
||||
}
|
||||
|
||||
private void Main_FormClosing(object sender, FormClosingEventArgs e)
|
||||
@@ -71,7 +157,6 @@ namespace TGInstallerWrapper
|
||||
|
||||
async void DoInstall()
|
||||
{
|
||||
string path = null;
|
||||
string logfile = null;
|
||||
try
|
||||
{
|
||||
@@ -90,6 +175,9 @@ namespace TGInstallerWrapper
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TellServiceWereComingForThem())
|
||||
return;
|
||||
|
||||
var args = new List<string>();
|
||||
if (!pathIsDefault)
|
||||
args.Add(String.Format("INSTALLFOLDER=\"{0}\"", PathTextBox.Text));
|
||||
@@ -108,32 +196,16 @@ namespace TGInstallerWrapper
|
||||
ShowLogCheckbox.Enabled = false;
|
||||
InstallButton.Text = "Installing...";
|
||||
|
||||
path = Path.GetTempFileName();
|
||||
File.Delete(path); //we want a dir not a file
|
||||
Directory.CreateDirectory(path);
|
||||
var msipath = path + Path.DirectorySeparatorChar + "TGServiceInstaller.msi";
|
||||
var msipath = Path.Combine(tempDir, "TGServiceInstaller.msi");
|
||||
File.WriteAllBytes(msipath, Properties.Resources.TGServiceInstaller);
|
||||
File.WriteAllBytes(path + Path.DirectorySeparatorChar + "cab1.cab", Properties.Resources.cab1);
|
||||
File.WriteAllBytes(Path.Combine(tempDir, "cab1.cab"), Properties.Resources.cab1);
|
||||
|
||||
ProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
|
||||
var connectionVerified = Server.VerifyConnection() == null;
|
||||
try
|
||||
{
|
||||
Server.GetComponent<ITGSService>().PrepareForUpdate();
|
||||
Thread.Sleep(3000); //chat messages
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (connectionVerified && MessageBox.Show("ITGSService.PrepareForUpdate() threw an exception! Existing DreamDaemon instances will be terminated. Continue?", "Warning", MessageBoxButtons.YesNo) != DialogResult.Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
InstallCancelButton.Enabled = true;
|
||||
|
||||
if (ShowLogCheckbox.Checked)
|
||||
{
|
||||
logfile = path + Path.DirectorySeparatorChar + "tgsinstall.log";
|
||||
logfile = Path.Combine(tempDir, "tgsinstall.log");
|
||||
Installer.EnableLog(InstallLogModes.Verbose | InstallLogModes.PropertyDump, logfile);
|
||||
}
|
||||
var cl = String.Join(" ", args);
|
||||
@@ -172,12 +244,6 @@ namespace TGInstallerWrapper
|
||||
Process.Start(logfile).WaitForInputIdle();
|
||||
}
|
||||
catch { }
|
||||
if (path != null)
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
MessageBox.Show("Success!");
|
||||
Application.Exit();
|
||||
@@ -208,7 +274,7 @@ namespace TGInstallerWrapper
|
||||
if (fbd.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
pathIsDefault = false;
|
||||
PathTextBox.Text = fbd.SelectedPath + Path.DirectorySeparatorChar + InstallDir;
|
||||
PathTextBox.Text = fbd.SelectedPath + Path.DirectorySeparatorChar + DefaultInstallDir;
|
||||
}
|
||||
|
||||
private void CancelButton_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TGInstallerWrapper
|
||||
|
||||
+11
-1
@@ -19,7 +19,7 @@ namespace TGInstallerWrapper.Properties {
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
@@ -79,5 +79,15 @@ namespace TGInstallerWrapper.Properties {
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] TGServiceInterface {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("TGServiceInterface", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
<value>..\..\TGServiceInstaller\bin\Release\cab1.cab;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="TGServiceInstaller" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>...\..\TGServiceInstaller\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>..\..\TGServiceInstaller\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="TGServiceInterface" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\..\TGServiceInterface\bin\x86\Release\TGServiceInterface.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -11,6 +11,8 @@
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -38,6 +40,10 @@
|
||||
<ApplicationIcon>tgs.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Costura, Version=1.6.2.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Deployment.WindowsInstaller, Version=3.0.0.0, Culture=neutral, PublicKeyToken=ce35f76fcda82bad, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
@@ -70,15 +76,21 @@
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="app.manifest" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TGServiceInterface\TGServiceInterface.csproj">
|
||||
<Project>{ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab}</Project>
|
||||
<Name>TGServiceInterface</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="FodyWeavers.xml" />
|
||||
<None Include="Resources\TGServiceInterface.dll" />
|
||||
<Content Include="tgs.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Fody.2.0.0\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.2.0.0\build\dotnet\Fody.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Fody.2.0.0\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.2.0.0\build\dotnet\Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" />
|
||||
</Project>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Costura.Fody" version="1.6.2" targetFramework="net452" developmentDependency="true" />
|
||||
<package id="Fody" version="2.0.0" targetFramework="net452" developmentDependency="true" />
|
||||
</packages>
|
||||
+2
-9
@@ -2,19 +2,12 @@ $bf = $Env:APPVEYOR_BUILD_FOLDER
|
||||
$src = "$bf\TGInstallerWrapper\bin\Release"
|
||||
$version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$src\TG Station Server Installer.exe").FileVersion
|
||||
|
||||
Remove-Item "$src\Microsoft.Deployment.WindowsInstaller.xml"
|
||||
Remove-Item "$src\TG Station Server Installer.exe.config"
|
||||
Remove-Item "$src\TG Station Server Installer.pdb"
|
||||
Rename-Item -Path "$src\TG Station Server Installer.exe" -NewName "$src\TG Station Server Installer v$version.exe"
|
||||
$destination = "$bf\TGS3-Server-v$version.exe"
|
||||
|
||||
$destination = "$bf\TGS3-Server-v$version.zip"
|
||||
|
||||
If(Test-path $destination) {Remove-item $destination}
|
||||
Move-Item -Path "$src\TG Station Server Installer.exe" -Destination "$destination"
|
||||
|
||||
Add-Type -assembly "system.io.compression.filesystem"
|
||||
|
||||
[io.compression.zipfile]::CreateFromDirectory($src, $destination)
|
||||
|
||||
$destination_md5sha = $Env:APPVEYOR_BUILD_FOLDER + "\MD5-SHA1-Server-v$version.txt"
|
||||
|
||||
$src2 = $Env:APPVEYOR_BUILD_FOLDER + "\ClientApps"
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="SettingsVersion" serializeAs="String">
|
||||
<value>4</value>
|
||||
<value>5</value>
|
||||
</setting>
|
||||
<setting name="ReattachCommsKey" serializeAs="String">
|
||||
<value />
|
||||
@@ -73,6 +73,9 @@
|
||||
<setting name="ReattachAPIVersion" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="AutoUpdateInterval" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="PushTestmergeCommits" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
|
||||
@@ -82,8 +82,13 @@ namespace TGServerService
|
||||
}
|
||||
protected override ExitCode Run(IList<string> parameters)
|
||||
{
|
||||
OutputProc(String.Format("^{0}", Instance.GetHead(true, out string error)) ?? error);
|
||||
return error == null ? ExitCode.Normal : ExitCode.ServerError;
|
||||
var res = Instance.LiveSha();
|
||||
if (res == "UNKNOWN") {
|
||||
OutputProc(res);
|
||||
return ExitCode.ServerError;
|
||||
}
|
||||
OutputProc(String.Format("^{0}", res));
|
||||
return ExitCode.Normal;
|
||||
}
|
||||
|
||||
public override string GetHelpText()
|
||||
|
||||
@@ -337,6 +337,7 @@ namespace TGServerService
|
||||
return;
|
||||
}
|
||||
}
|
||||
string CurrentSha;
|
||||
try
|
||||
{
|
||||
bool silent;
|
||||
@@ -378,6 +379,7 @@ namespace TGServerService
|
||||
|
||||
deleteExcludeList.Add(".git");
|
||||
Program.CopyDirectory(RepoPath, resurrectee, deleteExcludeList);
|
||||
CurrentSha = GetHead(false, out string error);
|
||||
//just the tip
|
||||
const string GitLogsDir = "/.git/logs";
|
||||
Program.CopyDirectory(RepoPath + GitLogsDir, resurrectee + GitLogsDir);
|
||||
@@ -524,6 +526,7 @@ namespace TGServerService
|
||||
TGServerService.WriteWarning("Postcompile hook failed!", TGServerService.EventID.DMCompileError);
|
||||
return;
|
||||
}
|
||||
UpdateLiveSha(CurrentSha);
|
||||
var msg = String.Format("Compile complete!{0}", !staged ? "" : " Server will update next round.");
|
||||
SendMessage("DM: " + msg, ChatMessageType.DeveloperInfo);
|
||||
TGServerService.WriteInfo(msg, TGServerService.EventID.DMCompileSuccess);
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
using TGServiceInterface;
|
||||
|
||||
namespace TGServerService
|
||||
@@ -18,14 +19,18 @@ namespace TGServerService
|
||||
Pinged,
|
||||
}
|
||||
|
||||
const string DiagnosticsDir = "Diagnostics";
|
||||
const string ResourceDiagnosticsDir = DiagnosticsDir + "/Resources";
|
||||
const int DDHangStartTime = 60;
|
||||
const int DDBadStartTime = 10;
|
||||
|
||||
Process Proc;
|
||||
PerformanceCounter pcpu;
|
||||
|
||||
object watchdogLock = new object();
|
||||
Thread DDWatchdog;
|
||||
TGDreamDaemonStatus currentStatus;
|
||||
string CurrentDDLog;
|
||||
ushort currentPort = 0;
|
||||
|
||||
object restartLock = new object();
|
||||
@@ -38,6 +43,8 @@ namespace TGServerService
|
||||
//Only need 1 proc instance
|
||||
void InitDreamDaemon()
|
||||
{
|
||||
Directory.CreateDirectory(DiagnosticsDir);
|
||||
Directory.CreateDirectory(ResourceDiagnosticsDir);
|
||||
var Reattach = Properties.Settings.Default.ReattachToDD;
|
||||
if (Reattach)
|
||||
try
|
||||
@@ -94,6 +101,7 @@ namespace TGServerService
|
||||
void DisposeDreamDaemon()
|
||||
{
|
||||
var Detach = Properties.Settings.Default.ReattachToDD;
|
||||
bool RenameLog = false;
|
||||
if (DaemonStatus() == TGDreamDaemonStatus.Online)
|
||||
{
|
||||
if (!Detach)
|
||||
@@ -102,13 +110,23 @@ namespace TGServerService
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenameLog = CurrentDDLog != null;
|
||||
SendMessage("DD: Detaching watch dog for update!", ChatMessageType.WatchdogInfo);
|
||||
WriteCurrentDDLog("Service updating! Splitting diagnostics...");
|
||||
}
|
||||
}
|
||||
else if (Detach)
|
||||
{
|
||||
Properties.Settings.Default.ReattachToDD = false;
|
||||
}
|
||||
Stop();
|
||||
if(pcpu != null)
|
||||
pcpu.Dispose();
|
||||
if (RenameLog)
|
||||
try
|
||||
{
|
||||
File.Move(Path.Combine(ResourceDiagnosticsDir, CurrentDDLog), Path.Combine(ResourceDiagnosticsDir, "SU-" + CurrentDDLog));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
//public api
|
||||
@@ -189,20 +207,30 @@ namespace TGServerService
|
||||
{
|
||||
if (DaemonStatus() == TGDreamDaemonStatus.Offline)
|
||||
return Start();
|
||||
if (!Monitor.TryEnter(restartLock))
|
||||
return "Restart already in progress";
|
||||
try
|
||||
lock(restartLock)
|
||||
{
|
||||
SendMessage("DD: Hard restart triggered", ChatMessageType.WatchdogInfo);
|
||||
if (RestartInProgress)
|
||||
return "Restart already in progress";
|
||||
RestartInProgress = true;
|
||||
Stop();
|
||||
var res = Start();
|
||||
return res;
|
||||
}
|
||||
finally
|
||||
SendMessage("DD: Hard restart triggered", ChatMessageType.WatchdogInfo);
|
||||
Stop();
|
||||
var res = Start();
|
||||
if(res != null)
|
||||
lock(restartLock)
|
||||
{
|
||||
RestartInProgress = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void WriteCurrentDDLog(string message)
|
||||
{
|
||||
lock (watchdogLock)
|
||||
{
|
||||
RestartInProgress = false;
|
||||
Monitor.Exit(restartLock);
|
||||
if (currentStatus != TGDreamDaemonStatus.Online || CurrentDDLog == null)
|
||||
return;
|
||||
File.AppendAllText(Path.Combine(ResourceDiagnosticsDir, CurrentDDLog), String.Format("[{0}]: {1}\n", DateTime.Now.ToLongTimeString(), message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,6 +253,13 @@ namespace TGServerService
|
||||
}
|
||||
}
|
||||
var retries = 0;
|
||||
|
||||
var MemTrackTimer = new System.Timers.Timer
|
||||
{
|
||||
AutoReset = true,
|
||||
Interval = 5000 //every 5 seconds
|
||||
};
|
||||
MemTrackTimer.Elapsed += MemTrackTimer_Elapsed;
|
||||
while (true)
|
||||
{
|
||||
var starttime = DateTime.Now;
|
||||
@@ -235,8 +270,23 @@ namespace TGServerService
|
||||
SendCommand(SCGracefulShutdown);
|
||||
}
|
||||
|
||||
//all good to go, let's start monitoring
|
||||
var Now = DateTime.Now;
|
||||
lock (watchdogLock)
|
||||
{
|
||||
CurrentDDLog = String.Format("{0} {1} Diagnostics.txt", Now.ToLongDateString(), Now.ToLongTimeString()).Replace(':', '-');
|
||||
WriteCurrentDDLog("Starting monitoring...");
|
||||
pcpu = new PerformanceCounter("Process", "% Processor Time", Proc.ProcessName, true);
|
||||
}
|
||||
MemTrackTimer.Start();
|
||||
Proc.WaitForExit();
|
||||
lock (watchdogLock) //synchronize
|
||||
{
|
||||
MemTrackTimer.Stop();
|
||||
pcpu.Dispose();
|
||||
}
|
||||
|
||||
bool BadStart;
|
||||
lock (watchdogLock)
|
||||
{
|
||||
currentStatus = TGDreamDaemonStatus.HardRebooting;
|
||||
@@ -245,8 +295,8 @@ namespace TGServerService
|
||||
|
||||
if (AwaitingShutdown == ShutdownRequestPhase.Pinged)
|
||||
return;
|
||||
|
||||
if ((DateTime.Now - starttime).TotalSeconds < DDBadStartTime)
|
||||
BadStart = (DateTime.Now - starttime).TotalSeconds < DDBadStartTime;
|
||||
if (BadStart)
|
||||
{
|
||||
++retries;
|
||||
var sleep_time = (int)Math.Min(Math.Pow(2, retries), 3600); //max of one hour
|
||||
@@ -261,6 +311,8 @@ namespace TGServerService
|
||||
TGServerService.WriteWarning(msg, TGServerService.EventID.DDWatchdogRebootingServer);
|
||||
}
|
||||
}
|
||||
if (BadStart)
|
||||
WriteCurrentDDLog("Crash detected!");
|
||||
|
||||
var res = StartImpl(true);
|
||||
if (res != null)
|
||||
@@ -313,6 +365,20 @@ namespace TGServerService
|
||||
}
|
||||
}
|
||||
|
||||
private void MemTrackTimer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
ulong megamem;
|
||||
float cputime;
|
||||
lock (watchdogLock)
|
||||
{
|
||||
cputime = pcpu.NextValue();
|
||||
using (var pcm = new PerformanceCounter("Process", "Working Set - Private", Proc.ProcessName, true))
|
||||
megamem = Convert.ToUInt64(pcm.NextValue()) / 1024;
|
||||
}
|
||||
var PercentCpuTime = (int)Math.Round((Decimal)cputime);
|
||||
WriteCurrentDDLog(String.Format("CPU: {1}% Memory: {0}MB", megamem, PercentCpuTime.ToString("D3")));
|
||||
}
|
||||
|
||||
//public api
|
||||
public string CanStart()
|
||||
{
|
||||
@@ -396,7 +462,7 @@ namespace TGServerService
|
||||
|
||||
GenCommsKey();
|
||||
StartingSecurity = (TGDreamDaemonSecurity)Config.ServerSecurity;
|
||||
Proc.StartInfo.Arguments = String.Format("{0} -port {1} {5}-close -verbose -params \"server_service={3}&server_service_version={4}\" -{2} -public", DMB, Config.ServerPort, SecurityWord(), serviceCommsKey, Version(), Config.Webclient ? "-webclient" : "");
|
||||
Proc.StartInfo.Arguments = String.Format("{0} -port {1} {5}-close -verbose -params \"server_service={3}&server_service_version={4}\" -{2} -public", DMB, Config.ServerPort, SecurityWord(), serviceCommsKey, Version(), Config.Webclient ? "-webclient " : "");
|
||||
UpdateInterfaceDll(true);
|
||||
lock (topicLock)
|
||||
{
|
||||
|
||||
@@ -88,6 +88,8 @@ namespace TGServerService
|
||||
{
|
||||
if (IRCConfig.AdminsAreSpecial)
|
||||
{
|
||||
if (e.Channel == null)
|
||||
return false;
|
||||
var user = (NonRfcChannelUser)irc.GetChannelUser(e.Channel, e.Nick);
|
||||
if (user != null)
|
||||
switch (IRCConfig.AuthLevel)
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace TGServerService
|
||||
break;
|
||||
case SRWorldReboot:
|
||||
TGServerService.WriteInfo("World Rebooted", TGServerService.EventID.WorldReboot);
|
||||
WriteCurrentDDLog("World rebooted");
|
||||
ServerChatCommands = null;
|
||||
ChatConnectivityCheck();
|
||||
lock (CompilerLock)
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace TGServerService
|
||||
if (excludeRoot != null && excludeRoot.Contains(file.Name.ToLower()))
|
||||
continue;
|
||||
file.Attributes = FileAttributes.Normal;
|
||||
file.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -205,7 +205,7 @@ namespace TGServerService.Properties {
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("4")]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("5")]
|
||||
public int SettingsVersion {
|
||||
get {
|
||||
return ((int)(this["SettingsVersion"]));
|
||||
@@ -275,6 +275,18 @@ namespace TGServerService.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public ulong AutoUpdateInterval {
|
||||
get {
|
||||
return ((ulong)(this["AutoUpdateInterval"]));
|
||||
}
|
||||
set {
|
||||
this["AutoUpdateInterval"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="SettingsVersion" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">4</Value>
|
||||
<Value Profile="(Default)">5</Value>
|
||||
</Setting>
|
||||
<Setting Name="ReattachCommsKey" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
@@ -65,6 +65,9 @@
|
||||
<Setting Name="ReattachAPIVersion" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="AutoUpdateInterval" Type="System.UInt64" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="PushTestmergeCommits" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
|
||||
@@ -19,9 +19,11 @@ namespace TGServerService
|
||||
const string CachedTGS3SettingsPath = "TGS3.json";
|
||||
const string RepoErrorUpToDate = "Already up to date!";
|
||||
const string SSHPushRemote = "ssh_push_target";
|
||||
const string PrivateKeyPath = "RepoKey/private_key.txt";
|
||||
const string PublicKeyPath = "RepoKey/public_key.txt";
|
||||
const string RepoKeyDir = "RepoKey/";
|
||||
const string PrivateKeyPath = RepoKeyDir + "private_key.txt";
|
||||
const string PublicKeyPath = RepoKeyDir + "public_key.txt";
|
||||
const string PRJobFile = "prtestjob.json";
|
||||
const string LiveTrackingBranch = "___TGSLiveCommitTrackingBranch";
|
||||
const string CommitMessage = "Automatic changelog compile, [ci skip]";
|
||||
|
||||
object RepoLock = new object();
|
||||
@@ -31,6 +33,11 @@ namespace TGServerService
|
||||
Repository Repo;
|
||||
int currentProgress = -1;
|
||||
|
||||
System.Timers.Timer autoUpdateTimer = new System.Timers.Timer()
|
||||
{
|
||||
AutoReset = true
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Repo specific information about the installation
|
||||
/// Requires RepoLock and !RepoBusy to be instantiated
|
||||
@@ -41,7 +48,7 @@ namespace TGServerService
|
||||
public readonly string PathToChangelogPy;
|
||||
public readonly string ChangelogPyArguments;
|
||||
public readonly IList<string> PipDependancies = new List<string>();
|
||||
public readonly IList<string> ChangelogPathsToStage = new List<string>();
|
||||
public readonly IList<string> PathsToStage = new List<string>();
|
||||
public readonly IList<string> StaticDirectoryPaths = new List<string>();
|
||||
public readonly IList<string> DLLPaths = new List<string>();
|
||||
|
||||
@@ -64,16 +71,16 @@ namespace TGServerService
|
||||
PipDependancies = LoadArray(details["pip_dependancies"]);
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
ChangelogPathsToStage = LoadArray(details["synchronize_paths"]);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
catch {
|
||||
ChangelogSupport = false;
|
||||
}
|
||||
try
|
||||
{
|
||||
PathsToStage = LoadArray(json["synchronize_paths"]);
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
StaticDirectoryPaths = LoadArray(json["static_directories"]);
|
||||
}
|
||||
@@ -109,7 +116,7 @@ namespace TGServerService
|
||||
&& PathToChangelogPy == other.PathToChangelogPy
|
||||
&& ChangelogPyArguments == other.ChangelogPyArguments
|
||||
&& ListEquals(PipDependancies, other.PipDependancies)
|
||||
&& ListEquals(ChangelogPathsToStage, other.ChangelogPathsToStage)
|
||||
&& ListEquals(PathsToStage, other.PathsToStage)
|
||||
&& ListEquals(StaticDirectoryPaths, other.StaticDirectoryPaths)
|
||||
&& ListEquals(DLLPaths, other.DLLPaths);
|
||||
}
|
||||
@@ -121,7 +128,7 @@ namespace TGServerService
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(PathToChangelogPy);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(ChangelogPyArguments);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<IList<string>>.Default.GetHashCode(PipDependancies);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<IList<string>>.Default.GetHashCode(ChangelogPathsToStage);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<IList<string>>.Default.GetHashCode(PathsToStage);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<IList<string>>.Default.GetHashCode(StaticDirectoryPaths);
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<IList<string>>.Default.GetHashCode(DLLPaths);
|
||||
return hashCode;
|
||||
@@ -140,10 +147,14 @@ namespace TGServerService
|
||||
|
||||
void InitRepo()
|
||||
{
|
||||
Directory.CreateDirectory(RepoKeyDir);
|
||||
if(Exists())
|
||||
UpdateInterfaceDll(false);
|
||||
if(LoadRepo() == null)
|
||||
DisableGarbageCollectionNoLock();
|
||||
//start the autoupdate timer
|
||||
autoUpdateTimer.Elapsed += AutoUpdateTimer_Elapsed;
|
||||
SetAutoUpdateInterval(Properties.Settings.Default.AutoUpdateInterval);
|
||||
}
|
||||
|
||||
bool RepoConfigsMatch()
|
||||
@@ -491,6 +502,8 @@ namespace TGServerService
|
||||
//public api
|
||||
public string Checkout(string sha)
|
||||
{
|
||||
if (sha == LiveTrackingBranch)
|
||||
return "I'm sorry Dave, I'm afraid I can't do that...";
|
||||
lock (RepoLock)
|
||||
{
|
||||
var result = LoadRepo();
|
||||
@@ -583,13 +596,17 @@ namespace TGServerService
|
||||
|
||||
//public api
|
||||
public string Update(bool reset)
|
||||
{
|
||||
return UpdateImpl(reset, true);
|
||||
}
|
||||
|
||||
string UpdateImpl(bool reset, bool successOnUpToDate)
|
||||
{
|
||||
lock (RepoLock)
|
||||
{
|
||||
var result = LoadRepo();
|
||||
if (result != null)
|
||||
return result;
|
||||
SendMessage(String.Format("REPO: Updating origin branch...({0})", reset ? "Hard Reset" : "Merge"), ChatMessageType.DeveloperInfo);
|
||||
try
|
||||
{
|
||||
if (Repo.Head == null || !Repo.Head.IsTracking)
|
||||
@@ -600,6 +617,11 @@ namespace TGServerService
|
||||
return res;
|
||||
|
||||
var originBranch = Repo.Head.TrackedBranch;
|
||||
if (!successOnUpToDate && Repo.Head.Tip.Sha == originBranch.Tip.Sha)
|
||||
return RepoErrorUpToDate;
|
||||
|
||||
SendMessage(String.Format("REPO: Updating origin branch...({0})", reset ? "Hard Reset" : "Merge"), ChatMessageType.DeveloperInfo);
|
||||
|
||||
if (reset)
|
||||
{
|
||||
var error = ResetNoLock(Repo.Head.TrackedBranch);
|
||||
@@ -1016,7 +1038,7 @@ namespace TGServerService
|
||||
try
|
||||
{
|
||||
// Stage the file
|
||||
foreach(var I in Config.ChangelogPathsToStage)
|
||||
foreach(var I in Config.PathsToStage)
|
||||
Commands.Stage(Repo, I);
|
||||
|
||||
if (Repo.RetrieveStatus().Staged.Count() == 0) //nothing to commit
|
||||
@@ -1205,6 +1227,33 @@ namespace TGServerService
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetAutoUpdateInterval(ulong newInterval)
|
||||
{
|
||||
lock (autoUpdateTimer)
|
||||
{
|
||||
autoUpdateTimer.Stop();
|
||||
if (newInterval > 0) {
|
||||
autoUpdateTimer.Interval = newInterval * 60 * 1000; //convert from minutes to ms
|
||||
autoUpdateTimer.Start();
|
||||
}
|
||||
}
|
||||
Properties.Settings.Default.AutoUpdateInterval = newInterval;
|
||||
}
|
||||
|
||||
public ulong AutoUpdateInterval()
|
||||
{
|
||||
return Properties.Settings.Default.AutoUpdateInterval;
|
||||
}
|
||||
|
||||
private void AutoUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
if (UpdateImpl(true, false) == null)
|
||||
{
|
||||
Compile(true);
|
||||
}
|
||||
}
|
||||
|
||||
//public api
|
||||
public bool SetPythonPath(string path)
|
||||
{
|
||||
@@ -1219,6 +1268,22 @@ namespace TGServerService
|
||||
return Properties.Settings.Default.PythonPath;
|
||||
}
|
||||
|
||||
void UpdateLiveSha(string newSha)
|
||||
{
|
||||
if (LoadRepo() != null)
|
||||
return;
|
||||
var B = Repo.Branches[LiveTrackingBranch];
|
||||
if (B != null)
|
||||
Repo.Branches.Remove(B);
|
||||
Repo.CreateBranch(LiveTrackingBranch, newSha);
|
||||
}
|
||||
|
||||
public string LiveSha()
|
||||
{
|
||||
var B = Repo.Branches[LiveTrackingBranch];
|
||||
return B != null ? B.Tip.Sha : "UNKNOWN";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool PushTestmergeCommits()
|
||||
{
|
||||
|
||||
@@ -226,6 +226,20 @@ namespace TGServiceInterface
|
||||
[OperationContract]
|
||||
string UpdateTGS3Json();
|
||||
|
||||
/// <summary>
|
||||
/// (De)Activate and set the interval for the automatic server updater
|
||||
/// </summary>
|
||||
/// <param name="newInterval">Interval to check for updates in minutes, disables if zero</param>
|
||||
[OperationContract]
|
||||
void SetAutoUpdateInterval(ulong newInterval);
|
||||
|
||||
/// <summary>
|
||||
/// Get the current autoupdate interval
|
||||
/// </summary>
|
||||
/// <returns>The current auto update interval or zero if it's disabled</returns>
|
||||
[OperationContract]
|
||||
ulong AutoUpdateInterval();
|
||||
|
||||
/// <summary>
|
||||
/// Check if we push a temporary branch to the remote when we make testmerge commits
|
||||
/// </summary>
|
||||
|
||||
+3
-3
@@ -12,6 +12,6 @@ using System.Reflection;
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
//It's impossible to make these a define, don't say I didn't warn you
|
||||
[assembly: AssemblyVersion("3.1.2.2")]
|
||||
[assembly: AssemblyFileVersion("3.1.2.2")]
|
||||
[assembly: AssemblyInformationalVersion("3.1.2.2")]
|
||||
[assembly: AssemblyVersion("3.1.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.1.4.1")]
|
||||
[assembly: AssemblyInformationalVersion("3.1.4.1")]
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ image: Visual Studio 2017
|
||||
configuration: Release
|
||||
shallow_clone: true
|
||||
artifacts:
|
||||
- path: TGS3-Server-v*.zip
|
||||
- path: TGS3-Server-v*.exe
|
||||
name: TGS3Server
|
||||
- path: MD5-SHA1-Server-v*.txt
|
||||
name: MD5SHA1Server
|
||||
|
||||
Reference in New Issue
Block a user