mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-16 03:32:20 +08:00
New config gen
This commit is contained in:
parent
405679a5d8
commit
5f96eb5393
|
@ -1,6 +1,6 @@
|
|||
// ******************************
|
||||
// GENERATED CODE, DO NOT EDIT MANUALLY.
|
||||
// SEE .tools/build_config.js
|
||||
// SEE /config_gen/README.md
|
||||
// ******************************
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
@ -13,18 +13,6 @@ namespace BililiveRecorder.Cli.Configure
|
|||
{
|
||||
[Description("[grey]Exit[/]")]
|
||||
Exit,
|
||||
TimingStreamRetry,
|
||||
TimingStreamConnect,
|
||||
TimingDanmakuRetry,
|
||||
TimingCheckInterval,
|
||||
TimingWatchdogTimeout,
|
||||
RecordDanmakuFlushInterval,
|
||||
Cookie,
|
||||
WebHookUrls,
|
||||
WebHookUrlsV2,
|
||||
LiveApiHost,
|
||||
RecordFilenameFormat,
|
||||
WpfShowTitleAndArea,
|
||||
RecordMode,
|
||||
CuttingMode,
|
||||
CuttingNumber,
|
||||
|
@ -33,7 +21,19 @@ namespace BililiveRecorder.Cli.Configure
|
|||
RecordDanmakuSuperChat,
|
||||
RecordDanmakuGift,
|
||||
RecordDanmakuGuard,
|
||||
RecordingQuality
|
||||
RecordingQuality,
|
||||
RecordFilenameFormat,
|
||||
WebHookUrls,
|
||||
WebHookUrlsV2,
|
||||
WpfShowTitleAndArea,
|
||||
Cookie,
|
||||
LiveApiHost,
|
||||
TimingCheckInterval,
|
||||
TimingStreamRetry,
|
||||
TimingStreamConnect,
|
||||
TimingDanmakuRetry,
|
||||
TimingWatchdogTimeout,
|
||||
RecordDanmakuFlushInterval
|
||||
}
|
||||
public enum RoomConfigProperties
|
||||
{
|
||||
|
@ -58,18 +58,6 @@ namespace BililiveRecorder.Cli.Configure
|
|||
|
||||
static ConfigInstructions()
|
||||
{
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingStreamRetry, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingStreamRetry = false, (config, value) => config.TimingStreamRetry = value) { Name = "TimingStreamRetry", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingStreamConnect, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingStreamConnect = false, (config, value) => config.TimingStreamConnect = value) { Name = "TimingStreamConnect", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingDanmakuRetry, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingDanmakuRetry = false, (config, value) => config.TimingDanmakuRetry = value) { Name = "TimingDanmakuRetry", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingCheckInterval, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingCheckInterval = false, (config, value) => config.TimingCheckInterval = value) { Name = "TimingCheckInterval", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingWatchdogTimeout, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingWatchdogTimeout = false, (config, value) => config.TimingWatchdogTimeout = value) { Name = "TimingWatchdogTimeout", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordDanmakuFlushInterval, new ConfigInstruction<GlobalConfig, uint>(config => config.HasRecordDanmakuFlushInterval = false, (config, value) => config.RecordDanmakuFlushInterval = value) { Name = "RecordDanmakuFlushInterval", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.Cookie, new ConfigInstruction<GlobalConfig, string>(config => config.HasCookie = false, (config, value) => config.Cookie = value) { Name = "Cookie", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WebHookUrls, new ConfigInstruction<GlobalConfig, string>(config => config.HasWebHookUrls = false, (config, value) => config.WebHookUrls = value) { Name = "WebHookUrls", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WebHookUrlsV2, new ConfigInstruction<GlobalConfig, string>(config => config.HasWebHookUrlsV2 = false, (config, value) => config.WebHookUrlsV2 = value) { Name = "WebHookUrlsV2", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.LiveApiHost, new ConfigInstruction<GlobalConfig, string>(config => config.HasLiveApiHost = false, (config, value) => config.LiveApiHost = value) { Name = "LiveApiHost", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordFilenameFormat, new ConfigInstruction<GlobalConfig, string>(config => config.HasRecordFilenameFormat = false, (config, value) => config.RecordFilenameFormat = value) { Name = "RecordFilenameFormat", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WpfShowTitleAndArea, new ConfigInstruction<GlobalConfig, bool>(config => config.HasWpfShowTitleAndArea = false, (config, value) => config.WpfShowTitleAndArea = value) { Name = "WpfShowTitleAndArea", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordMode, new ConfigInstruction<GlobalConfig, RecordMode>(config => config.HasRecordMode = false, (config, value) => config.RecordMode = value) { Name = "RecordMode", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.CuttingMode, new ConfigInstruction<GlobalConfig, CuttingMode>(config => config.HasCuttingMode = false, (config, value) => config.CuttingMode = value) { Name = "CuttingMode", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.CuttingNumber, new ConfigInstruction<GlobalConfig, uint>(config => config.HasCuttingNumber = false, (config, value) => config.CuttingNumber = value) { Name = "CuttingNumber", CanBeOptional = true });
|
||||
|
@ -79,6 +67,18 @@ namespace BililiveRecorder.Cli.Configure
|
|||
GlobalConfig.Add(GlobalConfigProperties.RecordDanmakuGift, new ConfigInstruction<GlobalConfig, bool>(config => config.HasRecordDanmakuGift = false, (config, value) => config.RecordDanmakuGift = value) { Name = "RecordDanmakuGift", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordDanmakuGuard, new ConfigInstruction<GlobalConfig, bool>(config => config.HasRecordDanmakuGuard = false, (config, value) => config.RecordDanmakuGuard = value) { Name = "RecordDanmakuGuard", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordingQuality, new ConfigInstruction<GlobalConfig, string>(config => config.HasRecordingQuality = false, (config, value) => config.RecordingQuality = value) { Name = "RecordingQuality", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordFilenameFormat, new ConfigInstruction<GlobalConfig, string>(config => config.HasRecordFilenameFormat = false, (config, value) => config.RecordFilenameFormat = value) { Name = "RecordFilenameFormat", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WebHookUrls, new ConfigInstruction<GlobalConfig, string>(config => config.HasWebHookUrls = false, (config, value) => config.WebHookUrls = value) { Name = "WebHookUrls", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WebHookUrlsV2, new ConfigInstruction<GlobalConfig, string>(config => config.HasWebHookUrlsV2 = false, (config, value) => config.WebHookUrlsV2 = value) { Name = "WebHookUrlsV2", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WpfShowTitleAndArea, new ConfigInstruction<GlobalConfig, bool>(config => config.HasWpfShowTitleAndArea = false, (config, value) => config.WpfShowTitleAndArea = value) { Name = "WpfShowTitleAndArea", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.Cookie, new ConfigInstruction<GlobalConfig, string>(config => config.HasCookie = false, (config, value) => config.Cookie = value) { Name = "Cookie", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.LiveApiHost, new ConfigInstruction<GlobalConfig, string>(config => config.HasLiveApiHost = false, (config, value) => config.LiveApiHost = value) { Name = "LiveApiHost", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingCheckInterval, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingCheckInterval = false, (config, value) => config.TimingCheckInterval = value) { Name = "TimingCheckInterval", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingStreamRetry, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingStreamRetry = false, (config, value) => config.TimingStreamRetry = value) { Name = "TimingStreamRetry", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingStreamConnect, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingStreamConnect = false, (config, value) => config.TimingStreamConnect = value) { Name = "TimingStreamConnect", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingDanmakuRetry, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingDanmakuRetry = false, (config, value) => config.TimingDanmakuRetry = value) { Name = "TimingDanmakuRetry", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.TimingWatchdogTimeout, new ConfigInstruction<GlobalConfig, uint>(config => config.HasTimingWatchdogTimeout = false, (config, value) => config.TimingWatchdogTimeout = value) { Name = "TimingWatchdogTimeout", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.RecordDanmakuFlushInterval, new ConfigInstruction<GlobalConfig, uint>(config => config.HasRecordDanmakuFlushInterval = false, (config, value) => config.RecordDanmakuFlushInterval = value) { Name = "RecordDanmakuFlushInterval", CanBeOptional = true });
|
||||
|
||||
RoomConfig.Add(RoomConfigProperties.RoomId, new ConfigInstruction<RoomConfig, int>(config => config.HasRoomId = false, (config, value) => config.RoomId = value) { Name = "RoomId", CanBeOptional = false });
|
||||
RoomConfig.Add(RoomConfigProperties.AutoRecord, new ConfigInstruction<RoomConfig, bool>(config => config.HasAutoRecord = false, (config, value) => config.AutoRecord = value) { Name = "AutoRecord", CanBeOptional = false });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// ******************************
|
||||
// GENERATED CODE, DO NOT EDIT MANUALLY.
|
||||
// SEE .tools/build_config.js
|
||||
// SEE /config_gen/README.md
|
||||
// ******************************
|
||||
|
||||
using System.ComponentModel;
|
||||
|
@ -22,7 +22,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<int> OptionalRoomId { get => this.GetPropertyValueOptional<int>(nameof(this.RoomId)); set => this.SetPropertyValueOptional(value, nameof(this.RoomId)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用自动录制
|
||||
/// 自动录制
|
||||
/// </summary>
|
||||
public bool AutoRecord { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasAutoRecord { get => this.GetPropertyHasValue(nameof(this.AutoRecord)); set => this.SetPropertyHasValue<bool>(value, nameof(this.AutoRecord)); }
|
||||
|
@ -38,7 +38,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<RecordMode> OptionalRecordMode { get => this.GetPropertyValueOptional<RecordMode>(nameof(this.RecordMode)); set => this.SetPropertyValueOptional(value, nameof(this.RecordMode)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件自动切割模式
|
||||
/// 自动分段模式
|
||||
/// </summary>
|
||||
public CuttingMode CuttingMode { get => this.GetPropertyValue<CuttingMode>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCuttingMode { get => this.GetPropertyHasValue(nameof(this.CuttingMode)); set => this.SetPropertyHasValue<CuttingMode>(value, nameof(this.CuttingMode)); }
|
||||
|
@ -46,7 +46,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<CuttingMode> OptionalCuttingMode { get => this.GetPropertyValueOptional<CuttingMode>(nameof(this.CuttingMode)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingMode)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件自动切割数值(分钟/MiB)
|
||||
/// 自动分段数值
|
||||
/// </summary>
|
||||
public uint CuttingNumber { get => this.GetPropertyValue<uint>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCuttingNumber { get => this.GetPropertyHasValue(nameof(this.CuttingNumber)); set => this.SetPropertyHasValue<uint>(value, nameof(this.CuttingNumber)); }
|
||||
|
@ -54,7 +54,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<uint> OptionalCuttingNumber { get => this.GetPropertyValueOptional<uint>(nameof(this.CuttingNumber)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingNumber)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制弹幕
|
||||
/// 弹幕录制
|
||||
/// </summary>
|
||||
public bool RecordDanmaku { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmaku { get => this.GetPropertyHasValue(nameof(this.RecordDanmaku)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmaku)); }
|
||||
|
@ -62,7 +62,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<bool> OptionalRecordDanmaku { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmaku)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmaku)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否记录弹幕原始数据
|
||||
/// 弹幕录制-原始数据
|
||||
/// </summary>
|
||||
public bool RecordDanmakuRaw { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuRaw { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuRaw)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuRaw)); }
|
||||
|
@ -70,7 +70,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<bool> OptionalRecordDanmakuRaw { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuRaw)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuRaw)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制 SuperChat
|
||||
/// 弹幕录制-SuperChat
|
||||
/// </summary>
|
||||
public bool RecordDanmakuSuperChat { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuSuperChat { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuSuperChat)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuSuperChat)); }
|
||||
|
@ -78,7 +78,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<bool> OptionalRecordDanmakuSuperChat { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuSuperChat)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuSuperChat)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制 礼物
|
||||
/// 弹幕录制-礼物
|
||||
/// </summary>
|
||||
public bool RecordDanmakuGift { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuGift { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuGift)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuGift)); }
|
||||
|
@ -86,7 +86,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<bool> OptionalRecordDanmakuGift { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuGift)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuGift)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制 上船
|
||||
/// 弹幕录制-上船
|
||||
/// </summary>
|
||||
public bool RecordDanmakuGuard { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuGuard { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuGuard)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuGuard)); }
|
||||
|
@ -94,13 +94,48 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<bool> OptionalRecordDanmakuGuard { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuGuard)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuGuard)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制的直播画质 qn 值,逗号分割,靠前的优先
|
||||
/// 直播画质
|
||||
/// </summary>
|
||||
public string? RecordingQuality { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordingQuality { get => this.GetPropertyHasValue(nameof(this.RecordingQuality)); set => this.SetPropertyHasValue<string>(value, nameof(this.RecordingQuality)); }
|
||||
[JsonProperty(nameof(RecordingQuality)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalRecordingQuality { get => this.GetPropertyValueOptional<string>(nameof(this.RecordingQuality)); set => this.SetPropertyValueOptional(value, nameof(this.RecordingQuality)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件名格式
|
||||
/// </summary>
|
||||
public string? RecordFilenameFormat => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件写入结束 Webhook 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrls => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Webhook v2 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrlsV2 => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 在界面显示标题和分区
|
||||
/// </summary>
|
||||
public bool WpfShowTitleAndArea => this.GetPropertyValue<bool>();
|
||||
|
||||
/// <summary>
|
||||
/// 请求 API 时使用的 Cookie
|
||||
/// </summary>
|
||||
public string? Cookie => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 替换 api.live.bilibili.com 服务器为其他反代,可以支持在云服务器上录制
|
||||
/// </summary>
|
||||
public string? LiveApiHost => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// HTTP API 检查时间间隔 秒
|
||||
/// </summary>
|
||||
public uint TimingCheckInterval => this.GetPropertyValue<uint>();
|
||||
|
||||
/// <summary>
|
||||
/// 录制断开重连时间间隔 毫秒
|
||||
/// </summary>
|
||||
|
@ -117,12 +152,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public uint TimingDanmakuRetry => this.GetPropertyValue<uint>();
|
||||
|
||||
/// <summary>
|
||||
/// HTTP API 检查时间间隔 秒
|
||||
/// </summary>
|
||||
public uint TimingCheckInterval => this.GetPropertyValue<uint>();
|
||||
|
||||
/// <summary>
|
||||
/// 最大未收到新直播数据时间 毫秒
|
||||
/// 最大允许未收到直播数据时间 毫秒
|
||||
/// </summary>
|
||||
public uint TimingWatchdogTimeout => this.GetPropertyValue<uint>();
|
||||
|
||||
|
@ -131,41 +161,139 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
/// </summary>
|
||||
public uint RecordDanmakuFlushInterval => this.GetPropertyValue<uint>();
|
||||
|
||||
/// <summary>
|
||||
/// 请求 API 时使用的 Cookie
|
||||
/// </summary>
|
||||
public string? Cookie => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件写入结束 Webhook 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrls => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Webhook v2 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrlsV2 => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 替换 api.live.bilibili.com 服务器为其他反代,可以支持在云服务器上录制
|
||||
/// </summary>
|
||||
public string? LiveApiHost => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件名模板
|
||||
/// </summary>
|
||||
public string? RecordFilenameFormat => this.GetPropertyValue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示直播间标题和分区
|
||||
/// </summary>
|
||||
public bool WpfShowTitleAndArea => this.GetPropertyValue<bool>();
|
||||
|
||||
}
|
||||
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public sealed partial class GlobalConfig : HierarchicalObject<DefaultConfig, GlobalConfig>
|
||||
{
|
||||
/// <summary>
|
||||
/// 录制模式
|
||||
/// </summary>
|
||||
public RecordMode RecordMode { get => this.GetPropertyValue<RecordMode>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordMode { get => this.GetPropertyHasValue(nameof(this.RecordMode)); set => this.SetPropertyHasValue<RecordMode>(value, nameof(this.RecordMode)); }
|
||||
[JsonProperty(nameof(RecordMode)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<RecordMode> OptionalRecordMode { get => this.GetPropertyValueOptional<RecordMode>(nameof(this.RecordMode)); set => this.SetPropertyValueOptional(value, nameof(this.RecordMode)); }
|
||||
|
||||
/// <summary>
|
||||
/// 自动分段模式
|
||||
/// </summary>
|
||||
public CuttingMode CuttingMode { get => this.GetPropertyValue<CuttingMode>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCuttingMode { get => this.GetPropertyHasValue(nameof(this.CuttingMode)); set => this.SetPropertyHasValue<CuttingMode>(value, nameof(this.CuttingMode)); }
|
||||
[JsonProperty(nameof(CuttingMode)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<CuttingMode> OptionalCuttingMode { get => this.GetPropertyValueOptional<CuttingMode>(nameof(this.CuttingMode)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingMode)); }
|
||||
|
||||
/// <summary>
|
||||
/// 自动分段数值
|
||||
/// </summary>
|
||||
public uint CuttingNumber { get => this.GetPropertyValue<uint>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCuttingNumber { get => this.GetPropertyHasValue(nameof(this.CuttingNumber)); set => this.SetPropertyHasValue<uint>(value, nameof(this.CuttingNumber)); }
|
||||
[JsonProperty(nameof(CuttingNumber)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<uint> OptionalCuttingNumber { get => this.GetPropertyValueOptional<uint>(nameof(this.CuttingNumber)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingNumber)); }
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕录制
|
||||
/// </summary>
|
||||
public bool RecordDanmaku { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmaku { get => this.GetPropertyHasValue(nameof(this.RecordDanmaku)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmaku)); }
|
||||
[JsonProperty(nameof(RecordDanmaku)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmaku { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmaku)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmaku)); }
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕录制-原始数据
|
||||
/// </summary>
|
||||
public bool RecordDanmakuRaw { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuRaw { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuRaw)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuRaw)); }
|
||||
[JsonProperty(nameof(RecordDanmakuRaw)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuRaw { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuRaw)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuRaw)); }
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕录制-SuperChat
|
||||
/// </summary>
|
||||
public bool RecordDanmakuSuperChat { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuSuperChat { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuSuperChat)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuSuperChat)); }
|
||||
[JsonProperty(nameof(RecordDanmakuSuperChat)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuSuperChat { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuSuperChat)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuSuperChat)); }
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕录制-礼物
|
||||
/// </summary>
|
||||
public bool RecordDanmakuGift { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuGift { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuGift)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuGift)); }
|
||||
[JsonProperty(nameof(RecordDanmakuGift)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuGift { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuGift)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuGift)); }
|
||||
|
||||
/// <summary>
|
||||
/// 弹幕录制-上船
|
||||
/// </summary>
|
||||
public bool RecordDanmakuGuard { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuGuard { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuGuard)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuGuard)); }
|
||||
[JsonProperty(nameof(RecordDanmakuGuard)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuGuard { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuGuard)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuGuard)); }
|
||||
|
||||
/// <summary>
|
||||
/// 直播画质
|
||||
/// </summary>
|
||||
public string? RecordingQuality { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordingQuality { get => this.GetPropertyHasValue(nameof(this.RecordingQuality)); set => this.SetPropertyHasValue<string>(value, nameof(this.RecordingQuality)); }
|
||||
[JsonProperty(nameof(RecordingQuality)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalRecordingQuality { get => this.GetPropertyValueOptional<string>(nameof(this.RecordingQuality)); set => this.SetPropertyValueOptional(value, nameof(this.RecordingQuality)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件名格式
|
||||
/// </summary>
|
||||
public string? RecordFilenameFormat { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordFilenameFormat { get => this.GetPropertyHasValue(nameof(this.RecordFilenameFormat)); set => this.SetPropertyHasValue<string>(value, nameof(this.RecordFilenameFormat)); }
|
||||
[JsonProperty(nameof(RecordFilenameFormat)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalRecordFilenameFormat { get => this.GetPropertyValueOptional<string>(nameof(this.RecordFilenameFormat)); set => this.SetPropertyValueOptional(value, nameof(this.RecordFilenameFormat)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件写入结束 Webhook 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrls { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasWebHookUrls { get => this.GetPropertyHasValue(nameof(this.WebHookUrls)); set => this.SetPropertyHasValue<string>(value, nameof(this.WebHookUrls)); }
|
||||
[JsonProperty(nameof(WebHookUrls)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalWebHookUrls { get => this.GetPropertyValueOptional<string>(nameof(this.WebHookUrls)); set => this.SetPropertyValueOptional(value, nameof(this.WebHookUrls)); }
|
||||
|
||||
/// <summary>
|
||||
/// Webhook v2 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrlsV2 { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasWebHookUrlsV2 { get => this.GetPropertyHasValue(nameof(this.WebHookUrlsV2)); set => this.SetPropertyHasValue<string>(value, nameof(this.WebHookUrlsV2)); }
|
||||
[JsonProperty(nameof(WebHookUrlsV2)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalWebHookUrlsV2 { get => this.GetPropertyValueOptional<string>(nameof(this.WebHookUrlsV2)); set => this.SetPropertyValueOptional(value, nameof(this.WebHookUrlsV2)); }
|
||||
|
||||
/// <summary>
|
||||
/// 在界面显示标题和分区
|
||||
/// </summary>
|
||||
public bool WpfShowTitleAndArea { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasWpfShowTitleAndArea { get => this.GetPropertyHasValue(nameof(this.WpfShowTitleAndArea)); set => this.SetPropertyHasValue<bool>(value, nameof(this.WpfShowTitleAndArea)); }
|
||||
[JsonProperty(nameof(WpfShowTitleAndArea)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalWpfShowTitleAndArea { get => this.GetPropertyValueOptional<bool>(nameof(this.WpfShowTitleAndArea)); set => this.SetPropertyValueOptional(value, nameof(this.WpfShowTitleAndArea)); }
|
||||
|
||||
/// <summary>
|
||||
/// 请求 API 时使用的 Cookie
|
||||
/// </summary>
|
||||
public string? Cookie { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCookie { get => this.GetPropertyHasValue(nameof(this.Cookie)); set => this.SetPropertyHasValue<string>(value, nameof(this.Cookie)); }
|
||||
[JsonProperty(nameof(Cookie)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalCookie { get => this.GetPropertyValueOptional<string>(nameof(this.Cookie)); set => this.SetPropertyValueOptional(value, nameof(this.Cookie)); }
|
||||
|
||||
/// <summary>
|
||||
/// 替换 api.live.bilibili.com 服务器为其他反代,可以支持在云服务器上录制
|
||||
/// </summary>
|
||||
public string? LiveApiHost { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasLiveApiHost { get => this.GetPropertyHasValue(nameof(this.LiveApiHost)); set => this.SetPropertyHasValue<string>(value, nameof(this.LiveApiHost)); }
|
||||
[JsonProperty(nameof(LiveApiHost)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalLiveApiHost { get => this.GetPropertyValueOptional<string>(nameof(this.LiveApiHost)); set => this.SetPropertyValueOptional(value, nameof(this.LiveApiHost)); }
|
||||
|
||||
/// <summary>
|
||||
/// HTTP API 检查时间间隔 秒
|
||||
/// </summary>
|
||||
public uint TimingCheckInterval { get => this.GetPropertyValue<uint>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasTimingCheckInterval { get => this.GetPropertyHasValue(nameof(this.TimingCheckInterval)); set => this.SetPropertyHasValue<uint>(value, nameof(this.TimingCheckInterval)); }
|
||||
[JsonProperty(nameof(TimingCheckInterval)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<uint> OptionalTimingCheckInterval { get => this.GetPropertyValueOptional<uint>(nameof(this.TimingCheckInterval)); set => this.SetPropertyValueOptional(value, nameof(this.TimingCheckInterval)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制断开重连时间间隔 毫秒
|
||||
/// </summary>
|
||||
|
@ -191,15 +319,7 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public Optional<uint> OptionalTimingDanmakuRetry { get => this.GetPropertyValueOptional<uint>(nameof(this.TimingDanmakuRetry)); set => this.SetPropertyValueOptional(value, nameof(this.TimingDanmakuRetry)); }
|
||||
|
||||
/// <summary>
|
||||
/// HTTP API 检查时间间隔 秒
|
||||
/// </summary>
|
||||
public uint TimingCheckInterval { get => this.GetPropertyValue<uint>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasTimingCheckInterval { get => this.GetPropertyHasValue(nameof(this.TimingCheckInterval)); set => this.SetPropertyHasValue<uint>(value, nameof(this.TimingCheckInterval)); }
|
||||
[JsonProperty(nameof(TimingCheckInterval)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<uint> OptionalTimingCheckInterval { get => this.GetPropertyValueOptional<uint>(nameof(this.TimingCheckInterval)); set => this.SetPropertyValueOptional(value, nameof(this.TimingCheckInterval)); }
|
||||
|
||||
/// <summary>
|
||||
/// 最大未收到新直播数据时间 毫秒
|
||||
/// 最大允许未收到直播数据时间 毫秒
|
||||
/// </summary>
|
||||
public uint TimingWatchdogTimeout { get => this.GetPropertyValue<uint>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasTimingWatchdogTimeout { get => this.GetPropertyHasValue(nameof(this.TimingWatchdogTimeout)); set => this.SetPropertyHasValue<uint>(value, nameof(this.TimingWatchdogTimeout)); }
|
||||
|
@ -214,126 +334,6 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
[JsonProperty(nameof(RecordDanmakuFlushInterval)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<uint> OptionalRecordDanmakuFlushInterval { get => this.GetPropertyValueOptional<uint>(nameof(this.RecordDanmakuFlushInterval)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuFlushInterval)); }
|
||||
|
||||
/// <summary>
|
||||
/// 请求 API 时使用的 Cookie
|
||||
/// </summary>
|
||||
public string? Cookie { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCookie { get => this.GetPropertyHasValue(nameof(this.Cookie)); set => this.SetPropertyHasValue<string>(value, nameof(this.Cookie)); }
|
||||
[JsonProperty(nameof(Cookie)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalCookie { get => this.GetPropertyValueOptional<string>(nameof(this.Cookie)); set => this.SetPropertyValueOptional(value, nameof(this.Cookie)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件写入结束 Webhook 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrls { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasWebHookUrls { get => this.GetPropertyHasValue(nameof(this.WebHookUrls)); set => this.SetPropertyHasValue<string>(value, nameof(this.WebHookUrls)); }
|
||||
[JsonProperty(nameof(WebHookUrls)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalWebHookUrls { get => this.GetPropertyValueOptional<string>(nameof(this.WebHookUrls)); set => this.SetPropertyValueOptional(value, nameof(this.WebHookUrls)); }
|
||||
|
||||
/// <summary>
|
||||
/// Webhook v2 地址 每行一个
|
||||
/// </summary>
|
||||
public string? WebHookUrlsV2 { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasWebHookUrlsV2 { get => this.GetPropertyHasValue(nameof(this.WebHookUrlsV2)); set => this.SetPropertyHasValue<string>(value, nameof(this.WebHookUrlsV2)); }
|
||||
[JsonProperty(nameof(WebHookUrlsV2)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalWebHookUrlsV2 { get => this.GetPropertyValueOptional<string>(nameof(this.WebHookUrlsV2)); set => this.SetPropertyValueOptional(value, nameof(this.WebHookUrlsV2)); }
|
||||
|
||||
/// <summary>
|
||||
/// 替换 api.live.bilibili.com 服务器为其他反代,可以支持在云服务器上录制
|
||||
/// </summary>
|
||||
public string? LiveApiHost { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasLiveApiHost { get => this.GetPropertyHasValue(nameof(this.LiveApiHost)); set => this.SetPropertyHasValue<string>(value, nameof(this.LiveApiHost)); }
|
||||
[JsonProperty(nameof(LiveApiHost)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalLiveApiHost { get => this.GetPropertyValueOptional<string>(nameof(this.LiveApiHost)); set => this.SetPropertyValueOptional(value, nameof(this.LiveApiHost)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件名模板
|
||||
/// </summary>
|
||||
public string? RecordFilenameFormat { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordFilenameFormat { get => this.GetPropertyHasValue(nameof(this.RecordFilenameFormat)); set => this.SetPropertyHasValue<string>(value, nameof(this.RecordFilenameFormat)); }
|
||||
[JsonProperty(nameof(RecordFilenameFormat)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalRecordFilenameFormat { get => this.GetPropertyValueOptional<string>(nameof(this.RecordFilenameFormat)); set => this.SetPropertyValueOptional(value, nameof(this.RecordFilenameFormat)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示直播间标题和分区
|
||||
/// </summary>
|
||||
public bool WpfShowTitleAndArea { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasWpfShowTitleAndArea { get => this.GetPropertyHasValue(nameof(this.WpfShowTitleAndArea)); set => this.SetPropertyHasValue<bool>(value, nameof(this.WpfShowTitleAndArea)); }
|
||||
[JsonProperty(nameof(WpfShowTitleAndArea)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalWpfShowTitleAndArea { get => this.GetPropertyValueOptional<bool>(nameof(this.WpfShowTitleAndArea)); set => this.SetPropertyValueOptional(value, nameof(this.WpfShowTitleAndArea)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制模式
|
||||
/// </summary>
|
||||
public RecordMode RecordMode { get => this.GetPropertyValue<RecordMode>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordMode { get => this.GetPropertyHasValue(nameof(this.RecordMode)); set => this.SetPropertyHasValue<RecordMode>(value, nameof(this.RecordMode)); }
|
||||
[JsonProperty(nameof(RecordMode)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<RecordMode> OptionalRecordMode { get => this.GetPropertyValueOptional<RecordMode>(nameof(this.RecordMode)); set => this.SetPropertyValueOptional(value, nameof(this.RecordMode)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件自动切割模式
|
||||
/// </summary>
|
||||
public CuttingMode CuttingMode { get => this.GetPropertyValue<CuttingMode>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCuttingMode { get => this.GetPropertyHasValue(nameof(this.CuttingMode)); set => this.SetPropertyHasValue<CuttingMode>(value, nameof(this.CuttingMode)); }
|
||||
[JsonProperty(nameof(CuttingMode)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<CuttingMode> OptionalCuttingMode { get => this.GetPropertyValueOptional<CuttingMode>(nameof(this.CuttingMode)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingMode)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件自动切割数值(分钟/MiB)
|
||||
/// </summary>
|
||||
public uint CuttingNumber { get => this.GetPropertyValue<uint>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasCuttingNumber { get => this.GetPropertyHasValue(nameof(this.CuttingNumber)); set => this.SetPropertyHasValue<uint>(value, nameof(this.CuttingNumber)); }
|
||||
[JsonProperty(nameof(CuttingNumber)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<uint> OptionalCuttingNumber { get => this.GetPropertyValueOptional<uint>(nameof(this.CuttingNumber)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingNumber)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制弹幕
|
||||
/// </summary>
|
||||
public bool RecordDanmaku { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmaku { get => this.GetPropertyHasValue(nameof(this.RecordDanmaku)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmaku)); }
|
||||
[JsonProperty(nameof(RecordDanmaku)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmaku { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmaku)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmaku)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否记录弹幕原始数据
|
||||
/// </summary>
|
||||
public bool RecordDanmakuRaw { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuRaw { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuRaw)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuRaw)); }
|
||||
[JsonProperty(nameof(RecordDanmakuRaw)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuRaw { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuRaw)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuRaw)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制 SuperChat
|
||||
/// </summary>
|
||||
public bool RecordDanmakuSuperChat { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuSuperChat { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuSuperChat)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuSuperChat)); }
|
||||
[JsonProperty(nameof(RecordDanmakuSuperChat)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuSuperChat { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuSuperChat)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuSuperChat)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制 礼物
|
||||
/// </summary>
|
||||
public bool RecordDanmakuGift { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuGift { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuGift)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuGift)); }
|
||||
[JsonProperty(nameof(RecordDanmakuGift)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuGift { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuGift)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuGift)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否同时录制 上船
|
||||
/// </summary>
|
||||
public bool RecordDanmakuGuard { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordDanmakuGuard { get => this.GetPropertyHasValue(nameof(this.RecordDanmakuGuard)); set => this.SetPropertyHasValue<bool>(value, nameof(this.RecordDanmakuGuard)); }
|
||||
[JsonProperty(nameof(RecordDanmakuGuard)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalRecordDanmakuGuard { get => this.GetPropertyValueOptional<bool>(nameof(this.RecordDanmakuGuard)); set => this.SetPropertyValueOptional(value, nameof(this.RecordDanmakuGuard)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制的直播画质 qn 值,逗号分割,靠前的优先
|
||||
/// </summary>
|
||||
public string? RecordingQuality { get => this.GetPropertyValue<string>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasRecordingQuality { get => this.GetPropertyHasValue(nameof(this.RecordingQuality)); set => this.SetPropertyHasValue<string>(value, nameof(this.RecordingQuality)); }
|
||||
[JsonProperty(nameof(RecordingQuality)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<string?> OptionalRecordingQuality { get => this.GetPropertyValueOptional<string>(nameof(this.RecordingQuality)); set => this.SetPropertyValueOptional(value, nameof(this.RecordingQuality)); }
|
||||
|
||||
}
|
||||
|
||||
public sealed partial class DefaultConfig
|
||||
|
@ -341,30 +341,6 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
public static readonly DefaultConfig Instance = new DefaultConfig();
|
||||
private DefaultConfig() { }
|
||||
|
||||
public uint TimingStreamRetry => 6 * 1000;
|
||||
|
||||
public uint TimingStreamConnect => 5 * 1000;
|
||||
|
||||
public uint TimingDanmakuRetry => 15 * 1000;
|
||||
|
||||
public uint TimingCheckInterval => 10 * 60;
|
||||
|
||||
public uint TimingWatchdogTimeout => 10 * 1000;
|
||||
|
||||
public uint RecordDanmakuFlushInterval => 20;
|
||||
|
||||
public string Cookie => string.Empty;
|
||||
|
||||
public string WebHookUrls => string.Empty;
|
||||
|
||||
public string WebHookUrlsV2 => string.Empty;
|
||||
|
||||
public string LiveApiHost => "https://api.live.bilibili.com";
|
||||
|
||||
public string RecordFilenameFormat => @"{roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv";
|
||||
|
||||
public bool WpfShowTitleAndArea => true;
|
||||
|
||||
public RecordMode RecordMode => RecordMode.Standard;
|
||||
|
||||
public CuttingMode CuttingMode => CuttingMode.Disabled;
|
||||
|
@ -383,6 +359,30 @@ namespace BililiveRecorder.Core.Config.V2
|
|||
|
||||
public string RecordingQuality => "10000";
|
||||
|
||||
public string RecordFilenameFormat => @"{roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv";
|
||||
|
||||
public string WebHookUrls => string.Empty;
|
||||
|
||||
public string WebHookUrlsV2 => string.Empty;
|
||||
|
||||
public bool WpfShowTitleAndArea => true;
|
||||
|
||||
public string Cookie => string.Empty;
|
||||
|
||||
public string LiveApiHost => "https://api.live.bilibili.com";
|
||||
|
||||
public uint TimingCheckInterval => 10 * 60;
|
||||
|
||||
public uint TimingStreamRetry => 6 * 1000;
|
||||
|
||||
public uint TimingStreamConnect => 5 * 1000;
|
||||
|
||||
public uint TimingDanmakuRetry => 9 * 1000;
|
||||
|
||||
public uint TimingWatchdogTimeout => 10 * 1000;
|
||||
|
||||
public uint RecordDanmakuFlushInterval => 20;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,11 +3,127 @@
|
|||
"$schema": "http://json-schema.org/schema",
|
||||
"definitions": {
|
||||
"global-config": {
|
||||
"description": "全局配置",
|
||||
"description": "全局设置",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"RecordFilenameFormat": {
|
||||
"description": "录制文件名格式\n默认: {roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv",
|
||||
"markdownDescription": "录制文件名格式 \n默认: `{roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": "{roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv"
|
||||
}
|
||||
}
|
||||
},
|
||||
"WebHookUrls": {
|
||||
"description": "WebhookV1\n默认: ",
|
||||
"markdownDescription": "WebhookV1 \n默认: ` `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"WebHookUrlsV2": {
|
||||
"description": "WebhookV2\n默认: ",
|
||||
"markdownDescription": "WebhookV2 \n默认: ` `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"WpfShowTitleAndArea": {
|
||||
"description": "在界面显示标题和分区\n默认: true",
|
||||
"markdownDescription": "在界面显示标题和分区 \n默认: `true `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Cookie": {
|
||||
"description": "请求 API 时使用的 Cookie\n默认: (空字符串)",
|
||||
"markdownDescription": "请求 API 时使用的 Cookie \n默认: `(空字符串) `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"pattern": "^(S+=S+;? ?)*$",
|
||||
"maxLength": 4096
|
||||
}
|
||||
}
|
||||
},
|
||||
"LiveApiHost": {
|
||||
"description": "请求的 API Host\n默认: https://api.live.bilibili.com",
|
||||
"markdownDescription": "请求的 API Host \n默认: `https://api.live.bilibili.com `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": "https://api.live.bilibili.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TimingCheckInterval": {
|
||||
"description": "HTTP API 检查时间间隔 秒\n默认: 600 (10分)",
|
||||
"markdownDescription": "HTTP API 检查时间间隔 秒 \n默认: `600 (10分) `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295,
|
||||
"default": 600
|
||||
}
|
||||
}
|
||||
},
|
||||
"TimingStreamRetry": {
|
||||
"description": "录制断开重连时间间隔 毫秒",
|
||||
"description": "录制断开重连时间间隔 毫秒\n默认: 6000 (6秒)",
|
||||
"markdownDescription": "录制断开重连时间间隔 毫秒 \n默认: `6000 (6秒) `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -24,7 +140,8 @@
|
|||
}
|
||||
},
|
||||
"TimingStreamConnect": {
|
||||
"description": "连接直播服务器超时时间 毫秒",
|
||||
"description": "连接直播服务器超时时间 毫秒\n默认: 5000 (5秒)",
|
||||
"markdownDescription": "连接直播服务器超时时间 毫秒 \n默认: `5000 (5秒) `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -41,7 +158,8 @@
|
|||
}
|
||||
},
|
||||
"TimingDanmakuRetry": {
|
||||
"description": "弹幕服务器重连时间间隔 毫秒",
|
||||
"description": "弹幕服务器重连时间间隔 毫秒\n默认: 9000 (9秒)",
|
||||
"markdownDescription": "弹幕服务器重连时间间隔 毫秒 \n默认: `9000 (9秒) `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -53,29 +171,13 @@
|
|||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295,
|
||||
"default": 15000
|
||||
}
|
||||
}
|
||||
},
|
||||
"TimingCheckInterval": {
|
||||
"description": "HTTP API 检查时间间隔 秒",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295,
|
||||
"default": 600
|
||||
"default": 9000
|
||||
}
|
||||
}
|
||||
},
|
||||
"TimingWatchdogTimeout": {
|
||||
"description": "最大未收到新直播数据时间 毫秒",
|
||||
"description": "最大允许未收到直播数据时间 毫秒\n默认: 10000 (10秒)",
|
||||
"markdownDescription": "最大允许未收到直播数据时间 毫秒 \n默认: `10000 (10秒) `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -92,7 +194,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuFlushInterval": {
|
||||
"description": "触发 <see cref=\"System.Xml.XmlWriter.Flush\"/> 的弹幕个数",
|
||||
"description": "触发刷新弹幕写入缓冲的个数\n默认: 20",
|
||||
"markdownDescription": "触发刷新弹幕写入缓冲的个数 \n默认: `20 `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -108,99 +211,9 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"Cookie": {
|
||||
"description": "请求 API 时使用的 Cookie",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"pattern": "^(S+=S+;? ?)*$",
|
||||
"maxLength": 4096
|
||||
}
|
||||
}
|
||||
},
|
||||
"WebHookUrls": {
|
||||
"description": "录制文件写入结束 Webhook 地址 每行一个",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"WebHookUrlsV2": {
|
||||
"description": "Webhook v2 地址 每行一个",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"LiveApiHost": {
|
||||
"description": "替换 api.live.bilibili.com 服务器为其他反代,可以支持在云服务器上录制",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": "https://api.live.bilibili.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RecordFilenameFormat": {
|
||||
"description": "录制文件名模板",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "string",
|
||||
"default": "{roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv"
|
||||
}
|
||||
}
|
||||
},
|
||||
"WpfShowTitleAndArea": {
|
||||
"description": "是否显示直播间标题和分区",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"HasValue": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"Value": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"RecordMode": {
|
||||
"description": "录制模式",
|
||||
"description": "录制模式\n默认: RecordMode.Standard",
|
||||
"markdownDescription": "录制模式 \n默认: `RecordMode.Standard `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -220,7 +233,8 @@
|
|||
}
|
||||
},
|
||||
"CuttingMode": {
|
||||
"description": "录制文件自动切割模式",
|
||||
"description": "自动分段模式\n默认: CuttingMode.Disabled",
|
||||
"markdownDescription": "自动分段模式 \n默认: `CuttingMode.Disabled `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -241,7 +255,8 @@
|
|||
}
|
||||
},
|
||||
"CuttingNumber": {
|
||||
"description": "录制文件自动切割数值(分钟/MiB)",
|
||||
"description": "自动分段数值\n默认: 100",
|
||||
"markdownDescription": "自动分段数值 \n默认: `100 `\n\n按时长分段时为分钟,按大小分段时为MiB",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -258,7 +273,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmaku": {
|
||||
"description": "是否同时录制弹幕",
|
||||
"description": "弹幕录制\n默认: false",
|
||||
"markdownDescription": "弹幕录制 \n默认: `false `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -273,7 +289,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuRaw": {
|
||||
"description": "是否记录弹幕原始数据",
|
||||
"description": "弹幕录制-原始数据\n默认: false",
|
||||
"markdownDescription": "弹幕录制-原始数据 \n默认: `false `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -288,7 +305,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuSuperChat": {
|
||||
"description": "是否同时录制 SuperChat",
|
||||
"description": "弹幕录制-SuperChat\n默认: true",
|
||||
"markdownDescription": "弹幕录制-SuperChat \n默认: `true `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -303,7 +321,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuGift": {
|
||||
"description": "是否同时录制 礼物",
|
||||
"description": "弹幕录制-礼物\n默认: false",
|
||||
"markdownDescription": "弹幕录制-礼物 \n默认: `false `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -318,7 +337,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuGuard": {
|
||||
"description": "是否同时录制 上船",
|
||||
"description": "弹幕录制-上船\n默认: true",
|
||||
"markdownDescription": "弹幕录制-上船 \n默认: `true `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -333,7 +353,8 @@
|
|||
}
|
||||
},
|
||||
"RecordingQuality": {
|
||||
"description": "录制的直播画质 qn 值,逗号分割,靠前的优先",
|
||||
"description": "直播画质\n默认: 10000",
|
||||
"markdownDescription": "直播画质 \n默认: `10000 `\n\n录制的直播画质 qn 值,逗号分割,靠前的优先",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -350,11 +371,12 @@
|
|||
}
|
||||
},
|
||||
"room-config": {
|
||||
"description": "单个房间配置",
|
||||
"description": "房间独立设置",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"RoomId": {
|
||||
"description": "房间号",
|
||||
"description": "房间号\n默认: default",
|
||||
"markdownDescription": "房间号 \n默认: `default `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -370,7 +392,8 @@
|
|||
}
|
||||
},
|
||||
"AutoRecord": {
|
||||
"description": "是否启用自动录制",
|
||||
"description": "自动录制\n默认: default",
|
||||
"markdownDescription": "自动录制 \n默认: `default `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -384,7 +407,8 @@
|
|||
}
|
||||
},
|
||||
"RecordMode": {
|
||||
"description": "录制模式",
|
||||
"description": "录制模式\n默认: RecordMode.Standard",
|
||||
"markdownDescription": "录制模式 \n默认: `RecordMode.Standard `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -404,7 +428,8 @@
|
|||
}
|
||||
},
|
||||
"CuttingMode": {
|
||||
"description": "录制文件自动切割模式",
|
||||
"description": "自动分段模式\n默认: CuttingMode.Disabled",
|
||||
"markdownDescription": "自动分段模式 \n默认: `CuttingMode.Disabled `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -425,7 +450,8 @@
|
|||
}
|
||||
},
|
||||
"CuttingNumber": {
|
||||
"description": "录制文件自动切割数值(分钟/MiB)",
|
||||
"description": "自动分段数值\n默认: 100",
|
||||
"markdownDescription": "自动分段数值 \n默认: `100 `\n\n按时长分段时为分钟,按大小分段时为MiB",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -442,7 +468,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmaku": {
|
||||
"description": "是否同时录制弹幕",
|
||||
"description": "弹幕录制\n默认: false",
|
||||
"markdownDescription": "弹幕录制 \n默认: `false `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -457,7 +484,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuRaw": {
|
||||
"description": "是否记录弹幕原始数据",
|
||||
"description": "弹幕录制-原始数据\n默认: false",
|
||||
"markdownDescription": "弹幕录制-原始数据 \n默认: `false `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -472,7 +500,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuSuperChat": {
|
||||
"description": "是否同时录制 SuperChat",
|
||||
"description": "弹幕录制-SuperChat\n默认: true",
|
||||
"markdownDescription": "弹幕录制-SuperChat \n默认: `true `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -487,7 +516,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuGift": {
|
||||
"description": "是否同时录制 礼物",
|
||||
"description": "弹幕录制-礼物\n默认: false",
|
||||
"markdownDescription": "弹幕录制-礼物 \n默认: `false `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -502,7 +532,8 @@
|
|||
}
|
||||
},
|
||||
"RecordDanmakuGuard": {
|
||||
"description": "是否同时录制 上船",
|
||||
"description": "弹幕录制-上船\n默认: true",
|
||||
"markdownDescription": "弹幕录制-上船 \n默认: `true `\n\n",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
@ -517,7 +548,8 @@
|
|||
}
|
||||
},
|
||||
"RecordingQuality": {
|
||||
"description": "录制的直播画质 qn 值,逗号分割,靠前的优先",
|
||||
"description": "直播画质\n默认: 10000",
|
||||
"markdownDescription": "直播画质 \n默认: `10000 `\n\n录制的直播画质 qn 值,逗号分割,靠前的优先",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
|
|
208
config_gen/data.ts
Normal file
208
config_gen/data.ts
Normal file
|
@ -0,0 +1,208 @@
|
|||
import { ConfigEntry, ConfigEntryType } from './types'
|
||||
|
||||
export const data: Array<ConfigEntry> = [
|
||||
{
|
||||
name: "RoomId",
|
||||
description: "房间号",
|
||||
type: "int",
|
||||
configType: "roomOnly",
|
||||
defaultValue: "default",
|
||||
// web_readonly: true,
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "AutoRecord",
|
||||
description: "自动录制",
|
||||
type: "bool",
|
||||
configType: "roomOnly",
|
||||
defaultValue: "default",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordMode",
|
||||
description: "录制模式",
|
||||
type: "RecordMode",
|
||||
configType: "room",
|
||||
defaultValue: "RecordMode.Standard",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "CuttingMode",
|
||||
description: "自动分段模式",
|
||||
type: "CuttingMode",
|
||||
configType: "room",
|
||||
defaultValue: "CuttingMode.Disabled",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "CuttingNumber",
|
||||
description: "自动分段数值",
|
||||
type: "uint",
|
||||
configType: "room",
|
||||
defaultValue: "100",
|
||||
markdown: "按时长分段时为分钟,按大小分段时为MiB"
|
||||
},
|
||||
{
|
||||
name: "RecordDanmaku",
|
||||
description: "弹幕录制",
|
||||
type: "bool",
|
||||
configType: "room",
|
||||
defaultValue: "false",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordDanmakuRaw",
|
||||
description: "弹幕录制-原始数据",
|
||||
type: "bool",
|
||||
configType: "room",
|
||||
defaultValue: "false",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordDanmakuSuperChat",
|
||||
description: "弹幕录制-SuperChat",
|
||||
type: "bool",
|
||||
configType: "room",
|
||||
defaultValue: "true",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordDanmakuGift",
|
||||
description: "弹幕录制-礼物",
|
||||
type: "bool",
|
||||
configType: "room",
|
||||
defaultValue: "false",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordDanmakuGuard",
|
||||
description: "弹幕录制-上船",
|
||||
type: "bool",
|
||||
configType: "room",
|
||||
defaultValue: "true",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordingQuality",
|
||||
type: "string?",
|
||||
configType: "room",
|
||||
description: "直播画质",
|
||||
defaultValue: "\"10000\"",
|
||||
defaultValueDescription: "10000",
|
||||
markdown: "录制的直播画质 qn 值,逗号分割,靠前的优先"
|
||||
},
|
||||
{
|
||||
name: "RecordFilenameFormat",
|
||||
description: "录制文件名格式",
|
||||
type: "string?",
|
||||
configType: "globalOnly",
|
||||
defaultValue: "@\"{roomid}-{name}/录制-{roomid}-{date}-{time}-{ms}-{title}.flv\"",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "WebHookUrls",
|
||||
description: "WebhookV1",
|
||||
type: "string?",
|
||||
configType: "globalOnly",
|
||||
defaultValue: "string.Empty",
|
||||
xmlComment: "录制文件写入结束 Webhook 地址 每行一个",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "WebHookUrlsV2",
|
||||
description: "WebhookV2",
|
||||
type: "string?",
|
||||
configType: "globalOnly",
|
||||
defaultValue: "string.Empty",
|
||||
xmlComment: "Webhook v2 地址 每行一个",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "WpfShowTitleAndArea",
|
||||
description: "在界面显示标题和分区",
|
||||
type: "bool",
|
||||
configType: "globalOnly",
|
||||
defaultValue: "true",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "Cookie",
|
||||
description: "请求 API 时使用的 Cookie",
|
||||
type: "string?",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "string.Empty",
|
||||
defaultValueDescription: "(空字符串)",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "LiveApiHost",
|
||||
description: "请求的 API Host",
|
||||
type: "string?",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "\"https://api.live.bilibili.com\"",
|
||||
xmlComment: "替换 api.live.bilibili.com 服务器为其他反代,可以支持在云服务器上录制",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "TimingCheckInterval",
|
||||
description: "HTTP API 检查时间间隔 秒",
|
||||
type: "uint",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "10 * 60",
|
||||
defaultValueDescription: "600 (10分)",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "TimingStreamRetry",
|
||||
description: "录制断开重连时间间隔 毫秒",
|
||||
type: "uint",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "6 * 1000",
|
||||
defaultValueDescription: "6000 (6秒)",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "TimingStreamConnect",
|
||||
description: "连接直播服务器超时时间 毫秒",
|
||||
type: "uint",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "5 * 1000",
|
||||
defaultValueDescription: "5000 (5秒)",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "TimingDanmakuRetry",
|
||||
description: "弹幕服务器重连时间间隔 毫秒",
|
||||
type: "uint",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "9 * 1000",
|
||||
defaultValueDescription: "9000 (9秒)",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "TimingWatchdogTimeout",
|
||||
description: "最大允许未收到直播数据时间 毫秒",
|
||||
type: "uint",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "10 * 1000",
|
||||
defaultValueDescription: "10000 (10秒)",
|
||||
markdown: ""
|
||||
},
|
||||
{
|
||||
name: "RecordDanmakuFlushInterval",
|
||||
description: "触发刷新弹幕写入缓冲的个数",
|
||||
type: "uint",
|
||||
configType: "globalOnly",
|
||||
advancedConfig: true,
|
||||
defaultValue: "20",
|
||||
xmlComment: "触发 <see cref=\"System.Xml.XmlWriter.Flush\"/> 的弹幕个数",
|
||||
markdown: ""
|
||||
},
|
||||
];
|
10
config_gen/generators/README.md
Normal file
10
config_gen/generators/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# 设置代码以及文档生成
|
||||
|
||||
用法
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npx ts-node index.ts
|
||||
npx ts-node index.ts code
|
||||
npx ts-node index.ts doc
|
||||
```
|
102
config_gen/generators/code.ts
Normal file
102
config_gen/generators/code.ts
Normal file
|
@ -0,0 +1,102 @@
|
|||
import { ConfigEntry, ConfigEntryType } from "../types"
|
||||
import builderCore from "./codeCore"
|
||||
import builderCli from "./codeCli"
|
||||
import builderSchema from "./codeSchema"
|
||||
import builderWeb from "./codeWeb"
|
||||
import { data } from "../data"
|
||||
import { resolve } from "path"
|
||||
import { writeFileSync } from "fs"
|
||||
import { spawn } from "child_process"
|
||||
import { stderr, stdout } from "process"
|
||||
|
||||
interface SectionInfoMap {
|
||||
[key: string]: SectionInfo
|
||||
}
|
||||
|
||||
interface SectionInfo {
|
||||
readonly path: string
|
||||
readonly format: boolean,
|
||||
readonly header: boolean,
|
||||
readonly build: ((data: ConfigEntry[]) => string)
|
||||
}
|
||||
|
||||
const map: SectionInfoMap = {
|
||||
core: {
|
||||
path: './BililiveRecorder.Core/Config/V2/Config.gen.cs',
|
||||
format: true,
|
||||
header: true,
|
||||
build: builderCore
|
||||
},
|
||||
cli: {
|
||||
path: './BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs',
|
||||
format: true,
|
||||
header: true,
|
||||
build: builderCli
|
||||
},
|
||||
web_is_disabled_for_now: {
|
||||
path: './BililiveRecorder.Web.Schemas/Types/Config.gen.cs',
|
||||
format: true,
|
||||
header: true,
|
||||
build: builderWeb
|
||||
},
|
||||
schema: {
|
||||
path: './configV2.schema.json',
|
||||
format: false,
|
||||
header: false,
|
||||
build: builderSchema
|
||||
}
|
||||
}
|
||||
|
||||
const HEADER = `// ******************************
|
||||
// GENERATED CODE, DO NOT EDIT MANUALLY.
|
||||
// SEE /config_gen/README.md
|
||||
// ******************************\n\n`
|
||||
|
||||
export default function code(sections: string[]): void {
|
||||
let formatList: string[] = [];
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const info = map[sections[i]]
|
||||
if (!info) continue;
|
||||
|
||||
let text = info.build(data)
|
||||
|
||||
if (info.header)
|
||||
text = HEADER + text
|
||||
|
||||
const fullPath = resolve(__dirname, "../..", info.path)
|
||||
|
||||
writeFileSync(fullPath, text, { encoding: 'utf8' })
|
||||
|
||||
if (info.format)
|
||||
formatList.push(info.path)
|
||||
}
|
||||
|
||||
if (formatList.length > 0) {
|
||||
console.log("[node] formatting...")
|
||||
|
||||
let format = spawn('dotnet',
|
||||
[
|
||||
'tool',
|
||||
'run',
|
||||
'dotnet-format',
|
||||
'--',
|
||||
'--include',
|
||||
...formatList
|
||||
],
|
||||
{
|
||||
cwd: resolve(__dirname, "../..")
|
||||
})
|
||||
|
||||
format.stdout.on('data', function (data) {
|
||||
stdout.write('[dotnet-format] ' + data.toString());
|
||||
});
|
||||
|
||||
format.stderr.on('data', function (data) {
|
||||
stderr.write('[dotnet-format] ' + data.toString());
|
||||
});
|
||||
|
||||
format.on('exit', function (code) {
|
||||
console.log('[node] format done, exit code: ' + code);
|
||||
});
|
||||
}
|
||||
}
|
50
config_gen/generators/codeCli.ts
Normal file
50
config_gen/generators/codeCli.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { ConfigEntry, ConfigEntryType } from "../types"
|
||||
import { trimEnd } from "../utils";
|
||||
|
||||
export default function (data: ConfigEntry[]): string {
|
||||
let result = `using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using BililiveRecorder.Core.Config.V2;
|
||||
|
||||
namespace BililiveRecorder.Cli.Configure
|
||||
{`;
|
||||
|
||||
result += `
|
||||
public enum GlobalConfigProperties
|
||||
{
|
||||
[Description("[grey]Exit[/]")]
|
||||
Exit,
|
||||
${data.filter(x => x.configType != 'roomOnly').map(x => x.name).join(",\n")}
|
||||
}`;
|
||||
|
||||
result += `
|
||||
public enum RoomConfigProperties
|
||||
{
|
||||
[Description("[grey]Exit[/]")]
|
||||
Exit,
|
||||
${data.filter(x => x.configType != 'globalOnly').map(x => x.name).join(",\n")}
|
||||
}`;
|
||||
|
||||
|
||||
result += `
|
||||
public static class ConfigInstructions
|
||||
{
|
||||
public static Dictionary<GlobalConfigProperties, ConfigInstructionBase<GlobalConfig>> GlobalConfig = new();
|
||||
public static Dictionary<RoomConfigProperties, ConfigInstructionBase<RoomConfig>> RoomConfig = new();
|
||||
|
||||
static ConfigInstructions()
|
||||
{
|
||||
${data
|
||||
.filter(x => x.configType != 'roomOnly')
|
||||
.map(r => `GlobalConfig.Add(GlobalConfigProperties.${r.name}, new ConfigInstruction<GlobalConfig, ${trimEnd(r.type, '?')}>(config => config.Has${r.name} = false, (config, value) => config.${r.name} = value) { Name = "${r.name}", CanBeOptional = true });`)
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
${data.filter(x => x.configType != 'globalOnly').map(r => `RoomConfig.Add(RoomConfigProperties.${r.name}, new ConfigInstruction<RoomConfig, ${trimEnd(r.type, '?')}>(config => config.Has${r.name} = false, (config, value) => config.${r.name} = value) { Name = "${r.name}", CanBeOptional = ${r.configType != 'roomOnly'} });`).join("\n")}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
result += `\n}\n`;
|
||||
return result;
|
||||
}
|
65
config_gen/generators/codeCore.ts
Normal file
65
config_gen/generators/codeCore.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { ConfigEntry, ConfigEntryType } from "../types"
|
||||
import { trimEnd } from "../utils";
|
||||
|
||||
export default function (data: ConfigEntry[]): string {
|
||||
let result = `using System.ComponentModel;
|
||||
using HierarchicalPropertyDefault;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
#nullable enable
|
||||
namespace BililiveRecorder.Core.Config.V2
|
||||
{
|
||||
`;
|
||||
|
||||
function write_property(r: ConfigEntry) {
|
||||
result += `/// <summary>\n/// ${r.xmlComment ?? r.description}\n/// </summary>\n`;
|
||||
result += `public ${r.type} ${r.name} { get => this.GetPropertyValue<${trimEnd(r.type, '?')}>(); set => this.SetPropertyValue(value); }\n`;
|
||||
result += `public bool Has${r.name} { get => this.GetPropertyHasValue(nameof(this.${r.name})); set => this.SetPropertyHasValue<${trimEnd(r.type, '?')}>(value, nameof(this.${r.name})); }\n`;
|
||||
result += `[JsonProperty(nameof(${r.name})), EditorBrowsable(EditorBrowsableState.Never)]\n`;
|
||||
result += `public Optional<${r.type}> Optional${r.name} { get => this.GetPropertyValueOptional<${trimEnd(r.type, '?')}>(nameof(this.${r.name})); set => this.SetPropertyValueOptional(value, nameof(this.${r.name})); }\n\n`;
|
||||
}
|
||||
|
||||
function write_readonly_property(r: ConfigEntry) {
|
||||
result += `/// <summary>\n/// ${r.xmlComment ?? r.description}\n/// </summary>\n`;
|
||||
result += `public ${r.type} ${r.name} => this.GetPropertyValue<${trimEnd(r.type, '?')}>();\n\n`;
|
||||
}
|
||||
|
||||
{
|
||||
result += "[JsonObject(MemberSerialization.OptIn)]\n";
|
||||
result += "public sealed partial class RoomConfig : HierarchicalObject<GlobalConfig, RoomConfig>\n";
|
||||
result += "{\n";
|
||||
|
||||
data.filter(x => x.configType != 'globalOnly').forEach(r => write_property(r));
|
||||
data.filter(x => x.configType == 'globalOnly').forEach(r => write_readonly_property(r));
|
||||
|
||||
result += "}\n\n";
|
||||
}
|
||||
|
||||
{
|
||||
result += "[JsonObject(MemberSerialization.OptIn)]\n";
|
||||
result += "public sealed partial class GlobalConfig : HierarchicalObject<DefaultConfig, GlobalConfig>\n";
|
||||
result += "{\n";
|
||||
|
||||
data.filter(x => x.configType != 'roomOnly').forEach(r => write_property(r));
|
||||
|
||||
result += "}\n\n";
|
||||
}
|
||||
|
||||
{
|
||||
result += `public sealed partial class DefaultConfig
|
||||
{
|
||||
public static readonly DefaultConfig Instance = new DefaultConfig();
|
||||
private DefaultConfig() {}\n\n`;
|
||||
|
||||
data
|
||||
.filter(x => x.configType != 'roomOnly')
|
||||
.forEach(r => {
|
||||
result += `public ${trimEnd(r.type, '?')} ${r.name} => ${r.defaultValue};\n\n`;
|
||||
});
|
||||
|
||||
result += "}\n\n";
|
||||
}
|
||||
|
||||
result += `}\n`;
|
||||
return result;
|
||||
}
|
110
config_gen/generators/codeSchema.ts
Normal file
110
config_gen/generators/codeSchema.ts
Normal file
|
@ -0,0 +1,110 @@
|
|||
import { ConfigEntry, ConfigEntryType } from "../types"
|
||||
|
||||
function tryEvalValue(str: string) {
|
||||
try {
|
||||
return eval(str);
|
||||
} catch {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
const mapCSharpString = (text: string): string => text === 'string.Empty' ? '' : tryEvalValue(text.replace(/^@/, ''));
|
||||
|
||||
function mapTypeToJsonSchema(name: string, type: string, defaultValue: string) {
|
||||
switch (type) {
|
||||
case "RecordMode":
|
||||
return { type: "integer", default: 0, enum: [0, 1], "description": "0: Standard\n1: Raw" };
|
||||
case "CuttingMode":
|
||||
return { type: "integer", default: 0, enum: [0, 1, 2], "description": "0: 禁用\n1: 根据时间切割\n2: 根据文件大小切割" };
|
||||
case "uint":
|
||||
return { type: "integer", minimum: 0, maximum: 4294967295, default: tryEvalValue(defaultValue) };
|
||||
case "int":
|
||||
return { type: "integer", minimum: -2147483648, maximum: 2147483647, default: tryEvalValue(defaultValue) };
|
||||
case "bool":
|
||||
return { type: "boolean", default: tryEvalValue(defaultValue) };
|
||||
case "string":
|
||||
case "string?":
|
||||
if (name === 'Cookie') {
|
||||
return { type: "string", pattern: "^(\S+=\S+;? ?)*$", maxLength: 4096, };
|
||||
}
|
||||
return { type: "string", default: mapCSharpString(defaultValue) };
|
||||
default:
|
||||
return { type, default: defaultValue };
|
||||
}
|
||||
}
|
||||
|
||||
function buildProperty(target: { [i: string]: any }, config: ConfigEntry) {
|
||||
const typeObj = mapTypeToJsonSchema(config.name, config.type, config.defaultValue);
|
||||
|
||||
if (config.defaultValue === 'default')
|
||||
delete typeObj['default'];
|
||||
|
||||
target[config.name] = {
|
||||
description: config.description
|
||||
+ '\n默认: ' + (!config.defaultValueDescription ? mapCSharpString(config.defaultValue) : config.defaultValueDescription),
|
||||
markdownDescription: config.description
|
||||
+ ' \n默认: `' + (!config.defaultValueDescription ? mapCSharpString(config.defaultValue) : config.defaultValueDescription)
|
||||
+ ' `\n\n' + config.markdown,
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
HasValue: {
|
||||
type: "boolean",
|
||||
default: true
|
||||
},
|
||||
Value: typeObj
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default function (data: ConfigEntry[]): string {
|
||||
const sharedConfig = {};
|
||||
const globalConfig = {};
|
||||
const roomConfig = {};
|
||||
|
||||
data.filter(x => x.configType == 'room').forEach(v => buildProperty(sharedConfig, v));
|
||||
data.filter(x => x.configType == 'roomOnly').forEach(v => buildProperty(roomConfig, v));
|
||||
data.filter(x => x.configType == 'globalOnly').forEach(v => buildProperty(globalConfig, v));
|
||||
|
||||
const schema = {
|
||||
"$comment": "GENERATED CODE, DO NOT EDIT MANUALLY.",
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"definitions": {
|
||||
"global-config": {
|
||||
"description": "全局设置",
|
||||
"additionalProperties": false,
|
||||
"properties": { ...globalConfig, ...sharedConfig }
|
||||
},
|
||||
"room-config": {
|
||||
"description": "房间独立设置",
|
||||
"additionalProperties": false,
|
||||
"properties": { ...roomConfig, ...sharedConfig }
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"$schema",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"$schema": {
|
||||
"type": "string",
|
||||
"default": "https://raw.githubusercontent.com/Bililive/BililiveRecorder/dev-1.3/configV2.schema.json"
|
||||
},
|
||||
"version": {
|
||||
"const": 2
|
||||
},
|
||||
"global": {
|
||||
"$ref": "#/definitions/global-config"
|
||||
},
|
||||
"rooms": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/room-config"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(schema, null, 2)
|
||||
}
|
5
config_gen/generators/codeWeb.ts
Normal file
5
config_gen/generators/codeWeb.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { ConfigEntry, ConfigEntryType } from "../types"
|
||||
|
||||
export default function (data: ConfigEntry[]): string {
|
||||
return ""
|
||||
}
|
46
config_gen/generators/doc.ts
Normal file
46
config_gen/generators/doc.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { ConfigEntry } from "../types"
|
||||
import fs from "fs"
|
||||
import { resolve } from "path"
|
||||
import { data } from "../data";
|
||||
import { trimEnd } from "../utils";
|
||||
|
||||
export default function doc(path: string): void {
|
||||
if (!fs.statSync(resolve(path, '_config.yml'))) {
|
||||
console.error('Check your path');
|
||||
return;
|
||||
}
|
||||
if (!fs.statSync(resolve(path, 'index.html'))) {
|
||||
console.error('Check your path');
|
||||
return;
|
||||
}
|
||||
|
||||
const targetPath = resolve(path, '_includes/generated_settings_list.md')
|
||||
|
||||
const text = buildMarkdown(data)
|
||||
|
||||
fs.writeFileSync(targetPath, text, { encoding: 'utf8' });
|
||||
}
|
||||
|
||||
function buildMarkdown(data: ConfigEntry[]): string {
|
||||
let result = '';
|
||||
|
||||
// 目录
|
||||
result += "## 目录\n\n"
|
||||
result += data.filter(x => !x.advancedConfig).map(x => `- [${x.description}](#${x.description})`).join('\n')
|
||||
result += '\n\n'
|
||||
|
||||
// 一般设置项目列表
|
||||
result += data.filter(x => !x.advancedConfig).map(x =>
|
||||
`### ${x.description}
|
||||
|
||||
键名: \`${x.name}\`
|
||||
类型: \`${trimEnd(x.type, '?')}\`
|
||||
默认设置: \`${x.defaultValueDescription ?? x.defaultValue}\`
|
||||
|
||||
${x.markdown}
|
||||
`).join('\n')
|
||||
result += '\n\n'
|
||||
|
||||
return result;
|
||||
}
|
||||
|
12
config_gen/generators/index.ts
Normal file
12
config_gen/generators/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { ConfigEntry } from "../types"
|
||||
export { default as code } from "./code"
|
||||
export { default as doc } from "./doc"
|
||||
|
||||
export const core = function (data: Array<ConfigEntry>) {
|
||||
}
|
||||
export const cli = function (data: Array<ConfigEntry>) {
|
||||
}
|
||||
export const web = function (data: Array<ConfigEntry>) {
|
||||
}
|
||||
export const schema = function (data: Array<ConfigEntry>) {
|
||||
}
|
46
config_gen/index.ts
Normal file
46
config_gen/index.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { spawn } from "child_process";
|
||||
import { stdout, stderr } from "process";
|
||||
import { writeFileSync } from "fs";
|
||||
import { resolve, dirname } from "path";
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
import { data } from "./data"
|
||||
import * as generators from "./generators"
|
||||
|
||||
const baseDirectory = __dirname
|
||||
|
||||
const argv = process.argv.slice(2)
|
||||
|
||||
switch (argv[0]) {
|
||||
case "c":
|
||||
case "code":
|
||||
const availableSections = ["core", "cli", "web", "schema"];
|
||||
let sections = argv.slice(1)
|
||||
sections = sections.length == 0
|
||||
? availableSections
|
||||
: sections.filter(value => {
|
||||
const r = availableSections.includes(value);
|
||||
if (!r)
|
||||
console.warn(`"${value}" is not a valid section name`)
|
||||
return r;
|
||||
})
|
||||
if (sections.length == 0) {
|
||||
console.error("Select valid sections to generate")
|
||||
} else {
|
||||
generators.code(sections);
|
||||
}
|
||||
break;
|
||||
case "d":
|
||||
case "doc":
|
||||
if (typeof argv[1] === 'string') {
|
||||
generators.doc(argv[1]);
|
||||
} else {
|
||||
console.error("Missing argument: <path to website> is required")
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log(`Usage:
|
||||
c, code [core, cli, web, schema]
|
||||
d, doc <path to website>`);
|
||||
break;
|
||||
}
|
125
config_gen/package-lock.json
generated
Normal file
125
config_gen/package-lock.json
generated
Normal file
|
@ -0,0 +1,125 @@
|
|||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-consumer": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.nlark.com/@cspotcode/source-map-consumer/download/@cspotcode/source-map-consumer-0.8.0.tgz?cache=0&sync_timestamp=1628465044726&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40cspotcode%2Fsource-map-consumer%2Fdownload%2F%40cspotcode%2Fsource-map-consumer-0.8.0.tgz",
|
||||
"integrity": "sha1-M79LeznBeIIWBvZpu8RHpqYpeGs=",
|
||||
"dev": true
|
||||
},
|
||||
"@cspotcode/source-map-support": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.nlark.com/@cspotcode/source-map-support/download/@cspotcode/source-map-support-0.6.1.tgz?cache=0&sync_timestamp=1628465040948&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40cspotcode%2Fsource-map-support%2Fdownload%2F%40cspotcode%2Fsource-map-support-0.6.1.tgz",
|
||||
"integrity": "sha1-EYUR8xbi6H7kKUdhho4lTT2keWA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cspotcode/source-map-consumer": "0.8.0"
|
||||
}
|
||||
},
|
||||
"@tsconfig/node10": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.nlark.com/@tsconfig/node10/download/@tsconfig/node10-1.0.8.tgz",
|
||||
"integrity": "sha1-weToDW+WT77LM1nEO9SLQPfK2tk=",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node12": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.nlark.com/@tsconfig/node12/download/@tsconfig/node12-1.0.9.tgz",
|
||||
"integrity": "sha1-YsH23uLr2a6tgNw6+laBDljhoEw=",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node14": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.nlark.com/@tsconfig/node14/download/@tsconfig/node14-1.0.1.tgz",
|
||||
"integrity": "sha1-lfLRZ/+5uNIGiwsjUwL6/U33EfI=",
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node16": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.nlark.com/@tsconfig/node16/download/@tsconfig/node16-1.0.2.tgz",
|
||||
"integrity": "sha1-Qjx3h30Fadsg4fyAiFrEEYMUAQ4=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.6.1",
|
||||
"resolved": "https://registry.nlark.com/@types/node/download/@types/node-16.6.1.tgz?cache=0&sync_timestamp=1628800447602&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-16.6.1.tgz",
|
||||
"integrity": "sha1-ruYse5ZvVfxmx7bfodWNsqYW2mE=",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.nlark.com/acorn/download/acorn-8.4.1.tgz",
|
||||
"integrity": "sha1-VsNiUfx8q8cJatwY8Fr+gUMhoow=",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.nlark.com/acorn-walk/download/acorn-walk-8.1.1.tgz",
|
||||
"integrity": "sha1-Pdq3+E5KfiMT9sQUxbfayF9OPrw=",
|
||||
"dev": true
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npm.taobao.org/arg/download/arg-4.1.3.tgz",
|
||||
"integrity": "sha1-Jp/HrVuOQstjyJbVZmAXJhwUQIk=",
|
||||
"dev": true
|
||||
},
|
||||
"create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/create-require/download/create-require-1.1.1.tgz",
|
||||
"integrity": "sha1-wdfo8eX2z8n/ZfnNNS03NIdWwzM=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz",
|
||||
"integrity": "sha1-YPOuy4nV+uUgwRqhnvwruYKq3n0=",
|
||||
"dev": true
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npm.taobao.org/make-error/download/make-error-1.3.6.tgz?cache=0&sync_timestamp=1582105487630&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmake-error%2Fdownload%2Fmake-error-1.3.6.tgz",
|
||||
"integrity": "sha1-LrLjfqm2fEiR9oShOUeZr0hM96I=",
|
||||
"dev": true
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.nlark.com/ts-node/download/ts-node-10.2.0.tgz?cache=0&sync_timestamp=1628464846072&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fts-node%2Fdownload%2Fts-node-10.2.0.tgz",
|
||||
"integrity": "sha1-8eiCSaAOJqqV6ak8UPcCQaihxLs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cspotcode/source-map-support": "0.6.1",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.nlark.com/tslib/download/tslib-2.3.1.tgz",
|
||||
"integrity": "sha1-6KM1rdXOrlGqJh0ypJAVjvBC7wE=",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.nlark.com/typescript/download/typescript-4.3.5.tgz",
|
||||
"integrity": "sha1-TRw3zBbok5c8RaBohrcRMjTxGfQ=",
|
||||
"dev": true
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/yn/download/yn-3.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyn%2Fdownload%2Fyn-3.1.1.tgz",
|
||||
"integrity": "sha1-HodAGgnXZ8HV6rJqbkwYUYLS61A=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
12
config_gen/package.json
Normal file
12
config_gen/package.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"scripts": {
|
||||
"build": "ts-node index.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.6.1",
|
||||
"ts-node": "^10.2.0",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
29
config_gen/types.ts
Normal file
29
config_gen/types.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/** 设置类型 */
|
||||
export type ConfigEntryType =
|
||||
/** 仅全局设置 */
|
||||
"globalOnly"
|
||||
/** 可单独房间设置或全局设置 */
|
||||
| "room"
|
||||
/** 只能单独房间设置 */
|
||||
| "roomOnly"
|
||||
|
||||
export interface ConfigEntry {
|
||||
/** 名字 */
|
||||
readonly name: string,
|
||||
/** 说明 */
|
||||
readonly description: string,
|
||||
/** 代码类型 */
|
||||
readonly type: string,
|
||||
/** 设置类型 */
|
||||
readonly configType: ConfigEntryType
|
||||
/** 是否为高级设置(隐藏设置),默认为 false */
|
||||
readonly advancedConfig?: boolean,
|
||||
/** 默认值 */
|
||||
readonly defaultValue: string,
|
||||
/** 文档显示用默认值,默认使用 defaultValue */
|
||||
readonly defaultValueDescription?: string,
|
||||
/** XML 注释,默认使用 description */
|
||||
readonly xmlComment?: string,
|
||||
/** Markdown 格式的说明文档 */
|
||||
readonly markdown: string,
|
||||
}
|
5
config_gen/utils.ts
Normal file
5
config_gen/utils.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export function trimEnd(text: string, trimChar: string): string {
|
||||
return text.slice(-1) === trimChar
|
||||
? text.slice(0, -1)
|
||||
: text;
|
||||
}
|
Loading…
Reference in New Issue
Block a user