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() 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); + } } } 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(); } }