From 0a676cd6db290364114f21530b6813cc9ddc2f9e Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 11 Oct 2017 21:36:56 -0400 Subject: [PATCH 01/26] Fixes webclient command --- TGServerService/DreamDaemon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index 0d822de64e..d8eb9d48f5 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -396,7 +396,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) { From 5c0f867882708a56a9fbefe79c595ef30863df14 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 11 Oct 2017 22:11:43 -0400 Subject: [PATCH 02/26] Version bump to 3.1.3.0 [TGSDeploy] --- Version.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Version.cs b/Version.cs index 29d52bda09..36555d8860 100644 --- a/Version.cs +++ b/Version.cs @@ -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.3.0")] +[assembly: AssemblyFileVersion("3.1.3.0")] +[assembly: AssemblyInformationalVersion("3.1.3.0")] From 7f5f61349f25162b6ab7b260aa33873ffe8d7ba4 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 12:30:49 -0400 Subject: [PATCH 03/26] Fixes DeleteDirectory not deleting root files if ContentsOnly is set --- TGServerService/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TGServerService/Program.cs b/TGServerService/Program.cs index d4822ea533..ef6ab4bfc1 100644 --- a/TGServerService/Program.cs +++ b/TGServerService/Program.cs @@ -57,6 +57,7 @@ namespace TGServerService if (excludeRoot != null && excludeRoot.Contains(file.Name.ToLower())) continue; file.Attributes = FileAttributes.Normal; + file.Delete(); } } From 18b54ae2dd4c5c6c614a9c5a7b7ee0fcc35c9eaa Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 13:00:21 -0400 Subject: [PATCH 04/26] Fixes double messages for hard restarts --- TGServerService/DreamDaemon.cs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index d8eb9d48f5..d740173e89 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -189,21 +189,16 @@ 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); - RestartInProgress = true; - Stop(); - var res = Start(); - return res; - } - finally - { - RestartInProgress = false; - Monitor.Exit(restartLock); + if (RestartInProgress) + return "Restart already in progress"; } + SendMessage("DD: Hard restart triggered", ChatMessageType.WatchdogInfo); + RestartInProgress = true; + Stop(); + var res = Start(); + return res; } //loop that keeps the server running From 2a381de1788d82da49597715ccedc601d58ef405 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 13:01:15 -0400 Subject: [PATCH 05/26] DewItRight --- TGServerService/DreamDaemon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index d740173e89..42738b223e 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -193,9 +193,9 @@ namespace TGServerService { if (RestartInProgress) return "Restart already in progress"; + RestartInProgress = true; } SendMessage("DD: Hard restart triggered", ChatMessageType.WatchdogInfo); - RestartInProgress = true; Stop(); var res = Start(); return res; From 468d1d88e32b45055d53c9b26b028f958705a5a9 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 13:03:20 -0400 Subject: [PATCH 06/26] DO IT RIGHT DAMMIT --- TGServerService/DreamDaemon.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index 42738b223e..8242cfe74f 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -198,6 +198,11 @@ namespace TGServerService SendMessage("DD: Hard restart triggered", ChatMessageType.WatchdogInfo); Stop(); var res = Start(); + if(res != null) + lock(restartLock) + { + RestartInProgress = false; + } return res; } From 1fe27123b205f89beccd4887ba6975e56b962e5e Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 13:05:37 -0400 Subject: [PATCH 07/26] Version bump to 3.1.3.1 [TGSDeploy] --- Version.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Version.cs b/Version.cs index 36555d8860..0371a4639a 100644 --- a/Version.cs +++ b/Version.cs @@ -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.3.0")] -[assembly: AssemblyFileVersion("3.1.3.0")] -[assembly: AssemblyInformationalVersion("3.1.3.0")] +[assembly: AssemblyVersion("3.1.3.1")] +[assembly: AssemblyFileVersion("3.1.3.1")] +[assembly: AssemblyInformationalVersion("3.1.3.1")] From 5a9d754674bf19ba8d60f1b85f6b32ce6c43e522 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 14:20:54 -0400 Subject: [PATCH 08/26] Excludes TGServiceInterface.dll from compiler directory sanitize --- TGServerService/Compiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TGServerService/Compiler.cs b/TGServerService/Compiler.cs index 49ccfffa8f..1ec5dbd916 100644 --- a/TGServerService/Compiler.cs +++ b/TGServerService/Compiler.cs @@ -352,7 +352,7 @@ namespace TGServerService resurrectee = GetStagingDir(); var Config = new RepoConfig(false); - var deleteExcludeList = new List(); + var deleteExcludeList = new List { InterfaceDLLName }; deleteExcludeList.AddRange(Config.StaticDirectoryPaths); deleteExcludeList.AddRange(Config.DLLPaths); Program.DeleteDirectory(resurrectee, true, deleteExcludeList); From 2562f3cbbb607dd9e08eed5057009f1c9ae147a2 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 14:21:55 -0400 Subject: [PATCH 09/26] Version bump to 3.1.3.2 [TGSDeploy] --- Version.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Version.cs b/Version.cs index 0371a4639a..718d9173c1 100644 --- a/Version.cs +++ b/Version.cs @@ -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.3.1")] -[assembly: AssemblyFileVersion("3.1.3.1")] -[assembly: AssemblyInformationalVersion("3.1.3.1")] +[assembly: AssemblyVersion("3.1.3.2")] +[assembly: AssemblyFileVersion("3.1.3.2")] +[assembly: AssemblyInformationalVersion("3.1.3.2")] From 289e5bd4f754a82d8de54389922c8a8bf1cde1a3 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 16:00:11 -0400 Subject: [PATCH 10/26] Adds automatic updating --- TGServerService/App.config | 5 +- .../Properties/Settings.Designer.cs | 14 +++++- TGServerService/Properties/Settings.settings | 5 +- TGServerService/Repository.cs | 46 ++++++++++++++++++- TGServiceInterface/Repository.cs | 14 ++++++ 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/TGServerService/App.config b/TGServerService/App.config index 6b4ecc1601..6a7a0786db 100644 --- a/TGServerService/App.config +++ b/TGServerService/App.config @@ -56,7 +56,7 @@ 0 - 4 + 5 @@ -73,6 +73,9 @@ + + 0 + diff --git a/TGServerService/Properties/Settings.Designer.cs b/TGServerService/Properties/Settings.Designer.cs index 7a76d2a5ae..34304772d5 100644 --- a/TGServerService/Properties/Settings.Designer.cs +++ b/TGServerService/Properties/Settings.Designer.cs @@ -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"])); @@ -274,5 +274,17 @@ namespace TGServerService.Properties { this["ReattachAPIVersion"] = value; } } + + [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; + } + } } } diff --git a/TGServerService/Properties/Settings.settings b/TGServerService/Properties/Settings.settings index 5618f8cd97..a417d94fbd 100644 --- a/TGServerService/Properties/Settings.settings +++ b/TGServerService/Properties/Settings.settings @@ -48,7 +48,7 @@ 0 - 4 + 5 @@ -65,5 +65,8 @@ + + 0 + \ No newline at end of file diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 2b6bf6a3b5..4ec88a7370 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -30,6 +30,11 @@ namespace TGServerService Repository Repo; int currentProgress = -1; + System.Timers.Timer autoUpdateTimer = new System.Timers.Timer() + { + AutoReset = true + }; + /// /// Repo specific information about the installation /// Requires RepoLock and !RepoBusy to be instantiated @@ -143,6 +148,9 @@ namespace TGServerService UpdateInterfaceDll(false); if(LoadRepo() == null) DisableGarbageCollectionNoLock(); + //start the autoupdate timer + autoUpdateTimer.Elapsed += AutoUpdateTimer_Elapsed; + SetAutoUpdateInterval(Properties.Settings.Default.AutoUpdateInterval); } bool RepoConfigsMatch() @@ -556,13 +564,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) @@ -573,6 +585,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); @@ -1179,6 +1196,33 @@ namespace TGServerService } } + /// + 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) { diff --git a/TGServiceInterface/Repository.cs b/TGServiceInterface/Repository.cs index da0ef9d8c5..eab2a89a8d 100644 --- a/TGServiceInterface/Repository.cs +++ b/TGServiceInterface/Repository.cs @@ -225,5 +225,19 @@ namespace TGServiceInterface /// null on success, error message on failure [OperationContract] string UpdateTGS3Json(); + + /// + /// (De)Activate and set the interval for the automatic server updater + /// + /// Interval to check for updates in minutes, disables if zero + [OperationContract] + void SetAutoUpdateInterval(ulong newInterval); + + /// + /// Get the current autoupdate interval + /// + /// The current auto update interval or zero if it's disabled + [OperationContract] + ulong AutoUpdateInterval(); } } From 90ab635b334d031216d54009bef03a7591d82fec Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 16:35:19 -0400 Subject: [PATCH 11/26] CLI for modifying auto updates --- TGCommandLine/RootCommands.cs | 60 ++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/TGCommandLine/RootCommands.cs b/TGCommandLine/RootCommands.cs index 884f1c0744..9fba17ca44 100644 --- a/TGCommandLine/RootCommands.cs +++ b/TGCommandLine/RootCommands.cs @@ -8,7 +8,7 @@ namespace TGCommandLine { public CLICommand() { - var tmp = new List { new UpdateCommand(), new TestmergeCommand(), new RepoCommand(), new BYONDCommand(), new DMCommand(), new DDCommand(), new ConfigCommand(), new IRCCommand(), new DiscordCommand() }; + 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 (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 parameters) + { + var res = Server.GetComponent().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 ""; + } + + public override string GetHelpText() + { + return "Set the interval in minutes that the server automatically updates"; + } + + protected override ExitCode Run(IList 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().SetAutoUpdateInterval(NewInterval); + return ExitCode.Normal; + } + + } class UpdateCommand : Command { public UpdateCommand() From c6fd5cc59b2150f1f3fc38276cb8a3b77c3a936e Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 16:51:51 -0400 Subject: [PATCH 12/26] CP field for modifying auto updates --- TGControlPanel/Main.Designer.cs | 75 ++++++++++++++++++++++++++++++--- TGControlPanel/ServerPage.cs | 35 +++++++++++++-- 2 files changed, 102 insertions(+), 8 deletions(-) diff --git a/TGControlPanel/Main.Designer.cs b/TGControlPanel/Main.Designer.cs index a58a04b3dc..3f787f03be 100644 --- a/TGControlPanel/Main.Designer.cs +++ b/TGControlPanel/Main.Designer.cs @@ -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; } } diff --git a/TGControlPanel/ServerPage.cs b/TGControlPanel/ServerPage.cs index 69b868a547..0f001d3abc 100644 --- a/TGControlPanel/ServerPage.cs +++ b/TGControlPanel/ServerPage.cs @@ -107,6 +107,7 @@ namespace TGControlPanel { var RepoExists = Server.GetComponent().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(); var DD = Server.GetComponent(); var Config = Server.GetComponent(); - - if (updatingFields) - return; + var Repo = Server.GetComponent(); 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().SetWebclient(WebclientCheckBox.Checked); } + + private void AutoUpdateInterval_ValueChanged(object sender, EventArgs e) + { + if (!updatingFields) + Server.GetComponent().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().SetAutoUpdateInterval(0); + else + Server.GetComponent().SetAutoUpdateInterval((ulong)AutoUpdateInterval.Value); + } } } From 977f7c94ca7d6dc054b9ed270aac5b20b7570dd3 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 16:53:17 -0400 Subject: [PATCH 13/26] Tabbing to the repo page updates it --- TGControlPanel/Main.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TGControlPanel/Main.cs b/TGControlPanel/Main.cs index 584e8b1f75..969e926771 100644 --- a/TGControlPanel/Main.cs +++ b/TGControlPanel/Main.cs @@ -35,6 +35,9 @@ namespace TGControlPanel { switch (Panels.SelectedIndex) { + case 0: //repo + PopulateRepoFields(); + break; case 1: //byond UpdateBYONDButtons(); break; From 7b907dff27a0c2243d72bbe6c72bdef1e0528868 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 22:08:27 -0400 Subject: [PATCH 14/26] Revision command now shows the server revision rather than the repository revision --- TGServerService/ChatCommands.cs | 9 +++++++-- TGServerService/Compiler.cs | 1 + TGServerService/Repository.cs | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/TGServerService/ChatCommands.cs b/TGServerService/ChatCommands.cs index 2e2ec6dab6..67c1ff1b79 100644 --- a/TGServerService/ChatCommands.cs +++ b/TGServerService/ChatCommands.cs @@ -82,8 +82,13 @@ namespace TGServerService } protected override ExitCode Run(IList 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() diff --git a/TGServerService/Compiler.cs b/TGServerService/Compiler.cs index 49ccfffa8f..5468509f29 100644 --- a/TGServerService/Compiler.cs +++ b/TGServerService/Compiler.cs @@ -378,6 +378,7 @@ namespace TGServerService deleteExcludeList.Add(".git"); Program.CopyDirectory(RepoPath, resurrectee, deleteExcludeList); + UpdateLiveSha(); //just the tip const string GitLogsDir = "/.git/logs"; Program.CopyDirectory(RepoPath + GitLogsDir, resurrectee + GitLogsDir); diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 460e8050b4..6f06ee4045 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -21,6 +21,7 @@ namespace TGServerService const string PrivateKeyPath = "RepoKey/private_key.txt"; const string PublicKeyPath = "RepoKey/public_key.txt"; const string PRJobFile = "prtestjob.json"; + const string LiveTrackingBranch = "___TGSLiveCommitTrackingBranch"; const string CommitMessage = "Automatic changelog compile, [ci skip]"; object RepoLock = new object(); @@ -1185,5 +1186,21 @@ namespace TGServerService { return Properties.Settings.Default.PythonPath; } + + void UpdateLiveSha() + { + if (LoadRepo() != null) + return; + var B = Repo.Branches[LiveTrackingBranch]; + if (B != null) + Repo.Branches.Remove(B); + Repo.CreateBranch(LiveTrackingBranch, Repo.Head.Tip); + } + + public string LiveSha() + { + var B = Repo.Branches[LiveTrackingBranch]; + return B != null ? B.Tip.Sha : "UNKNOWN"; + } } } From e259881a2e1e1a5821fcd8d9ffa857b17327cbf4 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 22:17:55 -0400 Subject: [PATCH 15/26] Better --- TGServerService/Compiler.cs | 4 +++- TGServerService/Repository.cs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/TGServerService/Compiler.cs b/TGServerService/Compiler.cs index 5468509f29..d65ad924c4 100644 --- a/TGServerService/Compiler.cs +++ b/TGServerService/Compiler.cs @@ -337,6 +337,7 @@ namespace TGServerService return; } } + string CurrentSha; try { bool silent; @@ -378,7 +379,7 @@ namespace TGServerService deleteExcludeList.Add(".git"); Program.CopyDirectory(RepoPath, resurrectee, deleteExcludeList); - UpdateLiveSha(); + CurrentSha = GetHead(false, out string error); //just the tip const string GitLogsDir = "/.git/logs"; Program.CopyDirectory(RepoPath + GitLogsDir, resurrectee + GitLogsDir); @@ -525,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); diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 6f06ee4045..84e759f3ae 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -1187,14 +1187,14 @@ namespace TGServerService return Properties.Settings.Default.PythonPath; } - void UpdateLiveSha() + void UpdateLiveSha(string newSha) { if (LoadRepo() != null) return; var B = Repo.Branches[LiveTrackingBranch]; if (B != null) Repo.Branches.Remove(B); - Repo.CreateBranch(LiveTrackingBranch, Repo.Head.Tip); + Repo.CreateBranch(LiveTrackingBranch, newSha); } public string LiveSha() From 5af1c909c5808e9825307d66da3e661bcfde6395 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 12 Oct 2017 22:19:31 -0400 Subject: [PATCH 16/26] Sanity check --- TGServerService/Repository.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 84e759f3ae..4f03ff83a2 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -482,6 +482,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(); From 4ef2863419793b461a6390b509e9b44345c32020 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 12 Oct 2017 22:23:42 -0400 Subject: [PATCH 17/26] Version bump to 3.1.4.0 [TGSDeploy] --- Version.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Version.cs b/Version.cs index 718d9173c1..7b79200049 100644 --- a/Version.cs +++ b/Version.cs @@ -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.3.2")] -[assembly: AssemblyFileVersion("3.1.3.2")] -[assembly: AssemblyInformationalVersion("3.1.3.2")] +[assembly: AssemblyVersion("3.1.4.0")] +[assembly: AssemblyFileVersion("3.1.4.0")] +[assembly: AssemblyInformationalVersion("3.1.4.0")] From 29a3fe820569e48a46c1e81afb7bfa19f96f6241 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Fri, 13 Oct 2017 12:06:41 -0400 Subject: [PATCH 18/26] Adds CPU and memory tracking log files --- TGServerService/DreamDaemon.cs | 72 ++++++++++++++++++++++++++++++++-- TGServerService/Interop.cs | 1 + 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index 8242cfe74f..cdd6de3004 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -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,17 @@ namespace TGServerService Pinged, } + const string DDDiagnosticsDir = "Diagnostics"; 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 +42,7 @@ namespace TGServerService //Only need 1 proc instance void InitDreamDaemon() { + Directory.CreateDirectory(DDDiagnosticsDir); var Reattach = Properties.Settings.Default.ReattachToDD; if (Reattach) try @@ -94,6 +99,7 @@ namespace TGServerService void DisposeDreamDaemon() { var Detach = Properties.Settings.Default.ReattachToDD; + bool RenameLog = false; if (DaemonStatus() == TGDreamDaemonStatus.Online) { if (!Detach) @@ -102,13 +108,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(DDDiagnosticsDir, CurrentDDLog), Path.Combine(DDDiagnosticsDir, "SU-" + CurrentDDLog)); + } + catch { } } //public api @@ -206,6 +222,16 @@ namespace TGServerService return res; } + void WriteCurrentDDLog(string message) + { + lock (watchdogLock) + { + if (currentStatus != TGDreamDaemonStatus.Online || CurrentDDLog == null) + return; + File.AppendAllText(Path.Combine(DDDiagnosticsDir, CurrentDDLog), String.Format("[{0}]: {1}\n", DateTime.Now.ToLongTimeString(), message)); + } + } + //loop that keeps the server running void Watchdog() { @@ -225,6 +251,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 +268,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 +293,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 +309,8 @@ namespace TGServerService TGServerService.WriteWarning(msg, TGServerService.EventID.DDWatchdogRebootingServer); } } + if (BadStart) + WriteCurrentDDLog("Crash detected!"); var res = StartImpl(true); if (res != null) @@ -313,6 +363,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() { diff --git a/TGServerService/Interop.cs b/TGServerService/Interop.cs index 5c8040162c..42ea994f50 100644 --- a/TGServerService/Interop.cs +++ b/TGServerService/Interop.cs @@ -89,6 +89,7 @@ namespace TGServerService break; case SRWorldReboot: TGServerService.WriteInfo("World Rebooted", TGServerService.EventID.WorldReboot); + WriteCurrentDDLog("World rebooted"); ServerChatCommands = null; ChatConnectivityCheck(); lock (CompilerLock) From 39857330202508d91bf572256952b49d636fa2d1 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 16 Oct 2017 12:03:39 -0400 Subject: [PATCH 19/26] RepoKey dir will be created by service --- TGServerService/Repository.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 89cb815326..09e867b57c 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -18,8 +18,9 @@ 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]"; @@ -145,6 +146,7 @@ namespace TGServerService void InitRepo() { + Directory.CreateDirectory(RepoKeyDir) if(Exists()) UpdateInterfaceDll(false); if(LoadRepo() == null) From 60b6c21f15ee90bcaa56ffc8f312217d7671b1e5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 16 Oct 2017 12:10:30 -0400 Subject: [PATCH 20/26] Add missing semicolons --- TGServerService/Repository.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 09e867b57c..1165777e83 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -18,7 +18,7 @@ namespace TGServerService const string CachedTGS3SettingsPath = "TGS3.json"; const string RepoErrorUpToDate = "Already up to date!"; const string SSHPushRemote = "ssh_push_target"; - const string RepoKeyDir = "RepoKey/" + const string RepoKeyDir = "RepoKey/"; const string PrivateKeyPath = RepoKeyDir + "private_key.txt"; const string PublicKeyPath = RepoKeyDir + "public_key.txt"; const string PRJobFile = "prtestjob.json"; @@ -146,7 +146,7 @@ namespace TGServerService void InitRepo() { - Directory.CreateDirectory(RepoKeyDir) + Directory.CreateDirectory(RepoKeyDir); if(Exists()) UpdateInterfaceDll(false); if(LoadRepo() == null) From 65aad1d28cfb401b88f49e3b76b577f0770cf38a Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 16 Oct 2017 12:25:55 -0400 Subject: [PATCH 21/26] Fixes parsing of synchronize directories in TGS3.json --- TGServerService/Repository.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/TGServerService/Repository.cs b/TGServerService/Repository.cs index 89cb815326..3f2a6cc469 100644 --- a/TGServerService/Repository.cs +++ b/TGServerService/Repository.cs @@ -46,7 +46,7 @@ namespace TGServerService public readonly string PathToChangelogPy; public readonly string ChangelogPyArguments; public readonly IList PipDependancies = new List(); - public readonly IList ChangelogPathsToStage = new List(); + public readonly IList PathsToStage = new List(); public readonly IList StaticDirectoryPaths = new List(); public readonly IList DLLPaths = new List(); @@ -69,16 +69,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"]); } @@ -114,7 +114,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); } @@ -126,7 +126,7 @@ namespace TGServerService hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(PathToChangelogPy); hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ChangelogPyArguments); hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(PipDependancies); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(ChangelogPathsToStage); + hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(PathsToStage); hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(StaticDirectoryPaths); hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(DLLPaths); return hashCode; @@ -1010,7 +1010,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 From f402c864e07ff331e0c79f86a583bcb4b9a859d5 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 16 Oct 2017 13:33:47 -0400 Subject: [PATCH 22/26] Server releases are now packaged as a single exe --- TGInstallerWrapper/FodyWeavers.xml | 4 ++++ TGInstallerWrapper/TGInstallerWrapper.csproj | 17 +++++++++++++++++ TGInstallerWrapper/packages.config | 5 +++++ TGS3Release.ps1 | 11 ++--------- appveyor.yml | 2 +- 5 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 TGInstallerWrapper/FodyWeavers.xml create mode 100644 TGInstallerWrapper/packages.config diff --git a/TGInstallerWrapper/FodyWeavers.xml b/TGInstallerWrapper/FodyWeavers.xml new file mode 100644 index 0000000000..c6e1b7c8af --- /dev/null +++ b/TGInstallerWrapper/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TGInstallerWrapper/TGInstallerWrapper.csproj b/TGInstallerWrapper/TGInstallerWrapper.csproj index e94ed50a6c..9685dbe6d6 100644 --- a/TGInstallerWrapper/TGInstallerWrapper.csproj +++ b/TGInstallerWrapper/TGInstallerWrapper.csproj @@ -11,6 +11,8 @@ v4.5.2 512 true + + AnyCPU @@ -38,6 +40,10 @@ tgs.ico + + ..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll + False + @@ -70,6 +76,7 @@ + @@ -78,7 +85,17 @@ + + + + + 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}. + + + + + \ No newline at end of file diff --git a/TGInstallerWrapper/packages.config b/TGInstallerWrapper/packages.config new file mode 100644 index 0000000000..b4d46b584a --- /dev/null +++ b/TGInstallerWrapper/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/TGS3Release.ps1 b/TGS3Release.ps1 index 0749e410db..ea5884c247 100644 --- a/TGS3Release.ps1 +++ b/TGS3Release.ps1 @@ -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" diff --git a/appveyor.yml b/appveyor.yml index cd29c86075..0bbbd54080 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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 From f2d6eb2ae33772d1b9272d8395749123a249066e Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Mon, 16 Oct 2017 16:15:33 -0400 Subject: [PATCH 23/26] Rewrite the installer using reflection Since the installer uses embedded native code for DD to be able to call it, we can't directly embed it in the installer exe. Let's just use the method we used for the .msi + reflection instead. --- TGInstallerWrapper/Main.Designer.cs | 11 +- TGInstallerWrapper/Main.cs | 138 +++++++++++++----- TGInstallerWrapper/Program.cs | 3 - .../Properties/Resources.Designer.cs | 12 +- TGInstallerWrapper/Properties/Resources.resx | 5 +- TGInstallerWrapper/TGInstallerWrapper.csproj | 7 +- 6 files changed, 126 insertions(+), 50 deletions(-) diff --git a/TGInstallerWrapper/Main.Designer.cs b/TGInstallerWrapper/Main.Designer.cs index 42842a7c05..88b82a06a3 100644 --- a/TGInstallerWrapper/Main.Designer.cs +++ b/TGInstallerWrapper/Main.Designer.cs @@ -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); diff --git a/TGInstallerWrapper/Main.cs b/TGInstallerWrapper/Main.cs index 43045bb0cc..e8fbd719d2 100644 --- a/TGInstallerWrapper/Main.cs +++ b/TGInstallerWrapper/Main.cs @@ -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().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(); 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().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) diff --git a/TGInstallerWrapper/Program.cs b/TGInstallerWrapper/Program.cs index c9669327d9..96dc421f86 100644 --- a/TGInstallerWrapper/Program.cs +++ b/TGInstallerWrapper/Program.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using System.Windows.Forms; namespace TGInstallerWrapper diff --git a/TGInstallerWrapper/Properties/Resources.Designer.cs b/TGInstallerWrapper/Properties/Resources.Designer.cs index 9365443396..e3858daec9 100644 --- a/TGInstallerWrapper/Properties/Resources.Designer.cs +++ b/TGInstallerWrapper/Properties/Resources.Designer.cs @@ -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)); } } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] TGServiceInterface { + get { + object obj = ResourceManager.GetObject("TGServiceInterface", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/TGInstallerWrapper/Properties/Resources.resx b/TGInstallerWrapper/Properties/Resources.resx index b29efcb08f..daa2b3cb0c 100644 --- a/TGInstallerWrapper/Properties/Resources.resx +++ b/TGInstallerWrapper/Properties/Resources.resx @@ -122,6 +122,9 @@ ..\..\TGServiceInstaller\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 + ..\..\TGServiceInstaller\bin\Release\TGServiceInstaller.msi;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\..\TGServiceInterface\bin\x86\Release\TGServiceInterface.dll;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/TGInstallerWrapper/TGInstallerWrapper.csproj index 9685dbe6d6..7e1bf4045e 100644 --- a/TGInstallerWrapper/TGInstallerWrapper.csproj +++ b/TGInstallerWrapper/TGInstallerWrapper.csproj @@ -78,14 +78,9 @@ - - - {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface - - + From 9c49ffcd65337996a5915eeaf2fe259d41863f78 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 16 Oct 2017 17:13:04 -0400 Subject: [PATCH 24/26] Version bump to 3.1.4.1 [TGSDeploy] --- Version.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Version.cs b/Version.cs index 7b79200049..966f876961 100644 --- a/Version.cs +++ b/Version.cs @@ -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.4.0")] -[assembly: AssemblyFileVersion("3.1.4.0")] -[assembly: AssemblyInformationalVersion("3.1.4.0")] +[assembly: AssemblyVersion("3.1.4.1")] +[assembly: AssemblyFileVersion("3.1.4.1")] +[assembly: AssemblyInformationalVersion("3.1.4.1")] From c46deb97db447623d3adff7ee91b95ea8c351e16 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 16 Oct 2017 20:08:05 -0400 Subject: [PATCH 25/26] Fixes IRC PMs not working --- TGServerService/IRC.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TGServerService/IRC.cs b/TGServerService/IRC.cs index 7194be267c..a04dfc2d36 100644 --- a/TGServerService/IRC.cs +++ b/TGServerService/IRC.cs @@ -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) From 0e0fef1e562a9c5c352240987535ff89410c653d Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 17 Oct 2017 14:07:40 -0400 Subject: [PATCH 26/26] Move it into a Resources subdir --- TGServerService/DreamDaemon.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index cdd6de3004..d7d5226721 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -19,7 +19,8 @@ namespace TGServerService Pinged, } - const string DDDiagnosticsDir = "Diagnostics"; + const string DiagnosticsDir = "Diagnostics"; + const string ResourceDiagnosticsDir = DiagnosticsDir + "/Resources"; const int DDHangStartTime = 60; const int DDBadStartTime = 10; @@ -42,7 +43,8 @@ namespace TGServerService //Only need 1 proc instance void InitDreamDaemon() { - Directory.CreateDirectory(DDDiagnosticsDir); + Directory.CreateDirectory(DiagnosticsDir); + Directory.CreateDirectory(ResourceDiagnosticsDir); var Reattach = Properties.Settings.Default.ReattachToDD; if (Reattach) try @@ -122,7 +124,7 @@ namespace TGServerService if (RenameLog) try { - File.Move(Path.Combine(DDDiagnosticsDir, CurrentDDLog), Path.Combine(DDDiagnosticsDir, "SU-" + CurrentDDLog)); + File.Move(Path.Combine(ResourceDiagnosticsDir, CurrentDDLog), Path.Combine(ResourceDiagnosticsDir, "SU-" + CurrentDDLog)); } catch { } } @@ -228,7 +230,7 @@ namespace TGServerService { if (currentStatus != TGDreamDaemonStatus.Online || CurrentDDLog == null) return; - File.AppendAllText(Path.Combine(DDDiagnosticsDir, CurrentDDLog), String.Format("[{0}]: {1}\n", DateTime.Now.ToLongTimeString(), message)); + File.AppendAllText(Path.Combine(ResourceDiagnosticsDir, CurrentDDLog), String.Format("[{0}]: {1}\n", DateTime.Now.ToLongTimeString(), message)); } }