From 67b7b1b0a7ec15c88501dc043b86d8f9307b4da9 Mon Sep 17 00:00:00 2001 From: tieonlinux Date: Wed, 1 Jul 2020 15:15:00 +0200 Subject: [PATCH 1/4] Added Config json feature Embed a lightweight json parser instead of the json.net provided by tshock. Because it doesn't work with .netcore unit test requiring some other version. --- .github/workflows/main.yml | 1 - .gitmodules | 3 + DiffBackup/Backup/BackupService.cs | 22 +++- DiffBackup/Backup/BackupStrategy.cs | 73 ++++++------ DiffBackup/Backup/Config/AllConfig.cs | 9 ++ DiffBackup/Backup/Config/BaseConfig.cs | 41 +++++++ DiffBackup/Backup/Config/CleanupConfig.cs | 22 ++++ DiffBackup/Backup/Config/CleanupTimeConfig.cs | 28 +++++ DiffBackup/Backup/Config/Config.cs | 20 ---- DiffBackup/Backup/Config/IConfig.cs | 13 +++ DiffBackup/Backup/Config/InternalConfig.cs | 14 +++ .../Backup/Config/Json/JsonConverters.cs | 69 +++++++++++ .../Backup/Config/Json/TShockConfigHandler.cs | 65 +++++++++++ DiffBackup/Backup/Config/StrategyConfig.cs | 12 ++ DiffBackup/Backup/Config/TimeSpanConfig.cs | 35 ++++++ .../Config}/WorldSaveTrackingStrategy.cs | 6 +- DiffBackup/DiffBackup.csproj | 95 ++++++++++++++- DiffBackup/TdiffPlugin.cs | 29 ++++- .../{ => Backup}/BackupServiceTests.cs | 15 ++- .../Config/Json/TShockConfigHandlerTests.cs | 108 ++++++++++++++++++ .../DefaultBackupStrategyTests.cs | 15 ++- DiffBackupTests/DiffBackupTests.csproj | 1 + JsonKit | 1 + bootstrap.py | 7 +- 24 files changed, 622 insertions(+), 82 deletions(-) create mode 100644 DiffBackup/Backup/Config/AllConfig.cs create mode 100644 DiffBackup/Backup/Config/BaseConfig.cs create mode 100644 DiffBackup/Backup/Config/CleanupConfig.cs create mode 100644 DiffBackup/Backup/Config/CleanupTimeConfig.cs delete mode 100644 DiffBackup/Backup/Config/Config.cs create mode 100644 DiffBackup/Backup/Config/IConfig.cs create mode 100644 DiffBackup/Backup/Config/InternalConfig.cs create mode 100644 DiffBackup/Backup/Config/Json/JsonConverters.cs create mode 100644 DiffBackup/Backup/Config/Json/TShockConfigHandler.cs create mode 100644 DiffBackup/Backup/Config/StrategyConfig.cs create mode 100644 DiffBackup/Backup/Config/TimeSpanConfig.cs rename DiffBackup/{ => Backup/Config}/WorldSaveTrackingStrategy.cs (66%) rename DiffBackupTests/{ => Backup}/BackupServiceTests.cs (96%) create mode 100644 DiffBackupTests/Backup/Config/Json/TShockConfigHandlerTests.cs rename DiffBackupTests/{ => Backup}/DefaultBackupStrategyTests.cs (91%) create mode 160000 JsonKit diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 858c91f..3178665 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,7 +3,6 @@ name: CI # Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the main branch on: push: branches: [ main, dev ] diff --git a/.gitmodules b/.gitmodules index b6c46cb..a013ccf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "Base32"] path = Base32 url = https://gist.github.com/9335c394c5cc65404c4cf9aceab04143.git +[submodule "JsonKit"] + path = JsonKit + url = https://github.com/toptensoftware/JsonKit.git diff --git a/DiffBackup/Backup/BackupService.cs b/DiffBackup/Backup/BackupService.cs index 66c64b0..15ca387 100644 --- a/DiffBackup/Backup/BackupService.cs +++ b/DiffBackup/Backup/BackupService.cs @@ -5,7 +5,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using deltaq_tie.BsDiff; +using deltaq_tie_tdiff.BsDiff; +using DiffBackup.Backup.Config; using DiffBackup.Logger; using TShockAPI.Extensions; @@ -16,13 +17,16 @@ namespace DiffBackup.Backup public class BackupService : IDisposable, IBackupService { private readonly SemaphoreSlim _saveDiffSemaphore = new SemaphoreSlim(1, 1); + public readonly AllConfig Config; public readonly ITlog Log; private Stopwatch _saveDiffStopWatch = new Stopwatch(); - public BackupService(ITlog log, IBackupStrategy? strategy = null, BackupIOWorker? worker = null) + public BackupService(ITlog log, AllConfig config, IBackupStrategy? strategy = null, + BackupIOWorker? worker = null) { Log = log; - Strategy = strategy ?? new DefaultBackupStrategy(Log); + Config = config.Clone(); + Strategy = strategy ?? new DefaultBackupStrategy(Log, config.Strategy); Worker = worker ?? new BackupIOWorker(log); var env = Environment.GetEnvironmentVariables(); @@ -37,7 +41,11 @@ public BackupService(ITlog log, IBackupStrategy? strategy = null, BackupIOWorker } } - public TimeSpan ThrottleTimeSpan { get; set; } = TimeSpan.FromMinutes(1); + public TimeSpan ThrottleTimeSpan + { + get => Config.Internal.ThrottleTimeSpan; + set => Config.Internal.ThrottleTimeSpan = value; + } public bool ShouldThrottle => ThrottleTimeSpan > TimeSpan.Zero && _saveDiffStopWatch.IsRunning && @@ -189,7 +197,11 @@ public async Task BackupSaveAsync(string path, DateTime? dateTime = null, CancellationToken cancellationToken = default) { using var timed = new CancellationTokenSource(); - timed.CancelAfter(TimeSpan.FromMinutes(3)); + if (Config.Internal.BackupTaskTimeoutTimeSpan > TimeSpan.Zero) + { + timed.CancelAfter(Config.Internal.BackupTaskTimeoutTimeSpan); + } + using var tokenSource = CancellationTokenSource.CreateLinkedTokenSource(Worker.Token, cancellationToken, timed.Token); tokenSource.Token.ThrowIfCancellationRequested(); diff --git a/DiffBackup/Backup/BackupStrategy.cs b/DiffBackup/Backup/BackupStrategy.cs index 5d56f91..00c0d98 100644 --- a/DiffBackup/Backup/BackupStrategy.cs +++ b/DiffBackup/Backup/BackupStrategy.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using DiffBackup.Backup.Config; using DiffBackup.Logger; #nullable enable @@ -9,11 +10,14 @@ namespace DiffBackup.Backup { public class DefaultBackupStrategy : IBackupStrategy { + public readonly StrategyConfig Config; public readonly ITlog Log; - public DefaultBackupStrategy(ITlog log) + public DefaultBackupStrategy(ITlog log, StrategyConfig config) { Log = log; + Config = config.Clone(); + Config.SetFromJson(config.ToJson()); var env = Environment.GetEnvironmentVariables(); // ReSharper disable once InconsistentNaming @@ -24,17 +28,34 @@ public DefaultBackupStrategy(ITlog log) TimeSpan.FromDays( double.Parse(Environment.GetEnvironmentVariable(TdiffOverwriteForceFullBackupTimeSpan))); } + else + { + ForceFullBackupTimeSpan = config.EveryXTimeSpanDoFullBackup; + } // ReSharper disable once InconsistentNaming const string TdiffOverwriteFillFactor = nameof(TdiffOverwriteFillFactor); if (env.Contains(TdiffOverwriteFillFactor)) { - FillFactor = float.Parse(Environment.GetEnvironmentVariable(TdiffOverwriteFillFactor)); + FillFactor = double.Parse(Environment.GetEnvironmentVariable(TdiffOverwriteFillFactor)); + } + else + { + FillFactor = config.DiffFillFactorToStartFullBackup; } } - public TimeSpan ForceFullBackupTimeSpan { get; set; } = TimeSpan.FromDays(7); - public float FillFactor { get; set; } = 0.5f; + public TimeSpan ForceFullBackupTimeSpan + { + get => Config.EveryXTimeSpanDoFullBackup; + set => Config.EveryXTimeSpanDoFullBackup = value; + } + + public double FillFactor + { + get => Config.DiffFillFactorToStartFullBackup; + set => Config.DiffFillFactorToStartFullBackup = value; + } public BackupRepositoryEntry? GetReference(BackupRepository repo, DateTime date) { @@ -97,34 +118,30 @@ public IList ListExpiredEntries(BackupRepository repo, Da } } - CleanupTimeConfig[] worldCleanupTimeConfigs = - { - new CleanupTimeConfig("yearly", TimeSpan.FromDays(365.25), TimeSpan.FromDays(3)), - new CleanupTimeConfig("monthly", TimeSpan.FromDays(30.44), TimeSpan.FromHours(12)), - new CleanupTimeConfig("weekly", TimeSpan.FromDays(7), TimeSpan.FromHours(1)) - }; - CleanupTimeConfig[] diffCleanupTimeConfigs = + foreach (var config in Config.Cleanup.WldFiles) { - new CleanupTimeConfig("yearly", TimeSpan.FromDays(365.25), TimeSpan.MaxValue), - new CleanupTimeConfig("monthly", TimeSpan.FromDays(30.44), TimeSpan.FromMinutes(30)), - new CleanupTimeConfig("weekly", TimeSpan.FromDays(7), TimeSpan.FromMinutes(1)) - }; - + if (config.AgeFilter <= TimeSpan.Zero) + { + continue; + } - foreach (var config in worldCleanupTimeConfigs) - { var marked = ConsumeIEnumerable(MarkOldEntries(backups.Where(backup => !backup.IsDiff), config.AgeFilter, config.KeepBackupEveryTimeSpan)); - Log.LogDebug($"Marked {marked} entries for {config.Text.ToLower()} wld cleanup"); + Log.LogDebug($"Marked {marked} entries for {config.Name} wld cleanup"); } - foreach (var config in diffCleanupTimeConfigs) + foreach (var config in Config.Cleanup.DiffFiles) { + if (config.AgeFilter <= TimeSpan.Zero) + { + continue; + } + var marked = ConsumeIEnumerable(MarkOldEntries(backups.Where(backup => backup.IsDiff), config.AgeFilter, config.KeepBackupEveryTimeSpan)); - Log.LogDebug($"Marked {marked} entries for {config.Text.ToLower()} diff cleanup"); + Log.LogDebug($"Marked {marked} entries for {config.Name} diff cleanup"); } foreach (var entry in backups.Where(backup => !backup.Valid)) @@ -143,19 +160,5 @@ internal static int ConsumeIEnumerable(IEnumerable enumerable) { return enumerable.Count(); } - - public readonly struct CleanupTimeConfig - { - public readonly string Text; - public readonly TimeSpan AgeFilter; - public readonly TimeSpan KeepBackupEveryTimeSpan; - - public CleanupTimeConfig(string text, TimeSpan ageFilter, TimeSpan keepBackupEveryTimeSpan) - { - Text = text; - AgeFilter = ageFilter; - KeepBackupEveryTimeSpan = keepBackupEveryTimeSpan; - } - } } } \ No newline at end of file diff --git a/DiffBackup/Backup/Config/AllConfig.cs b/DiffBackup/Backup/Config/AllConfig.cs new file mode 100644 index 0000000..4ca934e --- /dev/null +++ b/DiffBackup/Backup/Config/AllConfig.cs @@ -0,0 +1,9 @@ +namespace DiffBackup.Backup.Config +{ + public class AllConfig : BaseConfig + { + public int Version { get; set; } = 1; + public StrategyConfig Strategy { get; set; } = new StrategyConfig(); + public InternalConfig Internal { get; set; } = new InternalConfig(); + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/BaseConfig.cs b/DiffBackup/Backup/Config/BaseConfig.cs new file mode 100644 index 0000000..393d411 --- /dev/null +++ b/DiffBackup/Backup/Config/BaseConfig.cs @@ -0,0 +1,41 @@ +using System; +using Topten.JsonKit_tie_tdiff; + +namespace DiffBackup.Backup.Config +{ + public abstract class BaseConfig : IConfig + { + public BaseConfig() + { + } + + public BaseConfig(BaseConfig copy) + { + Topten.JsonKit_tie_tdiff.Json.CloneInto(this, copy); + } + + public IConfig Clone() + { + return Clone(); + } + + public T Clone() where T : IConfig + { + if (this is T t) + { + return Topten.JsonKit_tie_tdiff.Json.Clone(t); + } + throw new TypeAccessException(); + } + + public string ToJson(JsonOptions options = JsonOptions.None) + { + return Topten.JsonKit_tie_tdiff.Json.Format(this, options); + } + + public void SetFromJson(string data, JsonOptions options = JsonOptions.None) + { + Topten.JsonKit_tie_tdiff.Json.ParseInto(data, this, options); + } + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/CleanupConfig.cs b/DiffBackup/Backup/Config/CleanupConfig.cs new file mode 100644 index 0000000..04dfe24 --- /dev/null +++ b/DiffBackup/Backup/Config/CleanupConfig.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace DiffBackup.Backup.Config +{ + public class CleanupConfig : BaseConfig + { + public List WldFiles { get; set; } = new List + { + new CleanupTimeConfig("yearly", TimeSpan.FromDays(365), TimeSpan.FromDays(3)), + new CleanupTimeConfig("monthly", TimeSpan.FromDays(30), TimeSpan.FromHours(12)), + new CleanupTimeConfig("weekly", TimeSpan.FromDays(7), TimeSpan.FromHours(1)) + }; + + public List DiffFiles { get; set; } = new List + { + new CleanupTimeConfig("yearly", TimeSpan.FromDays(365), TimeSpan.FromDays(365)), + new CleanupTimeConfig("monthly", TimeSpan.FromDays(30), TimeSpan.FromMinutes(30)), + new CleanupTimeConfig("weekly", TimeSpan.FromDays(7), TimeSpan.FromMinutes(1)) + }; + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/CleanupTimeConfig.cs b/DiffBackup/Backup/Config/CleanupTimeConfig.cs new file mode 100644 index 0000000..04a6d0e --- /dev/null +++ b/DiffBackup/Backup/Config/CleanupTimeConfig.cs @@ -0,0 +1,28 @@ +using System; + +namespace DiffBackup.Backup.Config +{ + public class CleanupTimeConfig : BaseConfig + { + public CleanupTimeConfig() + { + } + + public CleanupTimeConfig(string name, TimeSpan ageFilter, TimeSpan keepBackupEveryTimeSpan) + { + Name = name; + AgeFilter = ageFilter; + KeepBackupEveryTimeSpan = keepBackupEveryTimeSpan; + } + + public CleanupTimeConfig(CleanupTimeConfig copy) : base(copy) + { + } + + public string Name { get; set; } = ""; + + public TimeSpanConfig AgeFilter { get; set; } = TimeSpan.Zero; + + public TimeSpanConfig KeepBackupEveryTimeSpan { get; set; } = TimeSpan.MaxValue; + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/Config.cs b/DiffBackup/Backup/Config/Config.cs deleted file mode 100644 index f7d9d89..0000000 --- a/DiffBackup/Backup/Config/Config.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace DiffBackup.Backup.Config -{ - public class InternalConfig - { - public double ThrottleSecond { get; set; } = 60; - } - - - public class StrategyConfig - { - public double EveryXDayDoFullBackup { get; set; } = 7; - public double FillFactorToStartFullBackup { get; set; } = 0.5; - } - - public class Config - { - public StrategyConfig Strategy { get; set; } = new StrategyConfig(); - public InternalConfig Internal { get; set; } = new InternalConfig(); - } -} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/IConfig.cs b/DiffBackup/Backup/Config/IConfig.cs new file mode 100644 index 0000000..c245353 --- /dev/null +++ b/DiffBackup/Backup/Config/IConfig.cs @@ -0,0 +1,13 @@ +using Topten.JsonKit_tie_tdiff; + +namespace DiffBackup.Backup.Config +{ + public interface IConfig + { + IConfig Clone(); + T Clone() where T: IConfig; + string ToJson(JsonOptions options = JsonOptions.None); + + void SetFromJson(string payload, JsonOptions options = JsonOptions.None); + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/InternalConfig.cs b/DiffBackup/Backup/Config/InternalConfig.cs new file mode 100644 index 0000000..fe0f131 --- /dev/null +++ b/DiffBackup/Backup/Config/InternalConfig.cs @@ -0,0 +1,14 @@ +using System; + +namespace DiffBackup.Backup.Config +{ + public class InternalConfig : BaseConfig + { + public TimeSpanConfig ThrottleTimeSpan { get; set; } = TimeSpan.FromSeconds(60); + + public TimeSpanConfig BackupTaskTimeoutTimeSpan { get; set; } = TimeSpan.FromMinutes(3); + + public WorldSaveTrackingStrategy WorldSaveTrackingStrategy { get; set; } = + WorldSaveTrackingStrategy.SaveEventListener; + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/Json/JsonConverters.cs b/DiffBackup/Backup/Config/Json/JsonConverters.cs new file mode 100644 index 0000000..5d5741f --- /dev/null +++ b/DiffBackup/Backup/Config/Json/JsonConverters.cs @@ -0,0 +1,69 @@ +using System; +using Topten.JsonKit_tie_tdiff; + +namespace DiffBackup.Backup.Config.Json +{ + public static class JsonConverters + { + /// + /// Format: Days.Hours:Minutes:Seconds:Milliseconds + /// + public const string TimeSpanFormatString = @"d\.hh\:mm\:ss\:FFF"; + + private static readonly object Lock = new object(); + + static JsonConverters() + { + Install(); + } + + public static bool Installed { get; private set; } + + public static bool Install() + { + if (!Installed) + { + lock (Lock) + { + if (!Installed) + { + Topten.JsonKit_tie_tdiff.Json.RegisterFormatter(WriteJson); + Topten.JsonKit_tie_tdiff.Json.RegisterParser(TimeSpanParseJson); + Topten.JsonKit_tie_tdiff.Json.RegisterFormatter(WriteJson); + Topten.JsonKit_tie_tdiff.Json.RegisterParser(WorldSaveTrackingStrategyParseJson); + Installed = true; + return true; + } + } + } + + return false; + } + + private static TimeSpanConfig TimeSpanParseJson(object literal) + { + var res = TimeSpan.ParseExact((string) literal, TimeSpanFormatString, null); + return res; + } + + private static void WriteJson(IJsonWriter writer, TimeSpanConfig value) + { + writer.WriteStringLiteral($"{value.Value.ToString(TimeSpanFormatString)}"); + } + + private static void WriteJson(IJsonWriter writer, WorldSaveTrackingStrategy value) + { + writer.WriteStringLiteral(value.ToString()); + } + + private static WorldSaveTrackingStrategy WorldSaveTrackingStrategyParseJson(object literal) + { + if (Enum.TryParse((string) literal, out WorldSaveTrackingStrategy res)) + { + return res; + } + + return WorldSaveTrackingStrategy.SaveEventListener; + } + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/Json/TShockConfigHandler.cs b/DiffBackup/Backup/Config/Json/TShockConfigHandler.cs new file mode 100644 index 0000000..ce08fc3 --- /dev/null +++ b/DiffBackup/Backup/Config/Json/TShockConfigHandler.cs @@ -0,0 +1,65 @@ +using System.IO; +using System.Text; +using Topten.JsonKit_tie_tdiff; +using TShockAPI; + +#nullable enable +namespace DiffBackup.Backup.Config.Json +{ + public class TShockConfigHandler + { + public readonly string BasePath; + + public TShockConfigHandler(string basePath) + { + JsonConverters.Install(); + BasePath = Path.GetFullPath(basePath); + } + + public TShockConfigHandler() : this(TShock.SavePath) + { + } + + + public T LoadJson(string fileName) where T : class?, new() + { + var path = Path.Combine(BasePath, fileName); + var content = File.ReadAllText(path, Encoding.UTF8); + return Topten.JsonKit_tie_tdiff.Json.Parse(content, JsonOptions.NonStrictParser); + } + + public bool TryLoadJson(string fileName, out T result) + where T : new() + { + var path = GetFullPath(fileName); + + if (!File.Exists(path)) + { + result = new T(); + return false; + } + + var content = File.ReadAllText(path, Encoding.UTF8); + if (string.IsNullOrWhiteSpace(content)) + { + result = new T(); + return false; + } + + result = Topten.JsonKit_tie_tdiff.Json.Parse(content, JsonOptions.NonStrictParser); + return true; + } + + public void SaveConfig(T config, string fileName) + { + var path = GetFullPath(fileName); + var payload = Topten.JsonKit_tie_tdiff.Json.Format(config); + File.WriteAllText(path, payload, Encoding.UTF8); + } + + public string GetFullPath(string fileName) + { + return Path.Combine(BasePath, fileName); + } + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/StrategyConfig.cs b/DiffBackup/Backup/Config/StrategyConfig.cs new file mode 100644 index 0000000..aa64db5 --- /dev/null +++ b/DiffBackup/Backup/Config/StrategyConfig.cs @@ -0,0 +1,12 @@ +using System; + +namespace DiffBackup.Backup.Config +{ + public class StrategyConfig : BaseConfig + { + public TimeSpanConfig EveryXTimeSpanDoFullBackup { get; set; } = TimeSpan.FromDays(7); + + public double DiffFillFactorToStartFullBackup { get; set; } = 0.5; + public CleanupConfig Cleanup { get; set; } = new CleanupConfig(); + } +} \ No newline at end of file diff --git a/DiffBackup/Backup/Config/TimeSpanConfig.cs b/DiffBackup/Backup/Config/TimeSpanConfig.cs new file mode 100644 index 0000000..2c7ad89 --- /dev/null +++ b/DiffBackup/Backup/Config/TimeSpanConfig.cs @@ -0,0 +1,35 @@ +using System; +using DiffBackup.Backup.Config.Json; + +namespace DiffBackup.Backup.Config +{ + public readonly struct TimeSpanConfig + { + public readonly TimeSpan Value; + + public TimeSpanConfig(TimeSpan value) + { + Value = value; + } + + public static implicit operator TimeSpan(TimeSpanConfig input) + { + return input.Value; + } + + public static implicit operator TimeSpanConfig(TimeSpan input) + { + return new TimeSpanConfig(input); + } + + public string FormatJson() + { + return $"{Value.ToString(JsonConverters.TimeSpanFormatString)}"; + } + + public static TimeSpanConfig ParseJson(string literal) + { + return TimeSpan.ParseExact(literal, JsonConverters.TimeSpanFormatString, null); + } + } +} \ No newline at end of file diff --git a/DiffBackup/WorldSaveTrackingStrategy.cs b/DiffBackup/Backup/Config/WorldSaveTrackingStrategy.cs similarity index 66% rename from DiffBackup/WorldSaveTrackingStrategy.cs rename to DiffBackup/Backup/Config/WorldSaveTrackingStrategy.cs index b78aece..032e1e8 100644 --- a/DiffBackup/WorldSaveTrackingStrategy.cs +++ b/DiffBackup/Backup/Config/WorldSaveTrackingStrategy.cs @@ -5,9 +5,9 @@ namespace DiffBackup [Flags] public enum WorldSaveTrackingStrategy : byte { - None, - FileSystemWatcher, - SaveEventListener, + None = 0, + FileSystemWatcher = 1, + SaveEventListener = 1 << 1, All = FileSystemWatcher | SaveEventListener } } \ No newline at end of file diff --git a/DiffBackup/DiffBackup.csproj b/DiffBackup/DiffBackup.csproj index b9043fd..89d0bc1 100644 --- a/DiffBackup/DiffBackup.csproj +++ b/DiffBackup/DiffBackup.csproj @@ -41,6 +41,7 @@ + ..\TShock\TerrariaServer.exe @@ -116,13 +117,104 @@ HumanDateParser\TokenKind.cs + + JsonKit\CancelReaderException.cs + + + JsonKit\DecoratingActivator.cs + + + JsonKit\Emit.cs + + + JsonKit\IDictionaryExtensions.cs + + + JsonKit\IJsonLoaded.cs + + + JsonKit\IJsonLoadField.cs + + + JsonKit\IJsonLoading.cs + + + JsonKit\IJsonReader.cs + + + JsonKit\IJsonWriter.cs + + + JsonKit\IJsonWriting.cs + + + JsonKit\IJsonWritten.cs + + + JsonKit\JsonAttribute.cs + + + JsonKit\JsonExcludeAttribute.cs + + + JsonKit\JsonKit.cs + + + JsonKit\JsonMemberInfo.cs + + + JsonKit\JsonOptions.cs + + + JsonKit\JsonParseException.cs + + + JsonKit\JsonReader.cs + + + JsonKit\JsonUnknownAttribute.cs + + + JsonKit\JsonWriter.cs + + + JsonKit\LineOffset.cs + + + JsonKit\LiteralKind.cs + + + JsonKit\ReflectionInfo.cs + + + JsonKit\ThreadSafeCache.cs + + + JsonKit\Token.cs + + + JsonKit\Tokenizer.cs + + + JsonKit\Utils.cs + - + + + + + + + + + + + @@ -131,7 +223,6 @@ -