2018-11-01 23:40:50 +08:00
|
|
|
using System;
|
|
|
|
using System.IO;
|
2021-01-03 11:38:20 +08:00
|
|
|
using System.Linq;
|
2021-01-01 14:46:27 +08:00
|
|
|
using System.Text;
|
|
|
|
using Newtonsoft.Json;
|
2021-02-23 18:03:37 +08:00
|
|
|
using Serilog;
|
2018-11-01 23:40:50 +08:00
|
|
|
|
2021-01-01 14:46:27 +08:00
|
|
|
#nullable enable
|
2018-11-01 23:40:50 +08:00
|
|
|
namespace BililiveRecorder.Core.Config
|
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
public class ConfigParser
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
private const string CONFIG_FILE_NAME = "config.json";
|
2021-02-23 18:03:37 +08:00
|
|
|
private static readonly ILogger logger = Log.ForContext<ConfigParser>();
|
|
|
|
private static readonly JsonSerializerSettings settings = new JsonSerializerSettings()
|
|
|
|
{
|
|
|
|
DefaultValueHandling = DefaultValueHandling.Ignore,
|
|
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
|
|
};
|
2020-06-21 19:39:32 +08:00
|
|
|
|
2021-01-01 14:46:27 +08:00
|
|
|
public static V2.ConfigV2? LoadFrom(string directory)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
try
|
2019-01-31 14:17:38 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
if (!Directory.Exists(directory))
|
|
|
|
return null;
|
2019-01-31 14:17:38 +08:00
|
|
|
|
2021-01-01 14:46:27 +08:00
|
|
|
var filepath = Path.Combine(directory, CONFIG_FILE_NAME);
|
|
|
|
|
|
|
|
if (!File.Exists(filepath))
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
logger.Debug("Config file does not exist {Path}", filepath);
|
2021-01-01 14:46:27 +08:00
|
|
|
return new V2.ConfigV2();
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
2021-01-01 14:46:27 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
logger.Debug("Loading config from {Path}", filepath);
|
2021-01-01 14:46:27 +08:00
|
|
|
var json = File.ReadAllText(filepath, Encoding.UTF8);
|
|
|
|
return LoadJson(json);
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
logger.Error(ex, "从文件加载设置时出错");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static V2.ConfigV2? LoadJson(string json)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
logger.Debug("Config json: {Json}", json);
|
2021-01-01 14:46:27 +08:00
|
|
|
|
|
|
|
var configBase = JsonConvert.DeserializeObject<ConfigBase>(json);
|
|
|
|
switch (configBase)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
case V1.ConfigV1Wrapper v1:
|
|
|
|
{
|
|
|
|
logger.Debug("读取到 config v1");
|
|
|
|
#pragma warning disable CS0612
|
2021-02-23 18:03:37 +08:00
|
|
|
var v1Data = JsonConvert.DeserializeObject<V1.ConfigV1>(v1.Data ?? string.Empty);
|
2021-01-01 14:46:27 +08:00
|
|
|
#pragma warning restore CS0612
|
2021-05-01 17:57:43 +08:00
|
|
|
if (v1Data is null)
|
|
|
|
return new V2.ConfigV2();
|
2021-01-01 14:46:27 +08:00
|
|
|
|
2021-05-01 17:57:43 +08:00
|
|
|
var newConfig = ConfigMapper.Map1To2(v1Data);
|
2021-01-01 14:46:27 +08:00
|
|
|
return newConfig;
|
|
|
|
}
|
|
|
|
case V2.ConfigV2 v2:
|
|
|
|
logger.Debug("读取到 config v2");
|
|
|
|
return v2;
|
|
|
|
default:
|
|
|
|
logger.Error("读取到不支持的设置版本");
|
|
|
|
return null;
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
|
|
|
}
|
2021-01-01 14:46:27 +08:00
|
|
|
catch (Exception ex)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
logger.Error(ex, "解析设置时出错");
|
|
|
|
return null;
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-01 14:46:27 +08:00
|
|
|
public static bool SaveTo(string directory, V2.ConfigV2 config)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-04 16:24:36 +08:00
|
|
|
if (config.DisableConfigSave)
|
|
|
|
{
|
|
|
|
logger.Debug("Skipping write config because DisableConfigSave is true.");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-01-01 14:46:27 +08:00
|
|
|
var json = SaveJson(config);
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (!Directory.Exists(directory))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
var filepath = Path.Combine(directory, CONFIG_FILE_NAME);
|
|
|
|
|
|
|
|
if (json is not null)
|
2021-01-03 11:38:20 +08:00
|
|
|
WriteAllTextWithBackup(filepath, json);
|
2021-01-01 14:46:27 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
logger.Error(ex, "保存设置时出错(写入文件)");
|
2018-11-01 23:40:50 +08:00
|
|
|
return false;
|
|
|
|
}
|
2021-01-01 14:46:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static string? SaveJson(V2.ConfigV2 config)
|
|
|
|
{
|
2018-11-01 23:40:50 +08:00
|
|
|
try
|
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
var json = JsonConvert.SerializeObject(config, Formatting.None, settings);
|
2021-01-01 14:46:27 +08:00
|
|
|
return json;
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
2021-01-01 14:46:27 +08:00
|
|
|
catch (Exception ex)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
logger.Error(ex, "保存设置时出错(序列化)");
|
|
|
|
return null;
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
|
|
|
}
|
2021-01-03 11:38:20 +08:00
|
|
|
|
|
|
|
// https://stackoverflow.com/q/25366534 with modification
|
|
|
|
private static void WriteAllTextWithBackup(string path, string contents)
|
|
|
|
{
|
2021-01-06 00:31:42 +08:00
|
|
|
if (!File.Exists(path))
|
|
|
|
{
|
|
|
|
File.WriteAllText(path, contents);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-01-03 11:38:20 +08:00
|
|
|
var ext = Path.GetExtension(path);
|
|
|
|
|
|
|
|
var tempPath = Path.Combine(Path.GetDirectoryName(path), Path.ChangeExtension(path, RandomString(6) + ext));
|
|
|
|
var backupPath = Path.ChangeExtension(path, "backup" + ext);
|
|
|
|
|
|
|
|
// delete any existing backups
|
|
|
|
if (File.Exists(backupPath))
|
|
|
|
File.Delete(backupPath);
|
|
|
|
|
|
|
|
// get the bytes
|
|
|
|
var data = Encoding.UTF8.GetBytes(contents);
|
|
|
|
|
|
|
|
// write the data to a temp file
|
|
|
|
using (var tempFile = File.Create(tempPath, 4096, FileOptions.WriteThrough))
|
|
|
|
tempFile.Write(data, 0, data.Length);
|
|
|
|
|
|
|
|
// replace the contents
|
|
|
|
File.Replace(tempPath, path, backupPath);
|
|
|
|
}
|
|
|
|
private static readonly Random random = new Random();
|
|
|
|
private static string RandomString(int length) => new string(Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", length).Select(s => s[random.Next(s.Length)]).ToArray());
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
|
|
|
}
|