• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Administrator's Toolkit VS plugin


Commit MetaInfo

修訂ca020bd7e84d5eac7c46196a961842afa9d52513 (tree)
時間2019-08-13 05:36:53
作者melchior <melchior@user...>
Commitermelchior

Log Message

re-cyclic backup process,
changed messages,
altering count now supported

Change Summary

差異

--- a/AdminToolkit/AdminModConfig.cs
+++ b/AdminToolkit/AdminModConfig.cs
@@ -37,15 +37,22 @@ namespace AdminToolkit
3737 /// <value>The backup count.</value>
3838 public uint BackupCount { get; set;}
3939
40+ /// <summary>
41+ /// If auto-enable delayed backup cycle on server start
42+ /// </summary>
43+ /// <value>The autobackup.</value>
44+ public bool Autobackup { get; set; }
45+
46+
4047 public AdminModConfig( )
4148 {
4249 this.PlayerRoleRestrain = "suvisitor";
4350 this.PlayerRoleNormal = "suplayer";
4451 this.RuleRoleChangerEnabled = false;
4552
46- this.BackupDelay = new TimeSpan(1, 0, 0);
47- this.BackupCount = 10;
48-
53+ this.BackupDelay = new TimeSpan(4, 0, 0);
54+ this.BackupCount = 6;
55+ this.Autobackup = false;
4956 }
5057
5158
--- a/AdminToolkit/AdminToolkitMod.cs
+++ b/AdminToolkit/AdminToolkitMod.cs
@@ -95,6 +95,7 @@ namespace AdminToolkit
9595 this.ServerAPI.RegisterCommand(new BackupCycleCommand(this.ServerAPI) );
9696
9797 this.ServerAPI.Event.PlayerChat += BoomingVoiceOfAuthority;
98+ this.ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.Shutdown, SaveConfigSettings);
9899 }
99100
100101 private void PopulateAdminRoleTable( )
@@ -157,12 +158,13 @@ namespace AdminToolkit
157158 return message;
158159 }
159160
160-
161-
162-
163-
164-
165-
161+ private void SaveConfigSettings( )
162+ {
163+ if (this.CachedConfiguration != null) {
164+ Mod.Logger.Notification("Persisting configuration.");
165+ ServerAPI.StoreModConfig<AdminModConfig>(this.CachedConfiguration, _configFilename);
166+ }
167+ }
166168
167169 }
168170 }
--- a/AdminToolkit/Commands/BackupCycleCommand.cs
+++ b/AdminToolkit/Commands/BackupCycleCommand.cs
@@ -18,6 +18,10 @@ namespace AdminToolkit
1818 private const string _timeFormat = @"d\D\ hh\H\ mm\M\ ss\S";
1919 private MechTurk mechanicalTurk;
2020
21+ private DateTimeOffset _lastBackupTime = DateTimeOffset.MinValue;
22+
23+ private string fileFilter;
24+
2125 public BackupCycleCommand(ICoreServerAPI _serverAPI) : base(_serverAPI)
2226 {
2327 this.Command = "backups";
@@ -27,6 +31,13 @@ namespace AdminToolkit
2731 this.Syntax = "enable / disable / delay [hours] / stats";
2832
2933 mechanicalTurk = new MechTurk(ServerAPI.Server.Config.Roles.Find(ro => ro.Code == "admin"), this.Logger);
34+
35+ ServerAPI.Event.ServerRunPhase(EnumServerRunPhase.RunGame, ServerStarts);
36+ }
37+
38+ public bool Enabled {
39+
40+ get { return this.backupTickerID != 0; }
3041 }
3142
3243 private void BackupCommandParser(IServerPlayer player, int groupId, CmdArgs args)
@@ -35,7 +46,7 @@ namespace AdminToolkit
3546
3647 StringBuilder msgLine = new StringBuilder( );
3748 bool success = false;
38- int? delay;
49+ int? delay, count;
3950
4051 if (args.Length > 0) {
4152 string command = args.PopWord( );
@@ -46,12 +57,12 @@ namespace AdminToolkit
4657
4758 switch (command) {
4859 case "enable":
49- success = EnableBackupCycle(true);
50- if (success) msgLine.AppendFormat("Enabled, with delay: {0}\n", this.CachedConfiguration.BackupDelay.ToString(_timeFormat));
60+ success = ToggleBackupCycle(true);
61+ if (success) msgLine.AppendFormat("Enabled, with delay: {0}, next: {1}\n", this.CachedConfiguration.BackupDelay.ToString(_timeFormat), DateTimeOffset.UtcNow.Add(this.CachedConfiguration.BackupDelay).ToString("u"));
5162 break;
5263
5364 case "disable":
54- success = EnableBackupCycle(false);
65+ success = ToggleBackupCycle(false);
5566 if (success) msgLine.AppendLine("Disabled.");
5667 break;
5768
@@ -68,10 +79,24 @@ namespace AdminToolkit
6879
6980 break;
7081
71- case "stats":
82+ case "count":
83+ count = args.PopInt( );
7284
85+ if (count.HasValue && count.Value >= 4) {
86+ this.CachedConfiguration.BackupCount = (uint)count.Value;
87+ msgLine.AppendFormat("Changed count to: {0} ", this.CachedConfiguration.BackupCount);
88+ success = true;
89+ } else {
90+ msgLine.AppendLine("Wrong quantity value; must be positive integer 4 or more (count) ");
91+ }
7392
93+ break;
7494
95+ case "state":
96+ case "status":
97+ case "stats":
98+ StatusLine(msgLine);
99+ success = true;
75100 break;
76101
77102 default:
@@ -91,23 +116,29 @@ namespace AdminToolkit
91116 player.SendMessage(groupId, msgLine.ToString( ), success ? EnumChatType.CommandSuccess : EnumChatType.CommandError);
92117 }
93118
94- private bool EnableBackupCycle(bool enable)
119+ /// <summary>
120+ /// Toggles the backup cycle.
121+ /// </summary>
122+ /// <returns>The backup cycle.</returns>
123+ /// <param name="enable">Enable.</param>
124+ private bool ToggleBackupCycle(bool enable)
95125 {
96126 if (enable)
97127 {
98- if (backupTickerID == 0)
128+ if (!this.Enabled)
99129 {
100130 this.backupTickerID = ServerAPI.Event.RegisterCallback(BackupCycleHandler, (int)this.CachedConfiguration.BackupDelay.TotalMilliseconds);
101- Logger.VerboseDebug("BackupCycle enabled, delay: {0}", this.CachedConfiguration.BackupDelay.ToString(_timeFormat));
131+ Logger.Notification("BackupCycle enabled, delay: {0}", this.CachedConfiguration.BackupDelay.ToString(_timeFormat));
102132 return true;
103133 }
104134 }
105135 else
106136 {
107- if (backupTickerID != 0)
137+ if (this.Enabled)
108138 {
109- ServerAPI.Event.UnregisterCallback(backupTickerID);
110- Logger.VerboseDebug("BackupCycle disabled");
139+ ServerAPI.Event.UnregisterCallback(backupTickerID);
140+ this.backupTickerID = 0;
141+ Logger.Notification("BackupCycle disabled");
111142 return true;
112143 }
113144 }
@@ -117,26 +148,26 @@ namespace AdminToolkit
117148
118149
119150 private void BackupCycleHandler(float elapsed)
120- {
121- Logger.Event("Automatic Backup triggered, elasped {0} @{1} Uptime",elapsed, ServerAPI.Server.ServerUptimeSeconds );
151+ {
152+ Logger.Event("Backup cycle triggered, elasped {0} @{1} Uptime", elapsed, ServerAPI.Server.ServerUptimeSeconds);
122153 //Peek at backup DIR, count files of the backup type
123154 var backupDir = new DirectoryInfo(GamePaths.Backups);
124155
125156 if (backupDir.Exists) {
126- var files = backupDir.GetFiles("*" + GlobalConstants.WorldSaveExtension);
157+
158+ var files = backupDir.GetFiles(fileFilter);
127159
128160 if (files.Length > this.CachedConfiguration.BackupCount) {
129161 Logger.VerboseDebug("There are {0} backup files, over set limit", files.Length);
130- var oldest = files.OrderByDescending(fi => fi.CreationTimeUtc).FirstOrDefault( );
162+ var oldest = files.OrderBy(fi => fi.CreationTimeUtc).FirstOrDefault( );
131163
132164 if (oldest != null) {
133- Logger.VerboseDebug("Oldest backup file: {0}", oldest.Name);
165+ Logger.VerboseDebug("Oldest backup file: {0}", oldest.FullName);
134166 oldest.Delete( );
135- Logger.Notification("Deleted old Backup: {0}", oldest.FullName);
167+ Logger.Notification("Deleted old Backup: {0}", oldest.Name);
136168 }
137169 }
138- } else
139- {
170+ } else {
140171 Logger.VerboseDebug("Could not open backup directory");
141172 }
142173
@@ -145,17 +176,21 @@ namespace AdminToolkit
145176
146177 ServerMain serverMain = ServerAPI.World as ServerMain;
147178 serverMain.EventManager.TriggerChatCommand(mechanicalTurk, GlobalConstants.ServerInfoChatGroup, @"genbackup", new CmdArgs( ));
148-
149- } else
150- {
179+ _lastBackupTime = DateTimeOffset.UtcNow;
180+ } else {
151181 Logger.Warning("Could not invoke backup command - API (implimentation) has changed, Contact Developer!");
182+ this.backupTickerID = 0;
183+ return;
152184 }
153185
186+ this.backupTickerID = ServerAPI.Event.RegisterCallback(BackupCycleHandler, ( int )this.CachedConfiguration.BackupDelay.TotalMilliseconds);
187+ Logger.Notification("BackupCycle re-engaged, delay: {0} next time: {1}", this.CachedConfiguration.BackupDelay.ToString(_timeFormat), DateTimeOffset.UtcNow.Add(this.CachedConfiguration.BackupDelay).ToString("u"));
154188
155189 //GlobalConstants.ConsoleGroup
156190 /*
157191 backupFileName = Path.GetFileName(server.Config.WorldConfig.SaveFileLocation).Replace(GlobalConstants.WorldSaveExtension, "") + "-" + string.Format("{0:yyyy-MM-dd_HH-mm-ss}", DateTime.Now) + GlobalConstants.WorldSaveExtension;
158192 */
193+
159194 }
160195
161196 private void AlterTimeDelay(int delay)
@@ -164,11 +199,97 @@ namespace AdminToolkit
164199 delay = Math.Min(delay, 500);//Limited by callback set in milliseconds
165200
166201 this.CachedConfiguration.BackupDelay = new TimeSpan(delay, 0, 0);
202+
203+ if (this.Enabled)
204+ {
205+ ToggleBackupCycle(false);
206+ ToggleBackupCycle(true);
207+ }
167208 }
168209
169- private void UseAMacro( )
210+ private void StatusLine(StringBuilder msgLine)
170211 {
171-
212+ msgLine.AppendFormat("Delay: {0}, Max Backups:{1}, Auto-start:{2}, ", CachedConfiguration.BackupDelay.ToString(_timeFormat),CachedConfiguration.BackupCount,CachedConfiguration.Autobackup );
213+
214+ if (this.Enabled) {
215+ msgLine.AppendFormat("<font color='lime'>Currently enabled: YES</font>\n");
216+ } else {
217+ msgLine.AppendFormat("<font color='red'>Currently enabled: NO</font>\n");
218+ }
219+
220+ if (_lastBackupTime != DateTimeOffset.MinValue)
221+ {
222+ msgLine.AppendFormat("Last Backup attempt: {0} ", _lastBackupTime.ToString("u") );
223+ msgLine.AppendFormat("Next backup due: {0}\n",_lastBackupTime.Add(CachedConfiguration.BackupDelay).ToString("u") );
224+ }
225+
226+ var backupDir = new DirectoryInfo(GamePaths.Backups);
227+ long totalBackupSize = 0;
228+
229+ if (backupDir.Exists)
230+ {
231+ var backups = backupDir.GetFiles(fileFilter);
232+
233+ foreach (FileInfo backFile in backups)
234+ {
235+ msgLine.AppendFormat("<font color='white'> '{0}' Size: {1} Written: {2} </font>\n", backFile.Name, FileSizeReadable(backFile.Length), backFile.LastWriteTimeUtc.ToString("u"));
236+ totalBackupSize += backFile.Length;
237+ }
238+
239+ msgLine.AppendFormat("Total size: {0} in {1} files.\n", FileSizeReadable(totalBackupSize),backups.Length);
240+
241+ }
242+ }
243+
244+ public static string FileSizeReadable(long i)
245+ {
246+ // Get absolute value
247+ long absolute_i = (i < 0 ? -i : i);
248+ // Determine the suffix and readable value
249+ string suffix;
250+ double readable;
251+ if (absolute_i >= 0x1000000000000000) // Exabyte
252+ {
253+ suffix = "EB";
254+ readable = (i >> 50);
255+ } else if (absolute_i >= 0x4000000000000) // Petabyte
256+ {
257+ suffix = "PB";
258+ readable = (i >> 40);
259+ } else if (absolute_i >= 0x10000000000) // Terabyte
260+ {
261+ suffix = "TB";
262+ readable = (i >> 30);
263+ } else if (absolute_i >= 0x40000000) // Gigabyte
264+ {
265+ suffix = "GB";
266+ readable = (i >> 20);
267+ } else if (absolute_i >= 0x100000) // Megabyte
268+ {
269+ suffix = "MB";
270+ readable = (i >> 10);
271+ } else if (absolute_i >= 0x400) // Kilobyte
272+ {
273+ suffix = "KB";
274+ readable = i;
275+ } else {
276+ return i.ToString("0 B"); // Byte
277+ }
278+ // Divide by 1024 to get fractional value
279+ readable = (readable / 1024);
280+ // Return formatted number with suffix
281+ return readable.ToString("0.### ") + suffix;
282+ }
283+
284+ private void ServerStarts( )
285+ {
286+ //ServerAPI.WorldManager.CurrentWorldName
287+ //ServerAPI.WorldManager.SaveGame.WorldName
288+ string worldNameTrimmed = Path.GetFileNameWithoutExtension(ServerAPI.WorldManager.CurrentWorldName);
289+ fileFilter = $"{worldNameTrimmed}-*{GlobalConstants.WorldSaveExtension}";
290+ Logger.VerboseDebug("File Filter: {0}", fileFilter);
291+
292+ if (CachedConfiguration.Autobackup) { ToggleBackupCycle(true); }
172293 }
173294 }
174295