diff --git a/Brotli.Core/.gitignore b/Brotli.Core/.gitignore new file mode 100644 index 0000000..33a2c50 --- /dev/null +++ b/Brotli.Core/.gitignore @@ -0,0 +1,2 @@ +!runtimes/x64 +!runtimes/x86 \ No newline at end of file diff --git a/Brotli.Core/Brotli.Core.csproj b/Brotli.Core/Brotli.Core.csproj new file mode 100644 index 0000000..2eb5ea0 --- /dev/null +++ b/Brotli.Core/Brotli.Core.csproj @@ -0,0 +1,46 @@ + + + + net45;netstandard2.0 + 2.1.1.0 + true + Brotli.NET + Jinjun Xie + Jinjun Xie + Copyright Jinjun Xie 2016 + + https://github.com/XieJJ99/brotli.net + Brotli Compress Decompress .NET Standard Stream + Add async stream support, update brotli core to v1.0.9 + Supported on dotnet standard2(Windows/Linux/OSX), provide similar interface to Google offical API.Quality and window control is supported. +The library use the native runtime and its performance should be better than System.IO.Compress.BrotliStream. +For more document,please visit https://github.com/XieJJ99/brotli.net. + MIT + 2.1.1.0 + + + + + runtimes + true + + + + + + + + + + + build + true + + + + + + diff --git a/Brotli.Core/Enum/BrotliDecoderParameter.cs b/Brotli.Core/Enum/BrotliDecoderParameter.cs new file mode 100644 index 0000000..a830651 --- /dev/null +++ b/Brotli.Core/Enum/BrotliDecoderParameter.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Brotli +{ + public enum BrotliDecoderParameter:int + { + DisableRingBufferReallocation=0, + LargeWindow=1, + } +} diff --git a/Brotli.Core/Enum/BrotliDecoderResult.cs b/Brotli.Core/Enum/BrotliDecoderResult.cs new file mode 100644 index 0000000..80ecd0d --- /dev/null +++ b/Brotli.Core/Enum/BrotliDecoderResult.cs @@ -0,0 +1,22 @@ +namespace Brotli +{ + public enum BrotliDecoderResult:int + { + /// + /// Decoding error, e.g. corrupt input or memory allocation problem + /// + Error = 0, + /// + /// Decoding successfully completed + /// + Success = 1, + /// + /// Partially done; should be called again with more input + /// + NeedsMoreInput = 2, + /// + /// Partially done; should be called again with more output + /// + NeedsMoreOutput = 3 + }; +} diff --git a/Brotli.Core/Enum/BrotliEncoderOperation.cs b/Brotli.Core/Enum/BrotliEncoderOperation.cs new file mode 100644 index 0000000..4cc17c4 --- /dev/null +++ b/Brotli.Core/Enum/BrotliEncoderOperation.cs @@ -0,0 +1,26 @@ +namespace Brotli +{ + public enum BrotliEncoderOperation : int + { + Process = 0, + /// + /// Request output stream to flush. Performed when input stream is depleted + /// and there is enough space in output stream. + /// + Flush = 1, + /// + /// Request output stream to finish. Performed when input stream is depleted + /// and there is enough space in output stream. + /// + Finish = 2, + + /// + /// Emits metadata block to stream. Stream is soft-flushed before metadata + /// block is emitted. CAUTION: when operation is started, length of the input + /// buffer is interpreted as length of a metadata block; changing operation, + /// expanding or truncating input before metadata block is completely emitted + /// will cause an error; metadata block must not be greater than 16MiB. + /// + EmitMetadata = 3 + }; +} diff --git a/Brotli.Core/Enum/BrotliEncoderParameter.cs b/Brotli.Core/Enum/BrotliEncoderParameter.cs new file mode 100644 index 0000000..d1e471e --- /dev/null +++ b/Brotli.Core/Enum/BrotliEncoderParameter.cs @@ -0,0 +1,22 @@ +namespace Brotli +{ + public enum BrotliEncoderParameter : int + { + Mode = 0, + /// + /// Controls the compression-speed vs compression-density tradeoffs. The higher + /// the quality, the slower the compression. Range is 0 to 11. + /// + Quality = 1, + /// + /// Base 2 logarithm of the sliding window size. Range is 10 to 24. + /// + LGWin = 2, + + /// + /// Base 2 logarithm of the maximum input block size. Range is 16 to 24. + /// If set to 0, the value will be set based on the quality. + /// + LGBlock = 3 + }; +} diff --git a/Brotli.Core/Exception/BrotliDecodeException.cs b/Brotli.Core/Exception/BrotliDecodeException.cs new file mode 100644 index 0000000..286f170 --- /dev/null +++ b/Brotli.Core/Exception/BrotliDecodeException.cs @@ -0,0 +1,25 @@ +using System; + +namespace Brotli +{ + public class BrotliDecodeException : BrotliException + { + public int Code { get; set; } + public String ErrorText { get; set; } + + + public BrotliDecodeException(int code, String errorText) : base() { + Code = code; + ErrorText = errorText; + } + + public BrotliDecodeException(String message, int code, String errorText) : base(message) { + Code = code; + ErrorText = errorText; + } + public BrotliDecodeException(String message, Exception innerException, int code, String errorText) : base(message, innerException) { + Code = code; + ErrorText = errorText; + } + } +} diff --git a/Brotli.Core/Exception/BrotliException.cs b/Brotli.Core/Exception/BrotliException.cs new file mode 100644 index 0000000..f232772 --- /dev/null +++ b/Brotli.Core/Exception/BrotliException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Brotli +{ + public class BrotliException:Exception + { + public BrotliException() : base() { } + public BrotliException(String message) : base(message) { } + public BrotliException(String message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/Brotli.Core/Extensions/BrotliExtensions.cs b/Brotli.Core/Extensions/BrotliExtensions.cs new file mode 100644 index 0000000..d2a7d05 --- /dev/null +++ b/Brotli.Core/Extensions/BrotliExtensions.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Brotli +{ + public static class BrotliExtensions + { + /// + /// Compress the data with brotli + /// + /// inputData + /// quality,0~11 + /// compress window(10~24) + /// compressed bytes + public static byte[] CompressToBrotli(this byte[] rawData, uint quality = 5, uint window = 22) + { + if (rawData == null) throw new ArgumentNullException(nameof(rawData)); + using (var msInput = new System.IO.MemoryStream(rawData)) + { + return CompressToBrotli(msInput, quality, window); + } + } + + /// + /// Compress the data with brotli + /// + /// input stream + /// quality,0~11 + /// compress window(10~24) + /// compressed bytes + public static byte[] CompressToBrotli(this System.IO.Stream inStream, uint quality = 5, uint window = 22) + { + using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream()) + { + CompressToBrotli(inStream, msOutput, quality, window); + var output = msOutput.ToArray(); + return output; + } + } + + /// + /// Compress the data with brotli + /// + /// input stream + /// dest output stream + /// quality,0~11 + /// compress window(10~24) + public static void CompressToBrotli(this System.IO.Stream inStream, System.IO.Stream destStream, uint quality = 5, uint window = 22) + { + using (BrotliStream bs = new BrotliStream(destStream, System.IO.Compression.CompressionMode.Compress)) + { + bs.SetQuality(quality); + bs.SetWindow(window); + inStream.CopyTo(bs); + bs.Close(); + } + } + + public static byte[] DecompressFromBrotli(this byte[] rawData) + { + if (rawData == null) throw new ArgumentNullException(nameof(rawData)); + using (var msInput = new System.IO.MemoryStream(rawData)) + { + return DecompressFromBrotli(msInput); + } + } + + public static byte[] DecompressFromBrotli(this System.IO.Stream inStream) + { + using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream()) + { + DecompressFromBrotli(inStream, msOutput); + var output = msOutput.ToArray(); + return output; + } + } + + public static void DecompressFromBrotli(this System.IO.Stream inStream,System.IO.Stream destStream) + { + using (BrotliStream bs = new BrotliStream(inStream, System.IO.Compression.CompressionMode.Decompress)) + { + bs.CopyTo(destStream); + destStream.Flush(); + } + } + } +} \ No newline at end of file diff --git a/Brotli.Core/Implement/AsyncHelper.cs b/Brotli.Core/Implement/AsyncHelper.cs new file mode 100644 index 0000000..eda8427 --- /dev/null +++ b/Brotli.Core/Implement/AsyncHelper.cs @@ -0,0 +1,67 @@ +using System; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; + +namespace Brotli +{ + internal class AsyncHelper + { + private static readonly TaskFactory _myTaskFactory = new + TaskFactory(CancellationToken.None, TaskCreationOptions.None, + TaskContinuationOptions.None, TaskScheduler.Default); + + internal static void RunSync(Func func, bool await = false) + { + CultureInfo cultureUi = CultureInfo.CurrentUICulture; + CultureInfo culture = CultureInfo.CurrentCulture; + _myTaskFactory.StartNew(delegate + { + Thread.CurrentThread.CurrentCulture = culture; + Thread.CurrentThread.CurrentUICulture = cultureUi; + return func(); + }).Unwrap().ConfigureAwait(await).GetAwaiter().GetResult(); + } + + // Microsoft.AspNet.Identity.AsyncHelper + internal static TResult RunSync(Func> func, bool await = false) + { + CultureInfo cultureUi = CultureInfo.CurrentUICulture; + CultureInfo culture = CultureInfo.CurrentCulture; + return _myTaskFactory.StartNew>(delegate + { + Thread.CurrentThread.CurrentCulture = culture; + Thread.CurrentThread.CurrentUICulture = cultureUi; + return func(); + }).Unwrap().ConfigureAwait(await).GetAwaiter().GetResult(); + } + + + + + internal static TResult RunSync(Func> func, object state, bool await = false) + { + CultureInfo cultureUi = CultureInfo.CurrentUICulture; + CultureInfo culture = CultureInfo.CurrentCulture; + return _myTaskFactory.StartNew>(delegate + { + Thread.CurrentThread.CurrentCulture = culture; + Thread.CurrentThread.CurrentUICulture = cultureUi; + return func(state); + }, state).Unwrap().ConfigureAwait(await).GetAwaiter().GetResult(); + } + + internal static TResult RunSync(Func> func, object state, CancellationToken cancellationToken, bool await = false) + { + CultureInfo cultureUi = CultureInfo.CurrentUICulture; + CultureInfo culture = CultureInfo.CurrentCulture; + return _myTaskFactory.StartNew>(delegate + { + Thread.CurrentThread.CurrentCulture = culture; + Thread.CurrentThread.CurrentUICulture = cultureUi; + return func(state); + }, state, cancellationToken).Unwrap().ConfigureAwait(await).GetAwaiter().GetResult(); + } + + } +} diff --git a/Brotli.Core/Implement/Brolib.cs b/Brotli.Core/Implement/Brolib.cs new file mode 100644 index 0000000..627d0ee --- /dev/null +++ b/Brotli.Core/Implement/Brolib.cs @@ -0,0 +1,316 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Brotli +{ + public class Brolib + { + static bool UseX86 = IntPtr.Size == 4; + #region Encoder + public static IntPtr BrotliEncoderCreateInstance() + { + if (UseX86) + { + return Brolib32.BrotliEncoderCreateInstance(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } + else + { + return Brolib64.BrotliEncoderCreateInstance(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } + } + + + public static IntPtr GetModuleHandle(String moduleName) + { + IntPtr r = IntPtr.Zero; + foreach (ProcessModule mod in Process.GetCurrentProcess().Modules) + { + if (String.Compare(mod.ModuleName,moduleName,true)==0) + { + r = mod.BaseAddress; + break; + } + } + return r; + } + + public static void FreeLibrary() + { + + IntPtr libHandle = IntPtr.Zero; + libHandle = GetModuleHandle(LibPathBootStrapper.LibPath); + if (libHandle!=IntPtr.Zero) + { + NativeLibraryLoader.FreeLibrary(libHandle); + } + } + + public static bool BrotliEncoderSetParameter(IntPtr state, BrotliEncoderParameter parameter, UInt32 value) + { + if (UseX86) + { + return Brolib32.BrotliEncoderSetParameter(state, parameter, value); + } + else + { + return Brolib64.BrotliEncoderSetParameter(state, parameter, value); + } + } + + //@to rewrite using the following APIs + //BrotliGetDictionary + //BrotliGetTransforms + //BrotliSetDictionaryData + //BrotliTransformDictionaryWord + //public static void BrotliEncoderSetCustomDictionary(IntPtr state, UInt32 size, IntPtr dict) + //{ + // if (UseX86) + // { + // Brolib32.BrotliEncoderSetCustomDictionary(state, size, dict); + // } + // else + // { + // Brolib64.BrotliEncoderSetCustomDictionary(state, size, dict); + // } + //} + + public static bool BrotliEncoderCompressStream( + IntPtr state, BrotliEncoderOperation op, ref UInt32 availableIn, + ref IntPtr nextIn, ref UInt32 availableOut, ref IntPtr nextOut, out UInt32 totalOut) + { + if (UseX86) + { + return Brolib32.BrotliEncoderCompressStream(state, op, ref availableIn, ref nextIn, ref availableOut, ref nextOut, out totalOut); + } + else + { + UInt64 availableInL = availableIn; + UInt64 availableOutL = availableOut; + UInt64 totalOutL = 0; + var r = Brolib64.BrotliEncoderCompressStream(state, op, ref availableInL, ref nextIn, ref availableOutL, ref nextOut, out totalOutL); + availableIn = (UInt32)availableInL; + availableOut = (UInt32)availableOutL; + totalOut = (UInt32)totalOutL; + return r; + } + } + + public static bool BrotliEncoderIsFinished(IntPtr state) + { + if (UseX86) + { + return Brolib32.BrotliEncoderIsFinished(state); + } + else + { + return Brolib64.BrotliEncoderIsFinished(state); + } + } + + public static void BrotliEncoderDestroyInstance(IntPtr state) + { + if (UseX86) + { + Brolib32.BrotliEncoderDestroyInstance(state); + } + else + { + Brolib64.BrotliEncoderDestroyInstance(state); + } + } + + public static UInt32 BrotliEncoderVersion() + { + if (UseX86) + { + return Brolib32.BrotliEncoderVersion(); + } + else + { + return Brolib64.BrotliEncoderVersion(); + } + } + + + public static IntPtr BrotliDecoderTakeOutput(IntPtr state, ref UInt32 size) + { + if (UseX86) + { + return Brolib32.BrotliDecoderTakeOutput(state, ref size); + } + else + { + UInt64 longSize = size; + var r = Brolib64.BrotliDecoderTakeOutput(state, ref longSize); + size = (UInt32)longSize; + return r; + } + } + + + + #endregion + #region Decoder + public static IntPtr BrotliDecoderCreateInstance() + { + if (UseX86) + { + return Brolib32.BrotliDecoderCreateInstance(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } + else + { + return Brolib64.BrotliDecoderCreateInstance(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } + } + + public static bool BrotliDecoderSetParameter(IntPtr state, BrotliDecoderParameter param, UInt32 value) + { + if (UseX86) + { + return Brolib32.BrotliDecoderSetParameter(state,param,value); + } + else + { + return Brolib64.BrotliDecoderSetParameter(state, param, value); + } + } + + + //@to rewrite using the following APIs + //BrotliGetDictionary + //BrotliGetTransforms + //BrotliSetDictionaryData + //BrotliTransformDictionaryWord + //public static void BrotliDecoderSetCustomDictionary(IntPtr state, UInt32 size, IntPtr dict) + //{ + // if (UseX86) + // { + // Brolib32.BrotliDecoderSetCustomDictionary(state, size, dict); + // } + // else + // { + // Brolib64.BrotliDecoderSetCustomDictionary(state, size, dict); + // } + //} + + public static BrotliDecoderResult BrotliDecoderDecompressStream( + IntPtr state, ref UInt32 availableIn, + ref IntPtr nextIn, ref UInt32 availableOut, ref IntPtr nextOut, out UInt32 totalOut) + { + if (UseX86) + { + return Brolib32.BrotliDecoderDecompressStream(state, ref availableIn, ref nextIn, ref availableOut, ref nextOut, out totalOut); + } + else + { + UInt64 availableInL = availableIn; + UInt64 availableOutL = availableOut; + UInt64 totalOutL = 0; + var r = Brolib64.BrotliDecoderDecompressStream(state, ref availableInL, ref nextIn, ref availableOutL, ref nextOut, out totalOutL); + availableIn = (UInt32)availableInL; + availableOut = (UInt32)availableOutL; + totalOut = (UInt32)totalOutL; + return r; + } + } + + public static void BrotliDecoderDestroyInstance(IntPtr state) + { + if (UseX86) + { + Brolib32.BrotliDecoderDestroyInstance(state); + } + else + { + Brolib64.BrotliDecoderDestroyInstance(state); + } + } + + public static UInt32 BrotliDecoderVersion() + { + if (UseX86) + { + return Brolib32.BrotliDecoderVersion(); + } + else + { + return Brolib64.BrotliDecoderVersion(); + } + } + + public static bool BrotliDecoderIsUsed(IntPtr state) + { + if (UseX86) + { + return Brolib32.BrotliDecoderIsUsed(state); + } + else + { + return Brolib64.BrotliDecoderIsUsed(state); + } + } + public static bool BrotliDecoderIsFinished(IntPtr state) + { + if (UseX86) + { + return Brolib32.BrotliDecoderIsFinished(state); + } + else + { + return Brolib64.BrotliDecoderIsFinished(state); + } + + } + public static Int32 BrotliDecoderGetErrorCode(IntPtr state) + { + if (UseX86) + { + return Brolib32.BrotliDecoderGetErrorCode(state); + } + else + { + return Brolib64.BrotliDecoderGetErrorCode(state); + } + } + + public static String BrotliDecoderErrorString(Int32 code) + { + IntPtr r = IntPtr.Zero; + if (UseX86) + { + r = Brolib32.BrotliDecoderErrorString(code); + } + else + { + r = Brolib64.BrotliDecoderErrorString(code); + } + + if (r != IntPtr.Zero) + { + return Marshal.PtrToStringAnsi(r); + } + return String.Empty; + + + } + + public static IntPtr BrotliEncoderTakeOutput(IntPtr state, ref UInt32 size) + { + if (UseX86) + { + return Brolib32.BrotliEncoderTakeOutput(state, ref size); + } + else + { + UInt64 longSize = size; + var r = Brolib64.BrotliEncoderTakeOutput(state, ref longSize); + size = (UInt32)longSize; + return r; + } + } + + + #endregion + } +} diff --git a/Brotli.Core/Implement/BrotliStream.cs b/Brotli.Core/Implement/BrotliStream.cs new file mode 100644 index 0000000..ebdadac --- /dev/null +++ b/Brotli.Core/Implement/BrotliStream.cs @@ -0,0 +1,443 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +namespace Brotli +{ + public class BrotliStream : Stream + { + const int BufferSize = 64 * 1024; + protected Stream _stream = null; + protected MemoryStream _intermediateStream = new MemoryStream(); + protected CompressionMode _mode = CompressionMode.Compress; + protected IntPtr _state = IntPtr.Zero; + protected IntPtr _ptrInputBuffer = IntPtr.Zero; + protected IntPtr _ptrOutputBuffer = IntPtr.Zero; + + protected IntPtr _ptrNextInput = IntPtr.Zero; + protected IntPtr _ptrNextOutput = IntPtr.Zero; + protected UInt32 _availableIn = 0; + protected UInt32 _availableOut = BufferSize; + + protected Byte[] _managedBuffer; + protected Boolean _endOfStream = false; + protected int _readOffset = 0; + protected BrotliDecoderResult _lastDecodeResult = BrotliDecoderResult.NeedsMoreInput; + protected Boolean _leaveOpen = false; + + public BrotliStream(Stream baseStream, CompressionMode mode,bool leaveOpen) + { + if (baseStream == null) throw new ArgumentNullException("baseStream"); + _mode = mode; + _stream = baseStream; + _leaveOpen = leaveOpen; + if (_mode == CompressionMode.Compress) + { + _state = Brolib.BrotliEncoderCreateInstance(); + if (_state == IntPtr.Zero) + { + throw new BrotliException("Unable to create brotli encoder instance"); + } + Brolib.BrotliEncoderSetParameter(_state, BrotliEncoderParameter.Quality, 5); + Brolib.BrotliEncoderSetParameter(_state, BrotliEncoderParameter.LGWin, 22); + } + else + { + _state = Brolib.BrotliDecoderCreateInstance(); + if (_state == IntPtr.Zero) + { + throw new BrotliException("Unable to create brotli decoder instance"); + } + //follow the brotli default standard + var succ = Brolib.BrotliDecoderSetParameter(_state, BrotliDecoderParameter.LargeWindow, 1U); + if (!succ) + { + throw new BrotliException("failed to set decoder parameter to large window"); + } + } + _ptrInputBuffer = Marshal.AllocHGlobal(BufferSize); + _ptrOutputBuffer = Marshal.AllocHGlobal(BufferSize); + _ptrNextInput = _ptrInputBuffer; + _ptrNextOutput = _ptrOutputBuffer; + + _managedBuffer = new Byte[BufferSize]; + } + public BrotliStream(Stream baseStream, CompressionMode mode):this(baseStream,mode,false) + { + + } + + /// + /// Set the compress quality(0~11) + /// + /// compress quality + public void SetQuality(uint quality) + { + if (quality < 0 || quality > 11) + { + throw new ArgumentException("quality", "the range of quality is 0~11"); + } + Brolib.BrotliEncoderSetParameter(_state, BrotliEncoderParameter.Quality, quality); + } + + /// + /// Set the compress LGWin(10~24) + /// + /// the window size + public void SetWindow(uint window) + { + if (window < 10 || window > 24) + { + throw new ArgumentException("window", "the range of window is 10~24"); + } + Brolib.BrotliEncoderSetParameter(_state, BrotliEncoderParameter.LGWin, window); + } + + public override bool CanRead + { + get + { + if (_stream == null) + { + return false; + } + + return (_mode == System.IO.Compression.CompressionMode.Decompress && _stream.CanRead); + } + } + + public override bool CanSeek + { + get + { + return false; + } + } + + public override bool CanWrite + { + get + { + if (_stream == null) + { + return false; + } + + return (_mode == System.IO.Compression.CompressionMode.Compress && _stream.CanWrite); + } + } + + public override long Length + { + get + { + throw new NotImplementedException(); + } + } + + public override long Position + { + get + { + throw new NotImplementedException(); + } + + set + { + throw new NotImplementedException(); + } + } + + public override async Task FlushAsync(CancellationToken cancellationToken) + { + if (_stream == null) + { + throw new ObjectDisposedException(null, "Underlying stream is disposed"); + } + if (_mode == CompressionMode.Compress) + { + await FlushBrotliStreamAsync(false).ConfigureAwait(false); + } + + } + public override void Flush() + { + AsyncHelper.RunSync(() => FlushAsync()); + } + + protected virtual async Task FlushBrotliStreamAsync(Boolean finished) + { + //test if the resource has been freed + if (_state == IntPtr.Zero) return; + if (Brolib.BrotliEncoderIsFinished(_state)) return; + BrotliEncoderOperation op = finished ? BrotliEncoderOperation.Finish : BrotliEncoderOperation.Flush; + UInt32 totalOut = 0; + while (true) + { + var compressOK = Brolib.BrotliEncoderCompressStream(_state, op, ref _availableIn, ref _ptrNextInput, ref _availableOut, ref _ptrNextOutput, out totalOut); + if (!compressOK) throw new BrotliException("Unable to finish encode stream"); + var extraData = _availableOut != BufferSize; + if (extraData) + { + var bytesWrote = (int)(BufferSize - _availableOut); + Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, bytesWrote); + await _stream.WriteAsync(_managedBuffer, 0, bytesWrote).ConfigureAwait(false); + _availableOut = BufferSize; + _ptrNextOutput = _ptrOutputBuffer; + } + if (Brolib.BrotliEncoderIsFinished(_state)) break; + if (!extraData) break; + } + + } + + protected virtual void FlushBrotliStream(Boolean finished) + { + + AsyncHelper.RunSync(() => FlushBrotliStreamAsync(finished)); + } + + protected override void Dispose(bool disposing) + { + if (_mode == CompressionMode.Compress) + { + FlushBrotliStream(true); + } + base.Dispose(disposing); + if (!_leaveOpen) _stream.Dispose(); + _intermediateStream.Dispose(); + if (_ptrInputBuffer!=IntPtr.Zero) Marshal.FreeHGlobal(_ptrInputBuffer); + if (_ptrOutputBuffer != IntPtr.Zero) Marshal.FreeHGlobal(_ptrOutputBuffer); + _managedBuffer = null; + _ptrInputBuffer = IntPtr.Zero; + _ptrOutputBuffer = IntPtr.Zero; + if (_state != IntPtr.Zero) + { + if (_mode == CompressionMode.Compress) + { + Brolib.BrotliEncoderDestroyInstance(_state); + } + else + { + Brolib.BrotliDecoderDestroyInstance(_state); + } + _state = IntPtr.Zero; + } + } + + + public void TruncateBeginning(MemoryStream ms, int numberOfBytesToRemove) + { +#if NETSTANDARD2_0 + ArraySegment buf; + if(ms.TryGetBuffer(out buf)) + { + Buffer.BlockCopy(buf.Array, numberOfBytesToRemove, buf.Array, 0, (int)ms.Length - numberOfBytesToRemove); + ms.SetLength(ms.Length - numberOfBytesToRemove); + } + else + { + throw new UnauthorizedAccessException(); + } +#else + byte[] buf = ms.GetBuffer(); + Buffer.BlockCopy(buf, numberOfBytesToRemove, buf, 0, (int)ms.Length - numberOfBytesToRemove); + ms.SetLength(ms.Length - numberOfBytesToRemove); +#endif + } + + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (_mode != CompressionMode.Decompress) throw new BrotliException("Can't read on this stream"); + + + int bytesRead = (int)(_intermediateStream.Length - _readOffset); + uint totalCount = 0; + Boolean endOfStream = false; + Boolean errorDetected = false; + while (bytesRead < count) + { + while (true) + { + if (_lastDecodeResult == BrotliDecoderResult.NeedsMoreInput) + { + _availableIn = (UInt32) await _stream.ReadAsync(_managedBuffer, 0, (int)BufferSize).ConfigureAwait(false); + _ptrNextInput = _ptrInputBuffer; + if (_availableIn <= 0) + { + endOfStream = true; + break; + } + Marshal.Copy(_managedBuffer, 0, _ptrInputBuffer, (int)_availableIn); + } + else if (_lastDecodeResult == BrotliDecoderResult.NeedsMoreOutput) + { + Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, BufferSize); + await _intermediateStream.WriteAsync(_managedBuffer, 0, BufferSize).ConfigureAwait(false); + bytesRead += BufferSize; + _availableOut = BufferSize; + _ptrNextOutput = _ptrOutputBuffer; + } + else + { + //Error or OK + endOfStream = true; + break; + } + _lastDecodeResult = Brolib.BrotliDecoderDecompressStream(_state, ref _availableIn, ref _ptrNextInput, + ref _availableOut, ref _ptrNextOutput, out totalCount); + if (bytesRead >= count) break; + } + if (endOfStream && !Brolib.BrotliDecoderIsFinished(_state)) + { + errorDetected = true; + } + + if (_lastDecodeResult == BrotliDecoderResult.Error || errorDetected) + { + var error = Brolib.BrotliDecoderGetErrorCode(_state); + var text = Brolib.BrotliDecoderErrorString(error); + throw new BrotliDecodeException(String.Format("Unable to decode stream,possibly corrupt data.Code={0}({1})", error, text), error, text); + } + + if (endOfStream && !Brolib.BrotliDecoderIsFinished(_state) && _lastDecodeResult == BrotliDecoderResult.NeedsMoreInput) + { + throw new BrotliException("Unable to decode stream,unexpected EOF"); + } + + if (endOfStream && _ptrNextOutput != _ptrOutputBuffer) + { + int remainBytes = (int)(_ptrNextOutput.ToInt64() - _ptrOutputBuffer.ToInt64()); + bytesRead += remainBytes; + Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, remainBytes); + await _intermediateStream.WriteAsync(_managedBuffer, 0, remainBytes).ConfigureAwait(false); + _ptrNextOutput = _ptrOutputBuffer; + } + if (endOfStream) break; + } + + if (_intermediateStream.Length - _readOffset >= count || endOfStream) + { + _intermediateStream.Seek(_readOffset, SeekOrigin.Begin); + var bytesToRead = (int)(_intermediateStream.Length - _readOffset); + if (bytesToRead > count) bytesToRead = count; + await _intermediateStream.ReadAsync(buffer, offset, bytesToRead).ConfigureAwait(false); + TruncateBeginning(_intermediateStream, _readOffset + bytesToRead); + _readOffset = 0; + return bytesToRead; + } + + return 0; + } + public override int Read(byte[] buffer, int offset, int count) + { + async Task task() + { + return await ReadAsync(buffer,offset,count).ConfigureAwait(false); + + } + return AsyncHelper.RunSync(task); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + static int totalWrote = 0; + + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (_mode != CompressionMode.Compress) throw new BrotliException("Can't write on this stream"); + totalWrote += count; + //Console.WriteLine(String.Format("Write {0} bytes,total={1} bytes.", count, totalWrote)); + + UInt32 totalOut = 0; + int bytesRemain = count; + int currentOffset = offset; + + Boolean compressOK = true; + while (bytesRemain > 0) + { + int copyLen = bytesRemain > BufferSize ? BufferSize : bytesRemain; + Marshal.Copy(buffer, currentOffset, _ptrInputBuffer, copyLen); + bytesRemain -= copyLen; + currentOffset += copyLen; + _availableIn = (UInt32)copyLen; + _ptrNextInput = _ptrInputBuffer; + while (_availableIn > 0) + { + compressOK = Brolib.BrotliEncoderCompressStream(_state, BrotliEncoderOperation.Process, ref _availableIn, ref _ptrNextInput, ref _availableOut, + ref _ptrNextOutput, out totalOut); + if (!compressOK) throw new BrotliException("Unable to compress stream"); + if (_availableOut != BufferSize) + { + var bytesWrote = (int)(BufferSize - _availableOut); + //Byte[] localBuffer = new Byte[bytesWrote]; + Marshal.Copy(_ptrOutputBuffer, _managedBuffer, 0, bytesWrote); + await _stream.WriteAsync(_managedBuffer, 0, bytesWrote).ConfigureAwait(false); + _availableOut = BufferSize; + _ptrNextOutput = _ptrOutputBuffer; + } + } + if (Brolib.BrotliEncoderIsFinished(_state)) break; + } + } + + public override void Write(byte[] buffer, int offset, int count) + { + async Task task() + { + await WriteAsync(buffer,offset,count).ConfigureAwait(false); + + } + AsyncHelper.RunSync(task); + } + } + +#if NET35 + /// + /// Improve compability issue on FX35 + /// + public static class StreamCopyExtension + { + public static void CopyTo(this Stream source,Stream destination, int bufferSize=4*1024) + { + if (source==null) + { + throw new ArgumentNullException(nameof(source)); + } + if (destination==null) + { + throw new ArgumentNullException(nameof(destination)); + } + if (!source.CanRead) + { + throw new InvalidOperationException("source stream is not readable"); + } + if (!destination.CanWrite) + { + throw new InvalidOperationException("destination stream is not writeable"); + } + if (bufferSize<=0) + { + throw new InvalidOperationException("buffer size should be greate than zero"); + } + + + byte[] buffer = new byte[bufferSize]; + int read; + while ((read = source.Read(buffer, 0, buffer.Length)) > 0) + destination.Write(buffer, 0, read); + } + } +#endif +} diff --git a/Brotli.Core/Interop/Brolib32.cs b/Brotli.Core/Interop/Brolib32.cs new file mode 100644 index 0000000..93b1efb --- /dev/null +++ b/Brotli.Core/Interop/Brolib32.cs @@ -0,0 +1,62 @@ +using System; +using System.Runtime.InteropServices; + +namespace Brotli +{ + class Brolib32 + { + static Brolib32() + { + var path = LibPathBootStrapper.LibPath; + NativeLibraryLoader nl = new NativeLibraryLoader(path); + #region set encoder + nl.FillDelegate(out BrotliEncoderCreateInstance); + nl.FillDelegate(out BrotliEncoderSetParameter); + nl.FillDelegate(out BrotliEncoderCompressStream); + nl.FillDelegate(out BrotliEncoderIsFinished); + nl.FillDelegate(out BrotliEncoderDestroyInstance); + nl.FillDelegate(out BrotliEncoderVersion); + nl.FillDelegate(out BrotliEncoderVersion); + nl.FillDelegate(out BrotliEncoderTakeOutput); + #endregion + #region set decoder + nl.FillDelegate(out BrotliDecoderCreateInstance); + nl.FillDelegate(out BrotliDecoderSetParameter); + nl.FillDelegate(out BrotliDecoderDecompressStream); + nl.FillDelegate(out BrotliDecoderDestroyInstance); + nl.FillDelegate(out BrotliDecoderVersion); + nl.FillDelegate(out BrotliDecoderIsUsed); + nl.FillDelegate(out BrotliDecoderIsFinished); + nl.FillDelegate(out BrotliDecoderGetErrorCode); + nl.FillDelegate(out BrotliDecoderErrorString); + nl.FillDelegate(out BrotliDecoderTakeOutput); + #endregion + } + #region Encoder + internal static Delegate32.BrotliEncoderCreateInstanceDelegate BrotliEncoderCreateInstance; + internal static Delegate32.BrotliEncoderSetParameterDelegate BrotliEncoderSetParameter; + //internal static Delegate32.BrotliEncoderSetCustomDictionaryDelegate BrotliEncoderSetCustomDictionary; + internal static Delegate32.BrotliEncoderCompressStreamDelegate BrotliEncoderCompressStream; + internal static Delegate32.BrotliEncoderIsFinishedDelegate BrotliEncoderIsFinished; + internal static Delegate32.BrotliEncoderDestroyInstanceDelegate BrotliEncoderDestroyInstance; + internal static Delegate32.BrotliEncoderVersionDelegate BrotliEncoderVersion; + internal static Delegate32.BrotliEncoderTakeOutputDelegate BrotliEncoderTakeOutput; + #endregion + #region Decoder + internal static Delegate32.BrotliDecoderCreateInstanceDelegate BrotliDecoderCreateInstance; + internal static Delegate32.BrotliDecoderSetParameter BrotliDecoderSetParameter; + //internal static Delegate32.BrotliDecoderSetCustomDictionary BrotliDecoderSetCustomDictionary; + internal static Delegate32.BrotliDecoderDecompressStreamDelegate BrotliDecoderDecompressStream; + + internal static Delegate32.BrotliDecoderDestroyInstanceDelegate BrotliDecoderDestroyInstance; + + internal static Delegate32.BrotliDecoderVersionDelegate BrotliDecoderVersion; + internal static Delegate32.BrotliDecoderIsUsedDelegate BrotliDecoderIsUsed; + internal static Delegate32.BrotliDecoderIsFinishedDelegate BrotliDecoderIsFinished; + internal static Delegate32.BrotliDecoderGetErrorCodeDelegate BrotliDecoderGetErrorCode; + internal static Delegate32.BrotliDecoderErrorStringDelegate BrotliDecoderErrorString; + internal static Delegate32.BrotliDecoderTakeOutputDelegate BrotliDecoderTakeOutput; + + #endregion + } +} diff --git a/Brotli.Core/Interop/Brolib64.cs b/Brotli.Core/Interop/Brolib64.cs new file mode 100644 index 0000000..6f73e0e --- /dev/null +++ b/Brotli.Core/Interop/Brolib64.cs @@ -0,0 +1,62 @@ +using System; +using System.Runtime.InteropServices; + +namespace Brotli +{ + class Brolib64 + { + static Brolib64() + { + var path = LibPathBootStrapper.LibPath; + NativeLibraryLoader nl = new NativeLibraryLoader(path); + #region set encoder + nl.FillDelegate(out BrotliEncoderCreateInstance); + nl.FillDelegate(out BrotliEncoderSetParameter); + nl.FillDelegate(out BrotliEncoderCompressStream); + nl.FillDelegate(out BrotliEncoderIsFinished); + nl.FillDelegate(out BrotliEncoderDestroyInstance); + nl.FillDelegate(out BrotliEncoderVersion); + nl.FillDelegate(out BrotliEncoderVersion); + nl.FillDelegate(out BrotliEncoderTakeOutput); + #endregion + #region set decoder + nl.FillDelegate(out BrotliDecoderCreateInstance); + nl.FillDelegate(out BrotliDecoderSetParameter); + nl.FillDelegate(out BrotliDecoderDecompressStream); + nl.FillDelegate(out BrotliDecoderDestroyInstance); + nl.FillDelegate(out BrotliDecoderVersion); + nl.FillDelegate(out BrotliDecoderIsUsed); + nl.FillDelegate(out BrotliDecoderIsFinished); + nl.FillDelegate(out BrotliDecoderGetErrorCode); + nl.FillDelegate(out BrotliDecoderErrorString); + nl.FillDelegate(out BrotliDecoderTakeOutput); + #endregion + } + #region Encoder + internal static Delegate64.BrotliEncoderCreateInstanceDelegate BrotliEncoderCreateInstance; + internal static Delegate64.BrotliEncoderSetParameterDelegate BrotliEncoderSetParameter; + //internal static Delegate64.BrotliEncoderSetCustomDictionaryDelegate BrotliEncoderSetCustomDictionary; + internal static Delegate64.BrotliEncoderCompressStreamDelegate BrotliEncoderCompressStream; + internal static Delegate64.BrotliEncoderIsFinishedDelegate BrotliEncoderIsFinished; + internal static Delegate64.BrotliEncoderDestroyInstanceDelegate BrotliEncoderDestroyInstance; + internal static Delegate64.BrotliEncoderVersionDelegate BrotliEncoderVersion; + internal static Delegate64.BrotliEncoderTakeOutputDelegate BrotliEncoderTakeOutput; + #endregion + #region Decoder + internal static Delegate64.BrotliDecoderCreateInstanceDelegate BrotliDecoderCreateInstance; + internal static Delegate64.BrotliDecoderSetParameter BrotliDecoderSetParameter; + //internal static Delegate64.BrotliDecoderSetCustomDictionary BrotliDecoderSetCustomDictionary; + internal static Delegate64.BrotliDecoderDecompressStreamDelegate BrotliDecoderDecompressStream; + + internal static Delegate64.BrotliDecoderDestroyInstanceDelegate BrotliDecoderDestroyInstance; + + internal static Delegate64.BrotliDecoderVersionDelegate BrotliDecoderVersion; + internal static Delegate64.BrotliDecoderIsUsedDelegate BrotliDecoderIsUsed; + internal static Delegate64.BrotliDecoderIsFinishedDelegate BrotliDecoderIsFinished; + internal static Delegate64.BrotliDecoderGetErrorCodeDelegate BrotliDecoderGetErrorCode; + internal static Delegate64.BrotliDecoderErrorStringDelegate BrotliDecoderErrorString; + internal static Delegate64.BrotliDecoderTakeOutputDelegate BrotliDecoderTakeOutput; + + #endregion + } +} diff --git a/Brotli.Core/Interop/Delegate32.cs b/Brotli.Core/Interop/Delegate32.cs new file mode 100644 index 0000000..ba444ae --- /dev/null +++ b/Brotli.Core/Interop/Delegate32.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace Brotli +{ + internal class Delegate32 + { + #region Encoder + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliEncoderCreateInstanceDelegate(IntPtr allocFunc, IntPtr freeFunc, IntPtr opaque); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliEncoderSetParameterDelegate(IntPtr state, BrotliEncoderParameter parameter, UInt32 value); + + //delegate void BrotliEncoderSetCustomDictionary(IntPtr state, UInt32 size, IntPtr dict); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliEncoderCompressStreamDelegate( + IntPtr state, BrotliEncoderOperation op, ref UInt32 availableIn, + ref IntPtr nextIn, ref UInt32 availableOut, ref IntPtr nextOut, out UInt32 totalOut); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliEncoderIsFinishedDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void BrotliEncoderDestroyInstanceDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate UInt32 BrotliEncoderVersionDelegate(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliEncoderTakeOutputDelegate(IntPtr state, ref UInt32 size); + #endregion + #region Decoder + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliDecoderCreateInstanceDelegate(IntPtr allocFunc, IntPtr freeFunc, IntPtr opaque); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliDecoderSetParameter(IntPtr state, BrotliDecoderParameter param, UInt32 value); + //delegate void BrotliDecoderSetCustomDictionary(IntPtr state, UInt32 size, IntPtr dict); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate BrotliDecoderResult BrotliDecoderDecompressStreamDelegate( + IntPtr state, ref UInt32 availableIn, ref IntPtr nextIn, + ref UInt32 availableOut, ref IntPtr nextOut, out UInt32 totalOut); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void BrotliDecoderDestroyInstanceDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate UInt32 BrotliDecoderVersionDelegate(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliDecoderIsUsedDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliDecoderIsFinishedDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Int32 BrotliDecoderGetErrorCodeDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliDecoderErrorStringDelegate(Int32 code); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliDecoderTakeOutputDelegate(IntPtr state, ref UInt32 size); + + #endregion + } +} diff --git a/Brotli.Core/Interop/Delegate64.cs b/Brotli.Core/Interop/Delegate64.cs new file mode 100644 index 0000000..e419e91 --- /dev/null +++ b/Brotli.Core/Interop/Delegate64.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace Brotli +{ + internal class Delegate64 + { + #region Encoder + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliEncoderCreateInstanceDelegate(IntPtr allocFunc, IntPtr freeFunc, IntPtr opaque); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliEncoderSetParameterDelegate(IntPtr state, BrotliEncoderParameter parameter, UInt32 value); + + //delegate void BrotliEncoderSetCustomDictionary(IntPtr state, UInt32 size, IntPtr dict); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliEncoderCompressStreamDelegate( + IntPtr state, BrotliEncoderOperation op, ref UInt64 availableIn, + ref IntPtr nextIn, ref UInt64 availableOut, ref IntPtr nextOut, out UInt64 totalOut); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliEncoderIsFinishedDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void BrotliEncoderDestroyInstanceDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate UInt32 BrotliEncoderVersionDelegate(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliEncoderTakeOutputDelegate(IntPtr state, ref UInt64 size); + + #endregion + #region Decoder + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliDecoderCreateInstanceDelegate(IntPtr allocFunc, IntPtr freeFunc, IntPtr opaque); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliDecoderSetParameter(IntPtr state, BrotliDecoderParameter param, UInt32 value); + //delegate void BrotliDecoderSetCustomDictionary(IntPtr state, UInt64 size, IntPtr dict); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate BrotliDecoderResult BrotliDecoderDecompressStreamDelegate( + IntPtr state, ref UInt64 availableIn, ref IntPtr nextIn, + ref UInt64 availableOut, ref IntPtr nextOut, out UInt64 totalOut); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void BrotliDecoderDestroyInstanceDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate UInt32 BrotliDecoderVersionDelegate(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliDecoderIsUsedDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BrotliDecoderIsFinishedDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Int32 BrotliDecoderGetErrorCodeDelegate(IntPtr state); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliDecoderErrorStringDelegate(Int32 code); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate IntPtr BrotliDecoderTakeOutputDelegate(IntPtr state, ref UInt64 size); + + #endregion + } +} diff --git a/Brotli.Core/Interop/LibPathBootStrapper.cs b/Brotli.Core/Interop/LibPathBootStrapper.cs new file mode 100644 index 0000000..0f3dcaa --- /dev/null +++ b/Brotli.Core/Interop/LibPathBootStrapper.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; + +namespace Brotli +{ + internal class LibPathBootStrapper + { + internal static string LibPath { get; private set; } + + static LibPathBootStrapper() + { + + + string fileName = null; + if (NativeLibraryLoader.IsWindows) + { + if (NativeLibraryLoader.Is64Bit) + { + fileName = "brolib_x64.dll"; + } + else + { + fileName = "brolib_x86.dll"; + } + } else if (NativeLibraryLoader.IsLinux) + { + if (NativeLibraryLoader.Is64Bit) + { + fileName = "brolib_x64.so"; + } + else + { + fileName = "brolib_x86.so"; + } + } else if (NativeLibraryLoader.IsMacOSX) + { + if (NativeLibraryLoader.Is64Bit) + { + fileName = "brolib_x64.dylib"; + } + } + if (string.IsNullOrEmpty(fileName)) throw new NotSupportedException($"OS not supported:{Environment.OSVersion.ToString()}"); + var paths = NativeLibraryLoader.GetPossibleRuntimeDirectories(); + var libFound = false; + foreach(var path in paths) + { + var fullPath = Path.Combine(path, fileName); + if (System.IO.File.Exists(fullPath)) + { + LibPath = fullPath; + libFound = true; + break; + } + } + + if (!libFound) throw new NotSupportedException($"Unable to find library {fileName}"); + } + } +} diff --git a/Brotli.Core/Interop/NativeLibraryLoader.cs b/Brotli.Core/Interop/NativeLibraryLoader.cs new file mode 100644 index 0000000..2b256fa --- /dev/null +++ b/Brotli.Core/Interop/NativeLibraryLoader.cs @@ -0,0 +1,234 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +namespace Brotli +{ + internal class NativeLibraryLoader + { + internal static bool IsWindows = false; + internal static bool IsLinux = false; + internal static bool IsMacOSX = false; + internal static bool IsNetCore = false; + internal static bool Is64Bit = false; + static NativeLibraryLoader() + { +#if NET35 || NET40 + IsWindows=true; +#else + IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + IsMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + IsNetCore = RuntimeInformation.FrameworkDescription.StartsWith(".NET Core"); +#endif + if (!IsWindows && !IsLinux && !IsMacOSX) + { + throw new InvalidOperationException("Unsupported platform."); + } + Is64Bit = IntPtr.Size == 8; + } + + // dlopen flags + const int RtldLazy = 1; + const int RtldGlobal = 8; + + readonly string _libraryPath; + internal IntPtr Handle { get; private set; } + + internal NativeLibraryLoader(string libraryPath) + { + _libraryPath = libraryPath; + Handle = LoadLibrary(_libraryPath, out var errorMsg); + if (!String.IsNullOrEmpty(errorMsg)) + { + throw new BrotliException($"unable to load library {libraryPath}"); + } + } + + public static IntPtr GetWin32ModuleHandle(String moduleName) + { + IntPtr r = IntPtr.Zero; + foreach (ProcessModule mod in Process.GetCurrentProcess().Modules) + { + if (mod.ModuleName == moduleName) + { + r = mod.BaseAddress; + break; + } + } + return r; + } + + /// + /// Loads method in the library + /// + /// The methold of the library + /// method address + private IntPtr LoadSymbol(string symbolName) + { + if (IsWindows) + { + return WindowsLoader.GetProcAddress(Handle, symbolName); + } + if (IsLinux) + { + + if (IsNetCore) + { + return CoreCLRLoader.dlsym(Handle, symbolName); + } + return LinuxLoader.dlsym(Handle, symbolName); + } + if (IsMacOSX) + { + return MacOSXLoader.dlsym(Handle, symbolName); + } + throw new InvalidOperationException("Unsupported platform."); + } + + public void FillDelegate(out T delegateType) where T : class + { + var typeName = typeof(T).Name; + var kt = "Delegate"; + if (typeName.EndsWith(kt)) + { + typeName = typeName.Substring(0, typeName.Length - kt.Length); + } + delegateType = GetNativeMethodDelegate(typeName); + } + + + public T GetNativeMethodDelegate(string methodName) where T : class + { + var ptr = LoadSymbol(methodName); + if (ptr == IntPtr.Zero) + { + throw new MissingMethodException(string.Format("The native method \"{0}\" does not exist", methodName)); + } + + return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; // generic version not available in .NET45 + } + + internal static string[] GetPossibleRuntimeDirectories() + { +#if NET35 || NET40 + var assemblyDirectory = Path.GetDirectoryName(typeof(LibPathBootStrapper).Assembly.Location); +#else + var assemblyDirectory = Path.GetDirectoryName(typeof(LibPathBootStrapper).GetTypeInfo().Assembly.Location); +#endif + //var platform = "win"; + //if (IsLinux) + //{ + // platform= "linux"; + //} + //if (IsMacOSX) + //{ + // platform= "osx"; + //} + //string runtimesDirectory = string.Format("runtimes/{0}/native", platform); + string runtimesDirectory; + if (Is64Bit) + { + runtimesDirectory = "x64"; // string.Format("x64/{0}", platform); + } + else + { + runtimesDirectory = "x86"; // string.Format("x86/{0}", platform); + } + + string runtimesFullDirectory = Path.Combine(assemblyDirectory,runtimesDirectory); + var iisBaseDirectory = $"{AppDomain.CurrentDomain.BaseDirectory}bin/{runtimesDirectory}"; + var execAssemblyDirectory= System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\\","")+"/"+ runtimesDirectory; +#if NET35 + var netCoreAppStyleDirectory = Path.Combine(Path.Combine(assemblyDirectory, "../.."), runtimesDirectory); +#else + var netCoreAppStyleDirectory = Path.Combine(assemblyDirectory, "../..", runtimesDirectory); +#endif + string[] paths = new[] { assemblyDirectory, runtimesFullDirectory, runtimesDirectory, netCoreAppStyleDirectory,iisBaseDirectory,execAssemblyDirectory }; + paths = paths.Select(v => v.Replace('/', Path.DirectorySeparatorChar)).ToArray(); + return paths; + } + + internal static bool FreeLibrary(IntPtr handle) + { + string errorMsg = null; + if (IsWindows) + { + return WindowsLoader.FreeLibrary(handle); + } + if (IsLinux) + { + if (IsNetCore) + { + return UnloadLibraryPosix(CoreCLRLoader.dlclose, CoreCLRLoader.dlerror, handle, out errorMsg); + } + return UnloadLibraryPosix(LinuxLoader.dlclose, LinuxLoader.dlerror, handle, out errorMsg); + } + if (IsMacOSX) + { + return UnloadLibraryPosix(MacOSXLoader.dlclose, MacOSXLoader.dlerror, handle, out errorMsg); + } + throw new InvalidOperationException("Unsupported platform."); + } + + /// + /// Load library + /// + internal static IntPtr LoadLibrary(string libraryPath, out string errorMsg) + { + if (IsWindows) + { + errorMsg = null; + //var handle = GetWin32ModuleHandle(libraryPath); + //if (handle != IntPtr.Zero) return handle; + var handle= WindowsLoader.LoadLibrary(libraryPath); + if (handle== IntPtr.Zero) + { + throw new System.ComponentModel.Win32Exception($"failed to load library {libraryPath}"); + } + return handle; + } + if (IsLinux) + { + if (IsNetCore) + { + return LoadLibraryPosix(CoreCLRLoader.dlopen, CoreCLRLoader.dlerror, libraryPath, out errorMsg); + } + return LoadLibraryPosix(LinuxLoader.dlopen, LinuxLoader.dlerror, libraryPath, out errorMsg); + } + if (IsMacOSX) + { + return LoadLibraryPosix(MacOSXLoader.dlopen, MacOSXLoader.dlerror, libraryPath, out errorMsg); + } + throw new InvalidOperationException("Unsupported platform."); + } + + static IntPtr LoadLibraryPosix(Func dlopenFunc, Func dlerrorFunc, string libraryPath, out string errorMsg) + { + errorMsg = null; + IntPtr ret = dlopenFunc(libraryPath, RtldGlobal + RtldLazy); + if (ret == IntPtr.Zero) + { + errorMsg = Marshal.PtrToStringAnsi(dlerrorFunc()); + } + return ret; + } + + static bool UnloadLibraryPosix(Func dlcloseFunc, Func dlerrorFunc, IntPtr handle,out string errorMsg) + { + errorMsg = null; + var r = dlcloseFunc(handle); + if (r!=0) + { + errorMsg= Marshal.PtrToStringAnsi(dlerrorFunc()); + return false; + } + return true; + } + } +} diff --git a/Brotli.Core/Interop/NativeMethods.cs b/Brotli.Core/Interop/NativeMethods.cs new file mode 100644 index 0000000..378c0ee --- /dev/null +++ b/Brotli.Core/Interop/NativeMethods.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace Brotli +{ + + static class WindowsLoader + { + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + public static extern IntPtr LoadLibrary(string dllFilePath); + + [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); + + [DllImport("kernel32.dll")] + public static extern bool FreeLibrary(IntPtr hModule); + } + + static class LinuxLoader + { + [DllImport("libdl.so")] + internal static extern IntPtr dlopen(string filename, int flags); + + [DllImport("libdl.so")] + internal static extern IntPtr dlerror(); + + [DllImport("libdl.so")] + internal static extern IntPtr dlsym(IntPtr handle, string symbol); + + [DllImport("libdl.so")] + internal static extern int dlclose(IntPtr handle); + } + + static class MacOSXLoader + { + [DllImport("libSystem.dylib")] + internal static extern IntPtr dlopen(string filename, int flags); + + [DllImport("libSystem.dylib")] + internal static extern IntPtr dlerror(); + + [DllImport("libSystem.dylib")] + internal static extern IntPtr dlsym(IntPtr handle, string symbol); + + [DllImport("libSystem.dylib")] + internal static extern int dlclose(IntPtr handle); + + } + + + /// + /// Similarly as for Mono on Linux, we load symbols for + /// dlopen and dlsym from the "libcoreclr.so", + /// to avoid the dependency on libc-dev Linux. + /// + static class CoreCLRLoader + { + [DllImport("libcoreclr.so")] + internal static extern IntPtr dlopen(string filename, int flags); + + [DllImport("libcoreclr.so")] + internal static extern IntPtr dlerror(); + + [DllImport("libcoreclr.so")] + internal static extern IntPtr dlsym(IntPtr handle, string symbol); + + [DllImport("libcoreclr.so")] + internal static extern int dlclose(IntPtr handle); + } +} diff --git a/Brotli.Core/build/Brotli.NET.targets b/Brotli.Core/build/Brotli.NET.targets new file mode 100644 index 0000000..635eed9 --- /dev/null +++ b/Brotli.Core/build/Brotli.NET.targets @@ -0,0 +1,16 @@ + + + + + + %(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + + \ No newline at end of file diff --git a/Brotli.Core/runtimes/x64/brolib_x64.dll b/Brotli.Core/runtimes/x64/brolib_x64.dll new file mode 100644 index 0000000..60bea1f Binary files /dev/null and b/Brotli.Core/runtimes/x64/brolib_x64.dll differ diff --git a/Brotli.Core/runtimes/x86/brolib_x86.dll b/Brotli.Core/runtimes/x86/brolib_x86.dll new file mode 100644 index 0000000..071a7ce Binary files /dev/null and b/Brotli.Core/runtimes/x86/brolib_x86.dll differ diff --git a/DatabaseManager/App.xaml b/DatabaseManager/App.xaml new file mode 100644 index 0000000..9246bd5 --- /dev/null +++ b/DatabaseManager/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/DatabaseManager/App.xaml.cs b/DatabaseManager/App.xaml.cs new file mode 100644 index 0000000..cc373a3 --- /dev/null +++ b/DatabaseManager/App.xaml.cs @@ -0,0 +1,23 @@ +using DatabaseManager.Views; +using Prism.Ioc; +using System.Windows; + +namespace DatabaseManager +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App + { + protected override Window CreateShell() + { + return Container.Resolve(); + } + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterForNavigation("Cover"); + containerRegistry.RegisterForNavigation("Header"); + } + } +} diff --git a/DatabaseManager/DatabaseManager.csproj b/DatabaseManager/DatabaseManager.csproj new file mode 100644 index 0000000..da46220 --- /dev/null +++ b/DatabaseManager/DatabaseManager.csproj @@ -0,0 +1,126 @@ + + + + + Debug + AnyCPU + {95F12C16-86B5-43D5-AF3E-D2489E2DB239} + WinExe + Properties + DatabaseManager + DatabaseManager + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + PackageReference + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + + + ViewCover.xaml + + + ViewHeader.xaml + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + MainWindow.xaml + Code + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + 1.0.112.2 + + + + + {4fde0364-f65b-4812-bfe8-34e886624fbd} + DownKyi.Core + + + + \ No newline at end of file diff --git a/DatabaseManager/Models/CoverModel.cs b/DatabaseManager/Models/CoverModel.cs new file mode 100644 index 0000000..deb9311 --- /dev/null +++ b/DatabaseManager/Models/CoverModel.cs @@ -0,0 +1,47 @@ +namespace DatabaseManager.Models +{ + public class CoverModel + { + public long Avid { get; set; } + public string Bvid { get; set; } + public long Cid { get; set; } + public string Url { get; set; } + public string Md5 { get; set; } + + + //private long avid; + //public long Avid + //{ + // get { return avid; } + // set { SetProperty(ref avid, value); } + //} + + //private string bvid; + //public string Bvid + //{ + // get { return bvid; } + // set { SetProperty(ref bvid, value); } + //} + + //private long cid; + //public long Cid + //{ + // get { return cid; } + // set { SetProperty(ref cid, value); } + //} + + //private string url; + //public string Url + //{ + // get { return url; } + // set { SetProperty(ref url, value); } + //} + + //private string md5; + //public string Md5 + //{ + // get { return md5; } + // set { SetProperty(ref md5, value); } + //} + } +} diff --git a/DatabaseManager/Properties/AssemblyInfo.cs b/DatabaseManager/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..debcf6f --- /dev/null +++ b/DatabaseManager/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DatabaseManager")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DatabaseManager")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DatabaseManager/Properties/Resources.Designer.cs b/DatabaseManager/Properties/Resources.Designer.cs new file mode 100644 index 0000000..80a911c --- /dev/null +++ b/DatabaseManager/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DatabaseManager.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DatabaseManager.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/DatabaseManager/Properties/Resources.resx b/DatabaseManager/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/DatabaseManager/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/DatabaseManager/Properties/Settings.Designer.cs b/DatabaseManager/Properties/Settings.Designer.cs new file mode 100644 index 0000000..87d56f9 --- /dev/null +++ b/DatabaseManager/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DatabaseManager.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/DatabaseManager/Properties/Settings.settings b/DatabaseManager/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/DatabaseManager/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/DatabaseManager/ViewModels/MainWindowViewModel.cs b/DatabaseManager/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..3a72c67 --- /dev/null +++ b/DatabaseManager/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,47 @@ +using Prism.Commands; +using Prism.Mvvm; +using Prism.Regions; + +namespace DatabaseManager.ViewModels +{ + public class MainWindowViewModel : BindableBase + { + private readonly IRegionManager regionManager; + + + private string _title = "DatabaseManager"; + public string Title + { + get { return _title; } + set { SetProperty(ref _title, value); } + } + + public MainWindowViewModel(IRegionManager regionManager) + { + this.regionManager = regionManager; + } + + + + private DelegateCommand coverCommand; + public DelegateCommand CoverCommand => coverCommand ?? (coverCommand = new DelegateCommand(ExecuteCoverCommand)); + + private void ExecuteCoverCommand() + { + regionManager.RequestNavigate("ContentRegion", "Cover"); + } + + private DelegateCommand headerCommand; + public DelegateCommand HeaderCommand => headerCommand ?? (headerCommand = new DelegateCommand(ExecuteHeaderCommand)); + + private void ExecuteHeaderCommand() + { + regionManager.RequestNavigate("ContentRegion", "Header"); + } + + + + + + } +} diff --git a/DatabaseManager/ViewModels/ViewCoverViewModel.cs b/DatabaseManager/ViewModels/ViewCoverViewModel.cs new file mode 100644 index 0000000..9a0fc9d --- /dev/null +++ b/DatabaseManager/ViewModels/ViewCoverViewModel.cs @@ -0,0 +1,66 @@ +using DownKyi.Core.Storage.Database; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using System.Windows; + +namespace DatabaseManager.ViewModels +{ + public class ViewCoverViewModel : BindableBase, INavigationAware + { + private ObservableCollection coverList; + public ObservableCollection CoverList + { + get { return coverList; } + set { SetProperty(ref coverList, value); } + } + + public ViewCoverViewModel() + { + CoverList = new ObservableCollection(); + } + + public async void OnNavigatedTo(NavigationContext navigationContext) + { + await Task.Run(() => + { + CoverDb coverDb = new CoverDb(); + var covers = coverDb.QueryAll(); + if (covers == null) + { + return; + } + + Application.Current.Dispatcher.Invoke(new Action(() => + { + CoverList.Clear(); + foreach (var cover in covers) + { + //CoverModel newCover = new CoverModel + //{ + // Avid = cover.Avid, + // Bvid = cover.Bvid, + // Cid = cover.Cid, + // Url = cover.Url, + // Md5 = cover.Md5 + //}; + + CoverList.Add(cover); + } + })); + + }); + } + + public bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + public void OnNavigatedFrom(NavigationContext navigationContext) + { + } + } +} diff --git a/DatabaseManager/ViewModels/ViewHeaderViewModel.cs b/DatabaseManager/ViewModels/ViewHeaderViewModel.cs new file mode 100644 index 0000000..da95b8a --- /dev/null +++ b/DatabaseManager/ViewModels/ViewHeaderViewModel.cs @@ -0,0 +1,57 @@ +using DownKyi.Core.Storage.Database; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using System.Windows; + +namespace DatabaseManager.ViewModels +{ + public class ViewHeaderViewModel : BindableBase, INavigationAware + { + private ObservableCollection
headerList; + public ObservableCollection
HeaderList + { + get { return headerList; } + set { SetProperty(ref headerList, value); } + } + + public ViewHeaderViewModel() + { + HeaderList = new ObservableCollection
(); + } + + public bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + public void OnNavigatedFrom(NavigationContext navigationContext) + { + } + + public async void OnNavigatedTo(NavigationContext navigationContext) + { + await Task.Run(() => + { + HeaderDb headerDb = new HeaderDb(); + var headers = headerDb.QueryAll(); + if (headers == null) + { + return; + } + + Application.Current.Dispatcher.Invoke(new Action(() => + { + HeaderList.Clear(); + foreach (var cover in headers) + { + HeaderList.Add(cover); + } + })); + + }); + } + } +} diff --git a/DatabaseManager/Views/MainWindow.xaml b/DatabaseManager/Views/MainWindow.xaml new file mode 100644 index 0000000..c3a3ae2 --- /dev/null +++ b/DatabaseManager/Views/MainWindow.xaml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DatabaseManager/Views/MainWindow.xaml.cs b/DatabaseManager/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..2d04dd0 --- /dev/null +++ b/DatabaseManager/Views/MainWindow.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows; + +namespace DatabaseManager.Views +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} diff --git a/DatabaseManager/Views/ViewCover.xaml b/DatabaseManager/Views/ViewCover.xaml new file mode 100644 index 0000000..54545ff --- /dev/null +++ b/DatabaseManager/Views/ViewCover.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/DatabaseManager/Views/ViewCover.xaml.cs b/DatabaseManager/Views/ViewCover.xaml.cs new file mode 100644 index 0000000..b717b45 --- /dev/null +++ b/DatabaseManager/Views/ViewCover.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DatabaseManager.Views +{ + /// + /// Interaction logic for ViewCover + /// + public partial class ViewCover : UserControl + { + public ViewCover() + { + InitializeComponent(); + } + } +} diff --git a/DatabaseManager/Views/ViewHeader.xaml b/DatabaseManager/Views/ViewHeader.xaml new file mode 100644 index 0000000..d86dd17 --- /dev/null +++ b/DatabaseManager/Views/ViewHeader.xaml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + diff --git a/DatabaseManager/Views/ViewHeader.xaml.cs b/DatabaseManager/Views/ViewHeader.xaml.cs new file mode 100644 index 0000000..67e645c --- /dev/null +++ b/DatabaseManager/Views/ViewHeader.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DatabaseManager.Views +{ + /// + /// Interaction logic for ViewHeader + /// + public partial class ViewHeader : UserControl + { + public ViewHeader() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi.Core.Test/BiliApi/Video/DynamicTest.cs b/DownKyi.Core.Test/BiliApi/Video/DynamicTest.cs new file mode 100644 index 0000000..0706cc9 --- /dev/null +++ b/DownKyi.Core.Test/BiliApi/Video/DynamicTest.cs @@ -0,0 +1,35 @@ +using DownKyi.Core.BiliApi.Video; +using DownKyi.Core.BiliApi.Video.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.Test.BiliApi.Video +{ + [TestClass] + public class DynamicTest + { + // 主分区tid + private readonly int[] typeIdList = { 1, 13, 167, 3, 129, 4, 36, 234, 223, 160, 211, 217, 119, 155, 5, 181, 177, 23, 11 }; + + [TestMethod] + public void TestRegionDynamicList() + { + foreach (var tid in typeIdList) + { + var time = DateTime.Now; + Random random = new Random(time.GetHashCode()); + int ps = random.Next(1, 51); + + var regionDynamicList = Dynamic.RegionDynamicList(tid, 1, ps); + + Assert.IsInstanceOfType(regionDynamicList, typeof(List)); + Assert.IsInstanceOfType(regionDynamicList[0], typeof(DynamicVideoView)); + Assert.IsNotNull(regionDynamicList[0]); + + Assert.AreEqual(regionDynamicList.Count, ps); + + } + } + } +} diff --git a/DownKyi.Core.Test/BiliApi/Video/RankingTest.cs b/DownKyi.Core.Test/BiliApi/Video/RankingTest.cs new file mode 100644 index 0000000..9c7128b --- /dev/null +++ b/DownKyi.Core.Test/BiliApi/Video/RankingTest.cs @@ -0,0 +1,34 @@ +using DownKyi.Core.BiliApi.Video; +using DownKyi.Core.BiliApi.Video.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; + +namespace DownKyi.Core.Test.BiliApi.Video +{ + [TestClass] + public class RankingTest + { + // 主分区tid + private readonly int[] typeIdList = { 1, 13, 167, 3, 129, 4, 36, 234, 223, 160, 211, 217, 119, 155, 5, 181, 177, 23, 11 }; + + [TestMethod] + public void TestRegionRankingList() + { + + foreach (var tid in typeIdList) + { + var regionRankingList = Ranking.RegionRankingList(tid, 3); + + Assert.IsInstanceOfType(regionRankingList, typeof(List)); + Assert.IsInstanceOfType(regionRankingList[0], typeof(RankingVideoView)); + Assert.IsNotNull(regionRankingList[0]); + + regionRankingList = Ranking.RegionRankingList(tid, 7); + + Assert.IsInstanceOfType(regionRankingList, typeof(List)); + Assert.IsInstanceOfType(regionRankingList[0], typeof(RankingVideoView)); + Assert.IsNotNull(regionRankingList[0]); + } + } + } +} diff --git a/DownKyi.Core.Test/BiliApi/Video/VideoInfoTest.cs b/DownKyi.Core.Test/BiliApi/Video/VideoInfoTest.cs new file mode 100644 index 0000000..b6f8542 --- /dev/null +++ b/DownKyi.Core.Test/BiliApi/Video/VideoInfoTest.cs @@ -0,0 +1,42 @@ +using DownKyi.Core.BiliApi.Video; +using DownKyi.Core.BiliApi.Video.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DownKyi.Core.Test.BiliApi.Video +{ + [TestClass] + public class VideoInfoTest + { + // 主分区tid + private readonly int[] typeIdList = { 1, 13, 167, 3, 129, 4, 36, 234, 223, 160, 211, 217, 119, 155, 5, 181, 177, 23, 11 }; + + [TestMethod] + public void TestVideoViewInfo() + { + foreach (var tid in typeIdList) + { + var regionDynamicList = Dynamic.RegionDynamicList(tid, 1, 12); + Assert.IsNotNull(regionDynamicList); + + foreach (var videoView in regionDynamicList) + { + long aid = videoView.Aid; + string bvid = videoView.Bvid; + + var bv = VideoInfo.VideoViewInfo(bvid, -1); + Assert.IsNotNull(bv); + Assert.IsInstanceOfType(bv, typeof(VideoView)); + Assert.IsNotNull(bv.Pages); + + var av = VideoInfo.VideoViewInfo(null, aid); + Assert.IsNotNull(av); + Assert.IsInstanceOfType(av, typeof(VideoView)); + Assert.IsNotNull(av.Pages); + + } + + } + + } + } +} diff --git a/DownKyi.Core.Test/DownKyi.Core.Test.csproj b/DownKyi.Core.Test/DownKyi.Core.Test.csproj new file mode 100644 index 0000000..355c91e --- /dev/null +++ b/DownKyi.Core.Test/DownKyi.Core.Test.csproj @@ -0,0 +1,78 @@ + + + + + + Debug + AnyCPU + {81B9719E-DA29-444F-BB72-CBD5819A654D} + Library + Properties + DownKyi.Core.Test + DownKyi.Core.Test + v4.7.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + + + {4fde0364-f65b-4812-bfe8-34e886624fbd} + DownKyi.Core + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + \ No newline at end of file diff --git a/DownKyi.Core.Test/Properties/AssemblyInfo.cs b/DownKyi.Core.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5ed6f79 --- /dev/null +++ b/DownKyi.Core.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("DownKyi.Core.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DownKyi.Core.Test")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("81b9719e-da29-444f-bb72-cbd5819a654d")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/DownKyi.Core.Test/Test/UnitTest1.cs b/DownKyi.Core.Test/Test/UnitTest1.cs new file mode 100644 index 0000000..f29ef6e --- /dev/null +++ b/DownKyi.Core.Test/Test/UnitTest1.cs @@ -0,0 +1,35 @@ +using DownKyi.Core.BiliApi.Danmaku; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Net; + +namespace DownKyi.Core.Test.Test +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + string url = "https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=421769791&pid=420986799&segment_index=1"; + string localFile = @"C:\Users\FlySelf\Desktop\test.proto"; + WebClient mywebclient = new WebClient(); + mywebclient.DownloadFile(url, localFile); + + } + + [TestMethod] + public void TestMethod2() + { + var danmakus = DanmakuProtobuf.GetAllDanmakuProto(420986799, 421769791); + + Console.WriteLine(danmakus.Count); + + foreach (var dan in danmakus) + { + Console.WriteLine(dan.ToString()); + } + } + + } +} diff --git a/DownKyi.Core.Test/app.config b/DownKyi.Core.Test/app.config new file mode 100644 index 0000000..20ad174 --- /dev/null +++ b/DownKyi.Core.Test/app.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi.Core.Test/packages.config b/DownKyi.Core.Test/packages.config new file mode 100644 index 0000000..7079f81 --- /dev/null +++ b/DownKyi.Core.Test/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/DownKyi.Core/Aria2cNet/AriaManager.cs b/DownKyi.Core/Aria2cNet/AriaManager.cs new file mode 100644 index 0000000..b2a8d45 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/AriaManager.cs @@ -0,0 +1,120 @@ +using DownKyi.Core.Aria2cNet.Client; +using DownKyi.Core.Logging; +using System.Threading; + +namespace DownKyi.Core.Aria2cNet +{ + public class AriaManager + { + // gid对应项目的状态 + public delegate void TellStatusHandler(long totalLength, long completedLength, long speed, string gid); + public event TellStatusHandler TellStatus; + protected virtual void OnTellStatus(long totalLength, long completedLength, long speed, string gid) + { + TellStatus?.Invoke(totalLength, completedLength, speed, gid); + } + + // 下载结果回调 + public delegate void DownloadFinishHandler(bool isSuccess, string downloadPath, string gid, string msg = null); + public event DownloadFinishHandler DownloadFinish; + protected virtual void OnDownloadFinish(bool isSuccess, string downloadPath, string gid, string msg = null) + { + DownloadFinish?.Invoke(isSuccess, downloadPath, gid, msg); + } + + // 全局下载状态 + public delegate void GetGlobalStatusHandler(long speed); + public event GetGlobalStatusHandler GlobalStatus; + protected virtual void OnGlobalStatus(long speed) + { + GlobalStatus?.Invoke(speed); + } + + /// + /// 获取gid下载项的状态 + /// + /// + /// + public DownloadStatus GetDownloadStatus(string gid) + { + string filePath = ""; + while (true) + { + var status = AriaClient.TellStatus(gid); + if (status == null || status.Result == null) { continue; } + + if (status.Result.Result == null && status.Result.Error != null) + { + if (status.Result.Error.Message.Contains("is not found")) + { + OnDownloadFinish(false, null, gid, status.Result.Error.Message); + return DownloadStatus.ABORT; + } + } + + if (status.Result.Result.Files != null && status.Result.Result.Files.Count >= 1) + { + filePath = status.Result.Result.Files[0].Path; + } + + long totalLength = long.Parse(status.Result.Result.TotalLength); + long completedLength = long.Parse(status.Result.Result.CompletedLength); + long speed = long.Parse(status.Result.Result.DownloadSpeed); + // 回调 + OnTellStatus(totalLength, completedLength, speed, gid); + + if (status.Result.Result.Status == "complete") + { + break; + } + if (status.Result.Result.ErrorCode != null && status.Result.Result.ErrorCode != "0") + { + Utils.Debug.Console.PrintLine("ErrorMessage: " + status.Result.Result.ErrorMessage); + LogManager.Error("AriaManager", status.Result.Result.ErrorMessage); + + //// 如果返回状态码不是200,则继续 + //if (status.Result.Result.ErrorMessage.Contains("The response status is not successful")) + //{ + // Thread.Sleep(1000); + // continue; + //} + + // aira中删除记录 + var ariaRemove1 = AriaClient.RemoveDownloadResultAsync(gid); + Utils.Debug.Console.PrintLine(ariaRemove1); + LogManager.Debug("AriaManager", ariaRemove1.Result.Result); + + // 返回回调信息,退出函数 + OnDownloadFinish(false, null, gid, status.Result.Result.ErrorMessage); + return DownloadStatus.FAILED; + } + + // 降低CPU占用 + Thread.Sleep(100); + } + OnDownloadFinish(true, filePath, gid, null); + return DownloadStatus.SUCCESS; + } + + /// + /// 获取全局下载速度 + /// + public async void GetGlobalStatus() + { + while (true) + { + // 查询全局status + var globalStatus = await AriaClient.GetGlobalStatAsync(); + if (globalStatus == null || globalStatus.Result == null) { continue; } + + long globalSpeed = long.Parse(globalStatus.Result.DownloadSpeed); + // 回调 + OnGlobalStatus(globalSpeed); + + // 降低CPU占用 + Thread.Sleep(100); + } + } + + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/AriaClient.cs b/DownKyi.Core/Aria2cNet/Client/AriaClient.cs new file mode 100644 index 0000000..ee7f287 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/AriaClient.cs @@ -0,0 +1,1130 @@ +using DownKyi.Core.Aria2cNet.Client.Entity; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace DownKyi.Core.Aria2cNet.Client +{ + /// + /// http://aria2.github.io/manual/en/html/aria2c.html#methods + /// + public static class AriaClient + { + private static readonly string JSONRPC = "2.0"; + private static readonly string TOKEN = "downkyi"; + + /// + /// This method adds a new download. + /// uris is an array of HTTP/FTP/SFTP/BitTorrent URIs (strings) pointing to the same resource. + /// If you mix URIs pointing to different resources, + /// then the download may fail or be corrupted without aria2 complaining. + /// When adding BitTorrent Magnet URIs, + /// uris must have only one element and it should be BitTorrent Magnet URI. + /// options is a struct and its members are pairs of option name and value. + /// See Options below for more details. + /// If position is given, it must be an integer starting from 0. + /// The new download will be inserted at position in the waiting queue. + /// If position is omitted or position is larger than the current size of the queue, + /// the new download is appended to the end of the queue. + /// This method returns the GID of the newly registered download. + /// + /// + /// + /// + /// + public static async Task AddUriAsync(List uris, AriaSendOption option, int position = -1) + { + List ariaParams = new List + { + "token:" + TOKEN, + uris, + option + }; + if (position > -1) + { + ariaParams.Add(position); + } + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.addUri", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method adds a BitTorrent download by uploading a ".torrent" file. + /// If you want to add a BitTorrent Magnet URI, use the aria2.addUri() method instead. + /// torrent must be a base64-encoded string containing the contents of the ".torrent" file. + /// uris is an array of URIs (string). + /// uris is used for Web-seeding. + /// For single file torrents, the URI can be a complete URI pointing to the resource; + /// if URI ends with /, name in torrent file is added. + /// For multi-file torrents, name and path in torrent are added to form a URI for each file. + /// options is a struct and its members are pairs of option name and value. + /// See Options below for more details. + /// If position is given, it must be an integer starting from 0. + /// The new download will be inserted at position in the waiting queue. + /// If position is omitted or position is larger than the current size of the queue, + /// the new download is appended to the end of the queue. + /// This method returns the GID of the newly registered download. + /// If --rpc-save-upload-metadata is true, + /// the uploaded data is saved as a file named as the hex string of SHA-1 hash of data plus ".torrent" in the directory specified by --dir option. + /// E.g. a file name might be 0a3893293e27ac0490424c06de4d09242215f0a6.torrent. + /// If a file with the same name already exists, it is overwritten! + /// If the file cannot be saved successfully or --rpc-save-upload-metadata is false, + /// the downloads added by this method are not saved by --save-session. + /// + /// + /// + /// + /// + public static async Task AddTorrentAsync(string torrent, List uris, AriaSendOption option, int position = -1) + { + List ariaParams = new List + { + "token:" + TOKEN, + torrent, + uris, + option + }; + if (position > -1) + { + ariaParams.Add(position); + } + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.addTorrent", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method adds a Metalink download by uploading a ".metalink" file. + /// metalink is a base64-encoded string which contains the contents of the ".metalink" file. + /// options is a struct and its members are pairs of option name and value. + /// See Options below for more details. + /// If position is given, it must be an integer starting from 0. + /// The new download will be inserted at position in the waiting queue. + /// If position is omitted or position is larger than the current size of the queue, + /// the new download is appended to the end of the queue. + /// This method returns an array of GIDs of newly registered downloads. + /// If --rpc-save-upload-metadata is true, + /// the uploaded data is saved as a file named hex string of SHA-1 hash of data plus ".metalink" in the directory specified by --dir option. + /// E.g. a file name might be 0a3893293e27ac0490424c06de4d09242215f0a6.metalink. + /// If a file with the same name already exists, it is overwritten! + /// If the file cannot be saved successfully or --rpc-save-upload-metadata is false, + /// the downloads added by this method are not saved by --save-session. + /// + /// + /// + /// + /// + public static async Task AddMetalinkAsync(string metalink, List uris, AriaSendOption option, int position = -1) + { + List ariaParams = new List + { + "token:" + TOKEN, + metalink, + uris, + option + }; + if (position > -1) + { + ariaParams.Add(position); + } + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.addMetalink", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method removes the download denoted by gid (string). + /// If the specified download is in progress, it is first stopped. + /// The status of the removed download becomes removed. + /// This method returns GID of removed download. + /// + /// + /// + public static async Task RemoveAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.remove", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method removes the download denoted by gid. + /// This method behaves just like aria2.remove() + /// except that this method removes the download without performing any actions which take time, + /// such as contacting BitTorrent trackers to unregister the download first. + /// + /// + /// + public static async Task ForceRemoveAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.forceRemove", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method pauses the download denoted by gid (string). + /// The status of paused download becomes paused. + /// If the download was active, the download is placed in the front of waiting queue. + /// While the status is paused, the download is not started. + /// To change status to waiting, use the aria2.unpause() method. + /// This method returns GID of paused download. + /// + /// + /// + public static async Task PauseAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.pause", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method is equal to calling aria2.pause() for every active/waiting download. + /// This methods returns OK. + /// + /// + public static async Task PauseAllAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.pauseAll", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method pauses the download denoted by gid. + /// This method behaves just like aria2.pause() + /// except that this method pauses downloads without performing any actions which take time, + /// such as contacting BitTorrent trackers to unregister the download first. + /// + /// + /// + public static async Task ForcePauseAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.forcePause", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method is equal to calling aria2.forcePause() for every active/waiting download. + /// This methods returns OK. + /// + /// + public static async Task ForcePauseAllAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.forcePauseAll", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method changes the status of the download denoted by gid (string) from paused to waiting, + /// making the download eligible to be restarted. + /// This method returns the GID of the unpaused download. + /// + /// + /// + public static async Task UnpauseAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.unpause", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method is equal to calling aria2.unpause() for every paused download. + /// This methods returns OK. + /// + /// + public static async Task UnpauseAllAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.unpauseAll", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns the progress of the download denoted by gid (string). + /// keys is an array of strings. + /// If specified, the response contains only keys in the keys array. + /// If keys is empty or omitted, the response contains all keys. + /// This is useful when you just want specific keys and avoid unnecessary transfers. + /// For example, aria2.tellStatus("2089b05ecca3d829", ["gid", "status"]) returns the gid and status keys only. + /// The response is a struct and contains following keys. Values are strings. + /// + /// + /// + public static async Task TellStatus(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.tellStatus", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns the URIs used in the download denoted by gid (string). + /// The response is an array of structs and it contains following keys. + /// Values are string. + /// + /// + /// + public static async Task GetUrisAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getUris", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns the file list of the download denoted by gid (string). + /// The response is an array of structs which contain following keys. + /// Values are strings. + /// + /// + /// + public static async Task GetFilesAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getFiles", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns a list peers of the download denoted by gid (string). + /// This method is for BitTorrent only. + /// The response is an array of structs and contains the following keys. + /// Values are strings. + /// + /// + /// + public static async Task GetPeersAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getPeers", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns currently connected HTTP(S)/FTP/SFTP servers of the download denoted by gid (string). + /// The response is an array of structs and contains the following keys. + /// Values are strings. + /// + /// + /// + public static async Task GetServersAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getServers", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns a list of active downloads. + /// The response is an array of the same structs as returned by the aria2.tellStatus() method. + /// For the keys parameter, please refer to the aria2.tellStatus() method. + /// + /// + public static async Task TellActiveAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.tellActive", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns a list of waiting downloads, including paused ones. + /// offset is an integer and specifies the offset from the download waiting at the front. + /// num is an integer and specifies the max. + /// number of downloads to be returned. + /// For the keys parameter, please refer to the aria2.tellStatus() method. + ///

+ /// If offset is a positive integer, + /// this method returns downloads in the range of [offset, offset + num). + ///

+ /// offset can be a negative integer. + /// offset == -1 points last download in the waiting queue and offset == -2 points the download before the last download, and so on. + /// Downloads in the response are in reversed order then. + ///

+ /// For example, imagine three downloads "A","B" and "C" are waiting in this order. + /// aria2.tellWaiting(0, 1) returns ["A"]. + /// aria2.tellWaiting(1, 2) returns ["B", "C"]. + /// aria2.tellWaiting(-1, 2) returns ["C", "B"]. + ///

+ /// The response is an array of the same structs as returned by aria2.tellStatus() method. + ///
+ /// + /// + /// + public static async Task TellWaitingAsync(int offset, int num) + { + List ariaParams = new List + { + "token:" + TOKEN, + offset, + num + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.tellWaiting", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns a list of stopped downloads. + /// offset is an integer and specifies the offset from the least recently stopped download. + /// num is an integer and specifies the max. + /// number of downloads to be returned. + /// For the keys parameter, please refer to the aria2.tellStatus() method. + ///

+ /// offset and num have the same semantics as described in the aria2.tellWaiting() method. + ///

+ /// The response is an array of the same structs as returned by the aria2.tellStatus() method. + ///
+ /// + /// + /// + public static async Task TellStoppedAsync(int offset, int num) + { + List ariaParams = new List + { + "token:" + TOKEN, + offset, + num + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.tellStopped", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method changes the position of the download denoted by gid in the queue. + /// pos is an integer. + /// how is a string. + /// If how is POS_SET, it moves the download to a position relative to the beginning of the queue. + /// If how is POS_CUR, it moves the download to a position relative to the current position. + /// If how is POS_END, it moves the download to a position relative to the end of the queue. + /// If the destination position is less than 0 or beyond the end of the queue, + /// it moves the download to the beginning or the end of the queue respectively. + /// The response is an integer denoting the resulting position. + /// + /// For example, if GID#2089b05ecca3d829 is currently in position 3, + /// aria2.changePosition('2089b05ecca3d829', -1, 'POS_CUR') will change its position to 2. + /// Additionally aria2.changePosition('2089b05ecca3d829', 0, 'POS_SET') will change its position to 0 (the beginning of the queue). + /// + /// The following examples move the download GID#2089b05ecca3d829 to the front of the queue. + /// + /// + /// + /// + /// + public static async Task ChangePositionAsync(string gid, int pos, HowChangePosition how) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid, + pos, + how.ToString("G") + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.changePosition", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method removes the URIs in delUris from and appends the URIs in addUris to download denoted by gid. + /// delUris and addUris are lists of strings. + /// A download can contain multiple files and URIs are attached to each file. + /// fileIndex is used to select which file to remove/attach given URIs. + /// fileIndex is 1-based. + /// position is used to specify where URIs are inserted in the existing waiting URI list. + /// position is 0-based. + /// When position is omitted, URIs are appended to the back of the list. + /// This method first executes the removal and then the addition. + /// position is the position after URIs are removed, not the position when this method is called. + /// When removing an URI, if the same URIs exist in download, + /// only one of them is removed for each URI in delUris. + /// In other words, + /// if there are three URIs http://example.org/aria2 and you want remove them all, + /// you have to specify (at least) 3 http://example.org/aria2 in delUris. + /// This method returns a list which contains two integers. + /// The first integer is the number of URIs deleted. The second integer is the number of URIs added. + /// + /// + /// + /// + /// + /// + /// + public static async Task ChangeUriAsync(string gid, int fileIndex, List delUris, List addUris, int position = -1) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid, + fileIndex, + delUris, + addUris + }; + if (position > -1) + { + ariaParams.Add(position); + } + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.changePosition", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns options of the download denoted by gid. + /// The response is a struct where keys are the names of options. + /// The values are strings. + /// Note that this method does not return options which have no default value and have not been set on the command-line, + /// in configuration files or RPC methods. + /// + /// + /// + public static async Task GetOptionAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getOption", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method changes options of the download denoted by gid (string) dynamically. + /// options is a struct. + /// The options listed in Input File subsection are available, except for following options: + ///
+ /// dry-run metalink-base-uri parameterized-uri pause piece-length rpc-save-upload-metadata + ///
+ /// Except for the following options, + /// changing the other options of active download makes it restart + /// (restart itself is managed by aria2, and no user intervention is required): + ///
+ /// bt-max-peers bt-request-peer-speed-limit bt-remove-unselected-file force-save max-download-limit max-upload-limit + ///
+ /// This method returns OK for success. + ///
+ /// + /// + /// + public static async Task ChangeOptionAsync(string gid, object option) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid, + option + }; + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.changeOption", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns the global options. + /// The response is a struct. + /// Its keys are the names of options. + /// Values are strings. + /// Note that this method does not return options which have no default value and have not been set on the command-line, + /// in configuration files or RPC methods. + /// Because global options are used as a template for the options of newly added downloads, + /// the response contains keys returned by the aria2.getOption() method. + /// + /// + public static async Task GetGlobalOptionAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getGlobalOption", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method changes global options dynamically. + /// options is a struct. + /// The following options are available: + ///
+ /// bt-max-open-files download-result keep-unfinished-download-result log log-level + /// max-concurrent-downloads max-download-result max-overall-download-limit max-overall-upload-limit + /// optimize-concurrent-downloads save-cookies save-session server-stat-of + ///
+ /// In addition, options listed in the Input File subsection are available, + /// except for following options: checksum, index-out, out, pause and select-file. + /// With the log option, you can dynamically start logging or change log file. + /// To stop logging, specify an empty string("") as the parameter value. + /// Note that log file is always opened in append mode. + /// This method returns OK for success. + ///
+ /// + /// + public static async Task ChangeGlobalOptionAsync(object option) + { + List ariaParams = new List + { + "token:" + TOKEN, + option + }; + + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.changeGlobalOption", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns global statistics such as the overall download and upload speeds. + /// The response is a struct and contains the following keys. Values are strings. + /// + /// + public static async Task GetGlobalStatAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getGlobalStat", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method purges completed/error/removed downloads to free memory. + /// This method returns OK. + /// + /// + public static async Task PurgeDownloadResultAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.purgeDownloadResult", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method removes a completed/error/removed download denoted by gid from memory. + /// This method returns OK for success. + /// + /// + /// + public static async Task RemoveDownloadResultAsync(string gid) + { + List ariaParams = new List + { + "token:" + TOKEN, + gid + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.removeDownloadResult", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns the version of aria2 and the list of enabled features. + /// The response is a struct and contains following keys. + /// + /// + public static async Task GetAriaVersionAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getVersion", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns session information. + /// The response is a struct and contains following key. + ///

+ /// Session ID, which is generated each time when aria2 is invoked. + ///
+ /// + public static async Task GetSessionInfoAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.getSessionInfo", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method shuts down aria2. + /// This method returns OK. + /// + /// + public static async Task ShutdownAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.shutdown", + Params = ariaParams + }; + var re = await GetRpcResponseAsync(ariaSend); + return re; + } + + /// + /// This method shuts down aria2(). + /// This method behaves like :func:'aria2.shutdown` without performing any actions which take time, + /// such as contacting BitTorrent trackers to unregister downloads first. + /// This method returns OK. + /// + /// + public static async Task ForceShutdownAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.forceShutdown", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method saves the current session to a file specified by the --save-session option. + /// This method returns OK if it succeeds. + /// + /// + public static async Task SaveSessionAsync() + { + List ariaParams = new List + { + "token:" + TOKEN + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "aria2.saveSession", + Params = ariaParams + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This methods encapsulates multiple method calls in a single request. + /// methods is an array of structs. The structs contain two keys: methodName and params. + /// methodName is the method name to call and params is array containing parameters to the method call. + /// This method returns an array of responses. + /// The elements will be either a one-item array containing the return value of the method call or a struct of fault element if an encapsulated method call fails. + /// + /// + /// + public static async Task> MulticallAsync(List systemMulticallMathods) + { + List ariaParams = new List + { + systemMulticallMathods + }; + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "system.multicall", + Params = ariaParams + }; + return await GetRpcResponseAsync>(ariaSend); + } + + /// + /// This method returns all the available RPC methods in an array of string. + /// Unlike other methods, this method does not require secret token. + /// This is safe because this method just returns the available method names. + /// + /// + public static async Task ListMethodsAsync() + { + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "system.listMethods" + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// This method returns all the available RPC notifications in an array of string. + /// Unlike other methods, this method does not require secret token. + /// This is safe because this method just returns the available notifications names. + /// + /// + public static async Task ListNotificationsAsync() + { + AriaSendData ariaSend = new AriaSendData + { + Id = Guid.NewGuid().ToString("N"), + Jsonrpc = JSONRPC, + Method = "system.listNotifications" + }; + return await GetRpcResponseAsync(ariaSend); + } + + /// + /// 获取jsonrpc的地址 + /// + /// + private static string GetRpcUri(int listenPort = 6800) + { + return $"http://localhost:{listenPort}/jsonrpc"; + } + + /// + /// 发送http请求,并将返回的json反序列化 + /// + /// + /// + /// + private async static Task GetRpcResponseAsync(AriaSendData ariaSend) + { + // 去掉null + var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + // 转换为json字符串 + string sendJson = JsonConvert.SerializeObject(ariaSend, Formatting.Indented, jsonSetting); + // 向服务器请求数据 + string result = string.Empty; + await Task.Run(() => + { + result = Request(GetRpcUri(), sendJson); + }); + if (result == null) { return default; } + + // 反序列化 + var aria = JsonConvert.DeserializeObject(result); + return aria; + } + + /// + /// http请求 + /// + /// + /// + /// + /// + private static string Request(string url, string parameters, int retry = 3) + { + // 重试次数 + if (retry <= 0) { return null; } + + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "POST"; + request.Timeout = 5 * 1000; + request.ContentType = "application/json"; + byte[] postData = Encoding.UTF8.GetBytes(parameters); + request.ContentLength = postData.Length; + using (Stream reqStream = request.GetRequestStream()) + { + reqStream.Write(postData, 0, postData.Length); + reqStream.Close(); + } + + string html = string.Empty; + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + { + using (Stream stream = response.GetResponseStream()) + { + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + html = reader.ReadToEnd(); + } + } + } + return html; + } + catch (WebException e) + { + Utils.Debug.Console.PrintLine("Request()发生Web异常: {0}", e); + LogManager.Error("AriaClient", e); + //return Request(url, parameters, retry - 1); + + string html = string.Empty; + var response = (HttpWebResponse)e.Response; + if (response == null) { return null; } + using (Stream stream = response.GetResponseStream()) + { + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + html = reader.ReadToEnd(); + } + } + + Console.WriteLine($"本次请求使用的参数:{parameters}"); + Console.WriteLine($"返回的web数据:{html}"); + return html; + } + catch (IOException e) + { + Utils.Debug.Console.PrintLine("Request()发生IO异常: {0}", e); + LogManager.Error("AriaClient", e); + return Request(url, parameters, retry - 1); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("Request()发生其他异常: {0}", e); + LogManager.Error("AriaClient", e); + return Request(url, parameters, retry - 1); + } + } + + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddMetalink.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddMetalink.cs new file mode 100644 index 0000000..4101680 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddMetalink.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaAddMetalink + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddTorrent.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddTorrent.cs new file mode 100644 index 0000000..80503ec --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddTorrent.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaAddTorrent + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddUri.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddUri.cs new file mode 100644 index 0000000..fca6526 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaAddUri.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + //{ + //"id": "downkyi", + //"jsonrpc": "2.0", + //"result": "1aac102a4875c8cd" + //} + [JsonObject] + public class AriaAddUri + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangeOption.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangeOption.cs new file mode 100644 index 0000000..b91a0e2 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangeOption.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaChangeOption + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangePosition.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangePosition.cs new file mode 100644 index 0000000..1405e56 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangePosition.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaChangePosition + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public int Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangeUri.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangeUri.cs new file mode 100644 index 0000000..b9af10a --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaChangeUri.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaChangeUri + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaError.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaError.cs new file mode 100644 index 0000000..4b967a3 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaError.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + //"error": { + // "code": 1, + // "message": "Unauthorized" + //} + [JsonObject] + public class AriaError + { + [JsonProperty("code")] + public int Code { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetFiles.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetFiles.cs new file mode 100644 index 0000000..34765e1 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetFiles.cs @@ -0,0 +1,53 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaGetFiles + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaGetFilesResult + { + [JsonProperty("completedLength")] + public string CompletedLength { get; set; } + + [JsonProperty("index")] + public string Index { get; set; } + + [JsonProperty("length")] + public string Length { get; set; } + + [JsonProperty("path")] + public string Path { get; set; } + + [JsonProperty("selected")] + public string Selected { get; set; } + + [JsonProperty("uris")] + public List Uris { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetGlobalStat.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetGlobalStat.cs new file mode 100644 index 0000000..1dc6591 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetGlobalStat.cs @@ -0,0 +1,66 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + /* + { + "id": "qwer", + "jsonrpc": "2.0", + "result": { + "downloadSpeed": "0", + "numActive": "0", + "numStopped": "0", + "numStoppedTotal": "0", + "numWaiting": "0", + "uploadSpeed": "0" + } + } + */ + [JsonObject] + public class AriaGetGlobalStat + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public AriaGetGlobalStatResult Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaGetGlobalStatResult + { + [JsonProperty("downloadSpeed")] + public string DownloadSpeed { get; set; } + + [JsonProperty("numActive")] + public string NumActive { get; set; } + + [JsonProperty("numStopped")] + public string NumStopped { get; set; } + + [JsonProperty("numStoppedTotal")] + public string NumStoppedTotal { get; set; } + + [JsonProperty("numWaiting")] + public string NumWaiting { get; set; } + + [JsonProperty("uploadSpeed")] + public string UploadSpeed { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetOption.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetOption.cs new file mode 100644 index 0000000..3e7e6e1 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetOption.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaGetOption + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public AriaOption Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetPeers.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetPeers.cs new file mode 100644 index 0000000..fa08242 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetPeers.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaGetPeers + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaPeer + { + [JsonProperty("amChoking")] + public string AmChoking { get; set; } + + [JsonProperty("bitfield")] + public string Bitfield { get; set; } + + [JsonProperty("downloadSpeed")] + public string DownloadSpeed { get; set; } + + [JsonProperty("ip")] + public string Ip { get; set; } + + [JsonProperty("peerChoking")] + public string PeerChoking { get; set; } + + [JsonProperty("peerId")] + public string PeerId { get; set; } + + [JsonProperty("port")] + public string Port { get; set; } + + [JsonProperty("seeder")] + public string Seeder { get; set; } + + [JsonProperty("uploadSpeed")] + public string UploadSpeed { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetServers.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetServers.cs new file mode 100644 index 0000000..7b6d8f2 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetServers.cs @@ -0,0 +1,59 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaGetServers + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaGetServersResult + { + [JsonProperty("index")] + public string Index { get; set; } + + [JsonProperty("servers")] + public List Servers { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaResultServer + { + [JsonProperty("currentUri")] + public string CurrentUri { get; set; } + + [JsonProperty("downloadSpeed")] + public string DownloadSpeed { get; set; } + + [JsonProperty("uri")] + public string Uri { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetSessionInfo.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetSessionInfo.cs new file mode 100644 index 0000000..76c9c6e --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetSessionInfo.cs @@ -0,0 +1,37 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaGetSessionInfo + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public AriaGetSessionInfoResult Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaGetSessionInfoResult + { + [JsonProperty("sessionId")] + public string SessionId { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetUris.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetUris.cs new file mode 100644 index 0000000..61b42ac --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaGetUris.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaGetUris + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaOption.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaOption.cs new file mode 100644 index 0000000..4a3e6aa --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaOption.cs @@ -0,0 +1,244 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaOption + { + [JsonProperty("all-proxy")] + public string AllProxy { get; set; } + + [JsonProperty("allow-overwrite")] + public string AllowOverwrite { get; set; } + + [JsonProperty("allow-piece-length-change")] + public string AllowPieceLengthChange { get; set; } + + [JsonProperty("always-resume")] + public string AlwaysResume { get; set; } + + [JsonProperty("async-dns")] + public string AsyncDns { get; set; } + + [JsonProperty("auto-file-renaming")] + public string AutoFileRenaming { get; set; } + + [JsonProperty("bt-enable-hook-after-hash-check")] + public string BtEnableHookAfterHashCheck { get; set; } + + [JsonProperty("bt-enable-lpd")] + public string BtEnableLpd { get; set; } + + [JsonProperty("bt-force-encryption")] + public string BtForceEncryption { get; set; } + + [JsonProperty("bt-hash-check-seed")] + public string BtHashCheckSeed { get; set; } + + [JsonProperty("bt-load-saved-metadata")] + public string BtLoadSavedMetadata { get; set; } + + [JsonProperty("bt-max-peers")] + public string BtMaxPeers { get; set; } + + [JsonProperty("bt-metadata-only")] + public string BtMetadataOnly { get; set; } + + [JsonProperty("bt-min-crypto-level")] + public string BtMinCryptoLevel { get; set; } + + [JsonProperty("bt-remove-unselected-file")] + public string BtRemoveUnselectedFile { get; set; } + + [JsonProperty("bt-request-peer-speed-limit")] + public string BtRequestPeerSpeedLimit { get; set; } + + [JsonProperty("bt-require-crypto")] + public string BtRequireCrypto { get; set; } + + [JsonProperty("bt-save-metadata")] + public string BtSaveMetadata { get; set; } + + [JsonProperty("bt-seed-unverified")] + public string BtSeedUnverified { get; set; } + + [JsonProperty("bt-stop-timeout")] + public string BtStopTimeout { get; set; } + + [JsonProperty("bt-tracker-connect-timeout")] + public string BtTrackerConnectTimeout { get; set; } + + [JsonProperty("bt-tracker-interval")] + public string BtTrackerInterval { get; set; } + + [JsonProperty("bt-tracker-timeout")] + public string BtTrackerTimeout { get; set; } + + [JsonProperty("check-integrity")] + public string CheckIntegrity { get; set; } + + [JsonProperty("conditional-get")] + public string ConditionalGet { get; set; } + + [JsonProperty("connect-timeout")] + public string ConnectTimeout { get; set; } + + [JsonProperty("content-disposition-default-utf8")] + public string ContentDispositionDefaultUtf8 { get; set; } + + [JsonProperty("continue")] + public string Continue { get; set; } + + [JsonProperty("dir")] + public string Dir { get; set; } + + [JsonProperty("dry-run")] + public string DryRun { get; set; } + + [JsonProperty("enable-http-keep-alive")] + public string EnableHttpKeepAlive { get; set; } + + [JsonProperty("enable-http-pipelining")] + public string EnableHttpPipelining { get; set; } + + [JsonProperty("enable-mmap")] + public string EnableMmap { get; set; } + + [JsonProperty("enable-peer-exchange")] + public string EnablePeerExchange { get; set; } + + [JsonProperty("file-allocation")] + public string FileAllocation { get; set; } + + [JsonProperty("follow-metalink")] + public string FollowMetalink { get; set; } + + [JsonProperty("follow-torrent")] + public string FollowTorrent { get; set; } + + [JsonProperty("force-save")] + public string ForceSave { get; set; } + + [JsonProperty("ftp-pasv")] + public string FtpPasv { get; set; } + + [JsonProperty("ftp-reuse-connection")] + public string FtpReuseConnection { get; set; } + + [JsonProperty("ftp-type")] + public string FtpType { get; set; } + + [JsonProperty("hash-check-only")] + public string HashCheckOnly { get; set; } + + [JsonProperty("http-accept-gzip")] + public string HttpAcceptGzip { get; set; } + + [JsonProperty("http-auth-challenge")] + public string HttpAuthChallenge { get; set; } + + [JsonProperty("http-no-cache")] + public string HttpNoCache { get; set; } + + [JsonProperty("lowest-speed-limit")] + public string LowestSpeedLimit { get; set; } + + [JsonProperty("max-connection-per-server")] + public string MaxConnectionPerServer { get; set; } + + [JsonProperty("max-download-limit")] + public string MaxDownloadLimit { get; set; } + + [JsonProperty("max-file-not-found")] + public string MaxFileNotFound { get; set; } + + [JsonProperty("max-mmap-limit")] + public string MaxMmapLimit { get; set; } + + [JsonProperty("max-resume-failure-tries")] + public string MaxResumeFailureTries { get; set; } + + [JsonProperty("max-tries")] + public string MaxTries { get; set; } + + [JsonProperty("max-upload-limit")] + public string MaxUploadLimit { get; set; } + + [JsonProperty("metalink-enable-unique-protocol")] + public string MetalinkEnableUniqueProtocol { get; set; } + + [JsonProperty("metalink-preferred-protocol")] + public string MetalinkPreferredProtocol { get; set; } + + [JsonProperty("min-split-size")] + public string MinSplitSize { get; set; } + + [JsonProperty("no-file-allocation-limit")] + public string NoFileAllocationLimit { get; set; } + + [JsonProperty("no-netrc")] + public string NoNetrc { get; set; } + + [JsonProperty("out")] + public string Out { get; set; } + + [JsonProperty("parameterized-uri")] + public string ParameterizedUri { get; set; } + + [JsonProperty("pause-metadata")] + public string PauseMetadata { get; set; } + + [JsonProperty("piece-length")] + public string PieceLength { get; set; } + + [JsonProperty("proxy-method")] + public string ProxyMethod { get; set; } + + [JsonProperty("realtime-chunk-checksum")] + public string RealtimeChunkChecksum { get; set; } + + [JsonProperty("remote-time")] + public string RemoteTime { get; set; } + + [JsonProperty("remove-control-file")] + public string RemoveControlFile { get; set; } + + [JsonProperty("retry-wait")] + public string RetryWait { get; set; } + + [JsonProperty("reuse-uri")] + public string ReuseUri { get; set; } + + [JsonProperty("rpc-save-upload-metadata")] + public string RpcSaveUploadMetadata { get; set; } + + [JsonProperty("save-not-found")] + public string SaveNotFound { get; set; } + + [JsonProperty("seed-ratio")] + public string SeedRatio { get; set; } + + [JsonProperty("split")] + public string Split { get; set; } + + [JsonProperty("stream-piece-selector")] + public string StreamPieceSelector { get; set; } + + [JsonProperty("timeout")] + public string Timeout { get; set; } + + [JsonProperty("uri-selector")] + public string UriSelector { get; set; } + + [JsonProperty("use-head")] + public string UseHead { get; set; } + + [JsonProperty("user-agent")] + public string UserAgent { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaPause.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaPause.cs new file mode 100644 index 0000000..3aa20fc --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaPause.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaPause + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaRemove.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaRemove.cs new file mode 100644 index 0000000..5950c4d --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaRemove.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaRemove + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaSaveSession.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaSaveSession.cs new file mode 100644 index 0000000..11f654e --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaSaveSession.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaSaveSession + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs new file mode 100644 index 0000000..ffbe89a --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs @@ -0,0 +1,53 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaSendData + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("method")] + public string Method { get; set; } + + [JsonProperty("params")] + public List Params { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaSendOption + { + [JsonProperty("all-proxy")] + public string HttpProxy { get; set; } + + [JsonProperty("out")] + public string Out { get; set; } + + [JsonProperty("dir")] + public string Dir { get; set; } + + //[JsonProperty("header")] + //public string Header { get; set; } + + //[JsonProperty("use-head")] + //public string UseHead { get; set; } + + //[JsonProperty("user-agent")] + //public string UserAgent { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaShutdown.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaShutdown.cs new file mode 100644 index 0000000..45a688d --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaShutdown.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaShutdown + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaTellStatus.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaTellStatus.cs new file mode 100644 index 0000000..fa2c41f --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaTellStatus.cs @@ -0,0 +1,128 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaTellStatus + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public AriaTellStatusResult Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaTellStatusList + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaTellStatusResult + { + [JsonProperty("bitfield")] + public string Bitfield { get; set; } + + [JsonProperty("completedLength")] + public string CompletedLength { get; set; } + + [JsonProperty("connections")] + public string Connections { get; set; } + + [JsonProperty("dir")] + public string Dir { get; set; } + + [JsonProperty("downloadSpeed")] + public string DownloadSpeed { get; set; } + + [JsonProperty("errorCode")] + public string ErrorCode { get; set; } + + [JsonProperty("errorMessage")] + public string ErrorMessage { get; set; } + + [JsonProperty("files")] + public List Files { get; set; } + + [JsonProperty("gid")] + public string Gid { get; set; } + + [JsonProperty("numPieces")] + public string NumPieces { get; set; } + + [JsonProperty("pieceLength")] + public string PieceLength { get; set; } + + [JsonProperty("status")] + public string Status { get; set; } + + [JsonProperty("totalLength")] + public string TotalLength { get; set; } + + [JsonProperty("uploadLength")] + public string UploadLength { get; set; } + + [JsonProperty("uploadSpeed")] + public string UploadSpeed { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaTellStatusResultFile + { + [JsonProperty("completedLength")] + public string CompletedLength { get; set; } + + [JsonProperty("index")] + public string Index { get; set; } + + [JsonProperty("length")] + public string Length { get; set; } + + [JsonProperty("path")] + public string Path { get; set; } + + [JsonProperty("selected")] + public string Selected { get; set; } + + [JsonProperty("uris")] + public List Uris { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaUri.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaUri.cs new file mode 100644 index 0000000..28001bc --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaUri.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaUri + { + [JsonProperty("status")] + public string Status { get; set; } + + [JsonProperty("uri")] + public string Uri { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaVersion.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaVersion.cs new file mode 100644 index 0000000..d7ab742 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaVersion.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class AriaVersion + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public AriaVersionResult Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } + + [JsonObject] + public class AriaVersionResult + { + [JsonProperty("enabledFeatures")] + public List EnabledFeatures { get; set; } + + [JsonProperty("version")] + public string Version { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/SystemListMethods.cs b/DownKyi.Core/Aria2cNet/Client/Entity/SystemListMethods.cs new file mode 100644 index 0000000..96ce9da --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/SystemListMethods.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class SystemListMethods + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/SystemListNotifications.cs b/DownKyi.Core/Aria2cNet/Client/Entity/SystemListNotifications.cs new file mode 100644 index 0000000..68be4be --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/SystemListNotifications.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class SystemListNotifications + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public List Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/SystemMulticall.cs b/DownKyi.Core/Aria2cNet/Client/Entity/SystemMulticall.cs new file mode 100644 index 0000000..b0da67d --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/SystemMulticall.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class SystemMulticall + { + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("jsonrpc")] + public string Jsonrpc { get; set; } + + [JsonProperty("result")] + public string Result { get; set; } + + [JsonProperty("error")] + public AriaError Error { get; set; } + + public override string ToString() + { + return JsonConvert.SerializeObject(this); + } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/SystemMulticallMathod.cs b/DownKyi.Core/Aria2cNet/Client/Entity/SystemMulticallMathod.cs new file mode 100644 index 0000000..3c8a71e --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/Entity/SystemMulticallMathod.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Client.Entity +{ + [JsonObject] + public class SystemMulticallMathod + { + [JsonProperty("method")] + public string Method { get; set; } + + [JsonProperty("params")] + public List Params { get; set; } + } +} diff --git a/DownKyi.Core/Aria2cNet/Client/HowChangePosition.cs b/DownKyi.Core/Aria2cNet/Client/HowChangePosition.cs new file mode 100644 index 0000000..f6246a2 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Client/HowChangePosition.cs @@ -0,0 +1,12 @@ +namespace DownKyi.Core.Aria2cNet.Client +{ + /// + /// changePosition函数的how参数 + /// + public enum HowChangePosition + { + POS_SET = 1, + POS_CUR, + POS_END + } +} diff --git a/DownKyi.Core/Aria2cNet/DownloadStatus.cs b/DownKyi.Core/Aria2cNet/DownloadStatus.cs new file mode 100644 index 0000000..a8c1d73 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/DownloadStatus.cs @@ -0,0 +1,12 @@ +namespace DownKyi.Core.Aria2cNet +{ + /// + /// 下载状态 + /// + public enum DownloadStatus + { + SUCCESS = 1, + FAILED, + ABORT + } +} diff --git a/DownKyi.Core/Aria2cNet/Server/AriaConfig.cs b/DownKyi.Core/Aria2cNet/Server/AriaConfig.cs new file mode 100644 index 0000000..8afa39d --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Server/AriaConfig.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.Aria2cNet.Server +{ + /// + /// Aria服务器的启动配置 + /// + public class AriaConfig + { + public int ListenPort { get; set; } // 服务器端口号,取值:1024-65535 + public string Token { get; set; } // 连接服务器的token + public AriaConfigLogLevel LogLevel { get; set; } // 日志等级,debug info notice warn error + public int MaxConcurrentDownloads { get; set; } // 最大同时下载数(任务数),取值:1-* + public int MaxConnectionPerServer { get; set; } // 同服务器连接数,取值:1-16 + public int Split { get; set; } // 单文件最大线程数,取值:1-* + //public int MaxTries { get; set; } //当服务器返回503错误时,尝试重连;尝试重连次数,0代表无限,默认:5 + public int MinSplitSize { get; set; } // 最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要,单位MB + public long MaxOverallDownloadLimit { get; set; } // 下载速度限制,取值:1-* + public long MaxDownloadLimit { get; set; } // 下载单文件速度限制,取值:1-* + public long MaxOverallUploadLimit { get; set; } // 上传速度限制,取值:1-* + public long MaxUploadLimit { get; set; } // 上传单文件速度限制,取值:1-* + public bool ContinueDownload { get; set; } // 断点续传 + public AriaConfigFileAllocation FileAllocation { get; set; } // 文件预分配, none prealloc + + public List Headers { get; set; } + } +} diff --git a/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs b/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs new file mode 100644 index 0000000..e00a9aa --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs @@ -0,0 +1,12 @@ +namespace DownKyi.Core.Aria2cNet.Server +{ + /// + /// 文件预分配 + /// + public enum AriaConfigFileAllocation + { + NONE = 1, // 没有预分配 + PREALLOC, // 预分配,默认 + FALLOC // NTFS建议使用 + } +} diff --git a/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs b/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs new file mode 100644 index 0000000..b1f4620 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs @@ -0,0 +1,14 @@ +namespace DownKyi.Core.Aria2cNet.Server +{ + /// + /// 日志等级 + /// + public enum AriaConfigLogLevel + { + DEBUG = 1, + INFO, + NOTICE, + WARN, + ERROR + } +} diff --git a/DownKyi.Core/Aria2cNet/Server/AriaServer.cs b/DownKyi.Core/Aria2cNet/Server/AriaServer.cs new file mode 100644 index 0000000..ded9b16 --- /dev/null +++ b/DownKyi.Core/Aria2cNet/Server/AriaServer.cs @@ -0,0 +1,245 @@ +using DownKyi.Core.Aria2cNet.Client; +using DownKyi.Core.Logging; +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace DownKyi.Core.Aria2cNet.Server +{ + public static class AriaServer + { + public static int ListenPort; // 服务器端口 + private static Process Server; + + /// + /// 启动aria2c服务器 + /// + /// + /// + /// + /// + public static async Task StartServerAsync(AriaConfig config, TextBox output = null, Window window = null) + { + // aria端口 + ListenPort = config.ListenPort; + // aria目录 + string ariaDir = Environment.CurrentDirectory + "\\aria\\"; + // 会话文件 +#if DEBUG + string sessionFile = ariaDir + "aira.session"; +#else + string sessionFile = ariaDir + "aira.session.gz"; +#endif + // 日志文件 + string logFile = ariaDir + "aira.log"; + // 自动保存会话文件的时间间隔 + int saveSessionInterval = 30; + + // --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all=true --continue=true + await Task.Run(() => + { + // 创建目录和文件 + if (!Directory.Exists(ariaDir)) + { + Directory.CreateDirectory(ariaDir); + } + if (!File.Exists(sessionFile)) + { + var stream = File.Create(sessionFile); + stream.Close(); + } + if (!File.Exists(logFile)) + { + var stream = File.Create(logFile); + stream.Close(); + } + else + { + // 日志文件存在,如果大于100M,则删除 + try + { + var stream = File.Open(logFile, FileMode.Open); + if (stream.Length >= 512 * 1024 * 1024L) + { + stream.SetLength(0); + } + stream.Close(); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("StartServerAsync()发生其他异常: {0}", e); + LogManager.Error("AriaServer", e); + } + } + + // header 解析 + string headers = string.Empty; + if (config.Headers != null) + { + foreach (var header in config.Headers) + { + headers += $"--header=\"{header}\" "; + } + } + + ExcuteProcess("aria2c.exe", + $"--enable-rpc --rpc-listen-all=true --rpc-allow-origin-all=true " + + $"--rpc-listen-port={config.ListenPort} " + + $"--rpc-secret={config.Token} " + + $"--input-file=\"{sessionFile}\" --save-session=\"{sessionFile}\" " + + $"--save-session-interval={saveSessionInterval} " + + $"--log=\"{logFile}\" --log-level={config.LogLevel.ToString("G").ToLower()} " + // log-level: 'debug' 'info' 'notice' 'warn' 'error' + $"--max-concurrent-downloads={config.MaxConcurrentDownloads} " + // 最大同时下载数(任务数) + $"--max-connection-per-server={config.MaxConnectionPerServer} " + // 同服务器连接数 + $"--split={config.Split} " + // 单文件最大线程数 + //$"--max-tries={config.MaxTries} retry-wait=3 " + // 尝试重连次数 + $"--min-split-size={config.MinSplitSize}M " + // 最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要 + $"--max-overall-download-limit={config.MaxOverallDownloadLimit} " + // 下载速度限制 + $"--max-download-limit={config.MaxDownloadLimit} " + // 下载单文件速度限制 + $"--max-overall-upload-limit={config.MaxOverallUploadLimit} " + // 上传速度限制 + $"--max-upload-limit={config.MaxUploadLimit} " + // 上传单文件速度限制 + $"--continue={config.ContinueDownload.ToString().ToLower()} " + // 断点续传 + $"--allow-overwrite=true " + // 允许复写文件 + $"--auto-file-renaming=false " + + $"--file-allocation={config.FileAllocation.ToString("G").ToLower()} " + // 文件预分配, none prealloc + $"{headers}" + // header + "", + null, (s, e) => + { + if (e.Data == null || e.Data == "" || e.Data.Replace(" ", "") == "") { return; } + Utils.Debug.Console.PrintLine(e.Data); + LogManager.Debug("AriaServer", e.Data); + + if (output != null && window != null) + { + window.Dispatcher.Invoke(new Action(() => + { + output.Text += e.Data + "\n"; + output.ScrollToEnd(); + })); + } + }); + }); + + return true; + } + + /// + /// 关闭aria2c服务器,异步方法 + /// + /// + public static async Task CloseServerAsync() + { + await AriaClient.ShutdownAsync(); + return true; + } + + /// + /// 强制关闭aria2c服务器,异步方法 + /// + /// + public static async Task ForceCloseServerAsync() + { + //await Task.Run(() => + //{ + // if (Server == null) { return; } + + // Server.Kill(); + // Server = null; // 将Server指向null + //}); + //return true; + await AriaClient.ForceShutdownAsync(); + return true; + } + + /// + /// 关闭aria2c服务器 + /// + /// + public static bool CloseServer() + { + var task = AriaClient.ShutdownAsync(); + if (task.Result != null && task.Result.Result != null && task.Result.Result == "OK") + { return true; } + return false; + } + + /// + /// 强制关闭aria2c服务器 + /// + /// + public static bool ForceCloseServer() + { + var task = AriaClient.ForceShutdownAsync(); + if (task.Result != null && task.Result.Result != null && task.Result.Result == "OK") + { return true; } + return false; + } + + /// + /// 杀死Aria进程 + /// + /// + /// + public static bool KillServer(string processName = "aria2c") + { + Process[] processes = Process.GetProcessesByName(processName); + foreach (var process in processes) + { + try + { + process.Kill(); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("KillServer()发生异常: {0}", e); + LogManager.Error("AriaServer", e); + } + } + return true; + } + + + private static void ExcuteProcess(string exe, string arg, string workingDirectory, DataReceivedEventHandler output) + { + using (var p = new Process()) + { + Server = p; + + p.StartInfo.FileName = exe; + p.StartInfo.Arguments = arg; + + // 工作目录 + if (workingDirectory != null) + { + p.StartInfo.WorkingDirectory = workingDirectory; + } + + // 输出信息重定向 + p.StartInfo.UseShellExecute = false; + p.StartInfo.CreateNoWindow = true; + p.StartInfo.RedirectStandardError = true; + p.StartInfo.RedirectStandardOutput = true; + + // 将 StandardErrorEncoding 改为 UTF-8 才不会出现中文乱码 + p.StartInfo.StandardOutputEncoding = Encoding.UTF8; + p.StartInfo.StandardErrorEncoding = Encoding.UTF8; + + p.OutputDataReceived += output; + p.ErrorDataReceived += output; + + // 启动线程 + p.Start(); + p.BeginOutputReadLine(); + p.BeginErrorReadLine(); + // 等待进程结束 + p.WaitForExit(); + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/BangumiInfo.cs b/DownKyi.Core/BiliApi/Bangumi/BangumiInfo.cs new file mode 100644 index 0000000..1aca793 --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/BangumiInfo.cs @@ -0,0 +1,68 @@ +using DownKyi.Core.BiliApi.Bangumi.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; + +namespace DownKyi.Core.BiliApi.Bangumi +{ + public static class BangumiInfo + { + + /// + /// 剧集基本信息(mediaId方式) + /// + /// + /// + public static BangumiMedia BangumiMediaInfo(long mediaId) + { + string url = $"https://api.bilibili.com/pgc/review/user?media_id={mediaId}"; + string referer = "https://www.bilibili.com"; + string response = WebClient.RequestWeb(url, referer); + + try + { + var media = JsonConvert.DeserializeObject(response); + if (media != null && media.Result != null) { return media.Result.Media; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("BangumiMediaInfo()发生异常: {0}", e); + LogManager.Error("BangumiInfo", e); + return null; + } + } + + /// + /// 获取剧集明细(web端)(seasonId/episodeId方式) + /// + /// + /// + /// + public static BangumiSeason BangumiSeasonInfo(long seasonId = -1, long episodeId = -1) + { + string baseUrl = "https://api.bilibili.com/pgc/view/web/season"; + string referer = "https://www.bilibili.com"; + string url; + if (seasonId > -1) { url = $"{baseUrl}?season_id={seasonId}"; } + else if (episodeId > -1) { url = $"{baseUrl}?ep_id={episodeId}"; } + else { return null; } + + string response = WebClient.RequestWeb(url, referer); + + try + { + var bangumiSeason = JsonConvert.DeserializeObject(response); + if (bangumiSeason != null) { return bangumiSeason.Result; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("BangumiSeasonInfo()发生异常: {0}", e); + LogManager.Error("BangumiInfo", e); + return null; + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/BangumiType.cs b/DownKyi.Core/BiliApi/Bangumi/BangumiType.cs new file mode 100644 index 0000000..fae5abc --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/BangumiType.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Bangumi +{ + public static class BangumiType + { + public static Dictionary Type = new Dictionary() + { + { 1, "Anime" }, + { 2, "Movie" }, + { 3, "Documentary" }, + { 4, "Guochuang" }, + { 5, "TV" }, + { 6, "Unknown" }, + { 7, "Entertainment" }, + { 8, "Unknown" }, + { 9, "Unknown" }, + { 10, "Unknown" } + }; + + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiArea.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiArea.cs new file mode 100644 index 0000000..4ce21b6 --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiArea.cs @@ -0,0 +1,13 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiArea : BaseModel + { + [JsonProperty("id")] + public int Id { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiEpisode.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiEpisode.cs new file mode 100644 index 0000000..4cee71e --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiEpisode.cs @@ -0,0 +1,53 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiEpisode : BaseModel + { + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("badge")] + public string Badge { get; set; } + // badge_info + // badge_type + [JsonProperty("bvid")] + public string Bvid { get; set; } + [JsonProperty("cid")] + public long Cid { get; set; } + [JsonProperty("cover")] + public string Cover { get; set; } + [JsonProperty("dimension")] + public Dimension Dimension { get; set; } + [JsonProperty("duration")] + public long Duration { get; set; } + [JsonProperty("from")] + public string From { get; set; } + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("link")] + public string Link { get; set; } + [JsonProperty("long_title")] + public string LongTitle { get; set; } + [JsonProperty("pub_time")] + public long PubTime { get; set; } + // pv + // release_date + // rights + [JsonProperty("share_copy")] + public string ShareCopy { get; set; } + [JsonProperty("share_url")] + public string ShareUrl { get; set; } + [JsonProperty("short_link")] + public string ShortLink { get; set; } + // stat + [JsonProperty("status")] + public int Status { get; set; } + [JsonProperty("subtitle")] + public string Subtitle { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("vid")] + public string Vid { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiMedia.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiMedia.cs new file mode 100644 index 0000000..d22667c --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiMedia.cs @@ -0,0 +1,46 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + // https://api.bilibili.com/pgc/review/user + public class BangumiMediaOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("result")] + public BangumiMediaData Result { get; set; } + } + + public class BangumiMediaData : BaseModel + { + [JsonProperty("media")] + public BangumiMedia Media { get; set; } + } + + public class BangumiMedia : BaseModel + { + [JsonProperty("areas")] + public List Areas { get; set; } + [JsonProperty("cover")] + public string Cover { get; set; } + [JsonProperty("media_id")] + public long MediaId { get; set; } + // new_ep + // rating + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("share_url")] + public string ShareUrl { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("type_name")] + public string TypeName { get; set; } + } + +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiPositive.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiPositive.cs new file mode 100644 index 0000000..acbfd2c --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiPositive.cs @@ -0,0 +1,13 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiPositive : BaseModel + { + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeason.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeason.cs new file mode 100644 index 0000000..87d3dcf --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeason.cs @@ -0,0 +1,79 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + // https://api.bilibili.com/pgc/view/web/season + public class BangumiSeasonOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("result")] + public BangumiSeason Result { get; set; } + } + + public class BangumiSeason : BaseModel + { + // activity + // alias + [JsonProperty("areas")] + public List Areas { get; set; } + [JsonProperty("bkg_cover")] + public string BkgCover { get; set; } + [JsonProperty("cover")] + public string Cover { get; set; } + [JsonProperty("episodes")] + public List Episodes { get; set; } + [JsonProperty("evaluate")] + public string Evaluate { get; set; } + // freya + // jp_title + [JsonProperty("link")] + public string Link { get; set; } + [JsonProperty("media_id")] + public long MediaId { get; set; } + // mode + // new_ep + // payment + [JsonProperty("positive")] + public BangumiPositive Positive { get; set; } + // publish + // rating + // record + // rights + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("season_title")] + public string SeasonTitle { get; set; } + [JsonProperty("seasons")] + public List Seasons { get; set; } + [JsonProperty("section")] + public List Section { get; set; } + // series + // share_copy + // share_sub_title + // share_url + // show + [JsonProperty("square_cover")] + public string SquareCover { get; set; } + [JsonProperty("stat")] + public BangumiStat Stat { get; set; } + // status + [JsonProperty("subtitle")] + public string Subtitle { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("total")] + public int Total { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + [JsonProperty("up_info")] + public BangumiUpInfo UpInfo { get; set; } + } + +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeasonInfo.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeasonInfo.cs new file mode 100644 index 0000000..2adaf55 --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeasonInfo.cs @@ -0,0 +1,25 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiSeasonInfo : BaseModel + { + [JsonProperty("badge")] + public string Badge { get; set; } + // badge_info + // badge_type + [JsonProperty("cover")] + public string Cover { get; set; } + [JsonProperty("media_id")] + public long MediaId { get; set; } + // new_ep + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("season_title")] + public string SeasonTitle { get; set; } + [JsonProperty("season_type")] + public int SeasonType { get; set; } + // stat + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSection.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSection.cs new file mode 100644 index 0000000..e416938 --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiSection.cs @@ -0,0 +1,20 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiSection : BaseModel + { + [JsonProperty("episode_id")] + public long EpisodeId { get; set; } + [JsonProperty("episodes")] + public List Episodes { get; set; } + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiStat.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiStat.cs new file mode 100644 index 0000000..fac010d --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiStat.cs @@ -0,0 +1,25 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiStat : BaseModel + { + [JsonProperty("coins")] + public long Coins { get; set; } + [JsonProperty("danmakus")] + public long Danmakus { get; set; } + [JsonProperty("favorite")] + public long Favorite { get; set; } + [JsonProperty("favorites")] + public long Favorites { get; set; } + [JsonProperty("likes")] + public long Likes { get; set; } + [JsonProperty("reply")] + public long Reply { get; set; } + [JsonProperty("share")] + public long Share { get; set; } + [JsonProperty("views")] + public long Views { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Bangumi/Models/BangumiUpInfo.cs b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiUpInfo.cs new file mode 100644 index 0000000..b7b8638 --- /dev/null +++ b/DownKyi.Core/BiliApi/Bangumi/Models/BangumiUpInfo.cs @@ -0,0 +1,22 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Bangumi.Models +{ + public class BangumiUpInfo : BaseModel + { + [JsonProperty("avatar")] + public string Avatar { get; set; } + // follower + // is_follow + [JsonProperty("mid")] + public long Mid { get; set; } + // pendant + // theme_type + [JsonProperty("uname")] + public string Name { get; set; } + // verify_type + // vip_status + // vip_type + } +} diff --git a/DownKyi.Core/BiliApi/BiliUtils/BvId.cs b/DownKyi.Core/BiliApi/BiliUtils/BvId.cs new file mode 100644 index 0000000..665bc50 --- /dev/null +++ b/DownKyi.Core/BiliApi/BiliUtils/BvId.cs @@ -0,0 +1,63 @@ +using System; + +namespace DownKyi.Core.BiliApi.BiliUtils +{ + public static class BvId + { + private const string tableStr = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"; //码表 + private static readonly char[] table = tableStr.ToCharArray(); + + private static readonly char[] tr = new char[124]; //反查码表 + private const ulong Xor = 177451812; //固定异或值 + private const ulong add = 8728348608; //固定加法值 + private static readonly int[] s = { 11, 10, 3, 8, 4, 6 }; //位置编码表 + + static BvId() + { + Tr_init(); + } + + //初始化反查码表 + private static void Tr_init() + { + for (int i = 0; i < 58; i++) + tr[table[i]] = (char)i; + } + + /// + /// bvid转avid + /// + /// + /// + public static ulong Bv2Av(string bvid) + { + char[] bv = bvid.ToCharArray(); + + ulong r = 0; + ulong av; + for (int i = 0; i < 6; i++) + r += tr[bv[s[i]]] * (ulong)Math.Pow(58, i); + av = (r - add) ^ Xor; + return av; + } + + /// + /// avid转bvid + /// + /// + /// + public static string Av2Bv(ulong av) + { + //编码结果 + string res = "BV1 4 1 7 "; + char[] result = res.ToCharArray(); + + av = (av ^ Xor) + add; + for (int i = 0; i < 6; i++) + result[s[i]] = table[av / (ulong)Math.Pow(58, i) % 58]; + string bv = new string(result); + return bv; + } + + } +} diff --git a/DownKyi.Core/BiliApi/BiliUtils/Constant.cs b/DownKyi.Core/BiliApi/BiliUtils/Constant.cs new file mode 100644 index 0000000..7b0ce8a --- /dev/null +++ b/DownKyi.Core/BiliApi/BiliUtils/Constant.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.BiliUtils +{ + public static class Constant + { + /// + /// 音质id及含义 + /// + public static Dictionary AudioQuality { get; } = new Dictionary() + { + { 30216, "64K" }, + { 30232, "132K" }, + { 30280, "192K" } + }; + + } +} diff --git a/DownKyi.Core/BiliApi/BiliUtils/DanmakuSender.cs b/DownKyi.Core/BiliApi/BiliUtils/DanmakuSender.cs new file mode 100644 index 0000000..9404f22 --- /dev/null +++ b/DownKyi.Core/BiliApi/BiliUtils/DanmakuSender.cs @@ -0,0 +1,154 @@ +using System; + +namespace DownKyi.Core.BiliApi.BiliUtils +{ + public static class DanmakuSender + { + private const uint CRCPOLYNOMIAL = 0xEDB88320; + private static readonly uint[] crctable = new uint[256]; + + static DanmakuSender() + { + CreateTable(); + } + + private static void CreateTable() + { + for (int i = 0; i < 256; i++) + { + uint crcreg = (uint)i; + + for (int j = 0; j < 8; j++) + { + if ((crcreg & 1) != 0) + { + crcreg = CRCPOLYNOMIAL ^ (crcreg >> 1); + } + else + { + crcreg >>= 1; + } + } + crctable[i] = crcreg; + } + } + + private static uint Crc32(string userId) + { + uint crcstart = 0xFFFFFFFF; + for (int i = 0; i < userId.Length; i++) + { + uint index = (uint)(crcstart ^ (int)userId[i]) & 255; + crcstart = (crcstart >> 8) ^ crctable[index]; + } + return crcstart; + } + + private static uint Crc32LastIndex(string userId) + { + uint index = 0; + uint crcstart = 0xFFFFFFFF; + for (int i = 0; i < userId.Length; i++) + { + index = (uint)((crcstart ^ (int)userId[i]) & 255); + crcstart = (crcstart >> 8) ^ crctable[index]; + } + return index; + } + + private static int GetCrcIndex(long t) + { + for (int i = 0; i < 256; i++) + { + if ((crctable[i] >> 24) == t) + { + return i; + } + } + return -1; + } + + private static object[] DeepCheck(int i, int[] index) + { + object[] resultArray = new object[2]; + + string result = ""; + uint tc;// = 0x00; + var hashcode = Crc32(i.ToString()); + tc = (uint)(hashcode & 0xff ^ index[2]); + + if (!(tc <= 57 && tc >= 48)) + { + resultArray[0] = 0; + return resultArray; + } + + result += (tc - 48).ToString(); + hashcode = crctable[index[2]] ^ (hashcode >> 8); + tc = (uint)(hashcode & 0xff ^ index[1]); + + if (!(tc <= 57 && tc >= 48)) + { + resultArray[0] = 0; + return resultArray; + } + + result += (tc - 48).ToString(); + hashcode = crctable[index[1]] ^ (hashcode >> 8); + tc = (uint)(hashcode & 0xff ^ index[0]); + + if (!(tc <= 57 && tc >= 48)) + { + resultArray[0] = 0; + return resultArray; + } + + result += (tc - 48).ToString(); + //hashcode = crctable[index[0]] ^ (hashcode >> 8); + + resultArray[0] = 1; + resultArray[1] = result; + return resultArray; + } + + /// + /// 查询弹幕发送者 + /// + /// + /// + public static string FindDanmakuSender(string userId) + { + object[] deepCheckData = new object[2]; + + int[] index = new int[4]; + uint ht = (uint)Convert.ToInt32($"0x{userId}", 16); + ht ^= 0xffffffff; + + int i; + for (i = 3; i > -1; i--) + { + index[3 - i] = GetCrcIndex(ht >> (i * 8)); + uint snum = crctable[index[3 - i]]; + ht ^= snum >> ((3 - i) * 8); + } + for (i = 0; i < 100000000; i++) + { + uint lastindex = Crc32LastIndex(i.ToString()); + if (lastindex == index[3]) + { + deepCheckData = DeepCheck(i, index); + if ((int)deepCheckData[0] != 0) + { + break; + } + } + } + if (i == 100000000) + { + return "-1"; + } + return $"{i}{deepCheckData[1]}"; + } + + } +} diff --git a/DownKyi.Core/BiliApi/BiliUtils/ParseEntrance.cs b/DownKyi.Core/BiliApi/BiliUtils/ParseEntrance.cs new file mode 100644 index 0000000..f7c51ad --- /dev/null +++ b/DownKyi.Core/BiliApi/BiliUtils/ParseEntrance.cs @@ -0,0 +1,503 @@ +using DownKyi.Core.Utils.Validator; +using System.Text.RegularExpressions; + +namespace DownKyi.Core.BiliApi.BiliUtils +{ + /// + /// 解析输入的字符串 + /// 支持的格式有: + /// av号:av170001, AV170001, https://www.bilibili.com/video/av170001 + /// BV号:BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC + /// 番剧(电影、电视剧)ss号:ss32982, SS32982, https://www.bilibili.com/bangumi/play/ss32982 + /// 番剧(电影、电视剧)ep号:ep317925, EP317925, https://www.bilibili.com/bangumi/play/ep317925 + /// 番剧(电影、电视剧)md号:md28228367, MD28228367, https://www.bilibili.com/bangumi/media/md28228367 + /// 课程ss号:https://www.bilibili.com/cheese/play/ss205 + /// 课程ep号:https://www.bilibili.com/cheese/play/ep3489 + /// 收藏夹:ml1329019876, ML1329019876, https://www.bilibili.com/medialist/detail/ml1329019876 + /// 用户空间:uid928123, UID928123, uid:928123, UID:928123, https://space.bilibili.com/928123 + /// + public static class ParseEntrance + { + public static readonly string WwwUrl = "https://www.bilibili.com"; + public static readonly string MobileUrl = "https://m.bilibili.com"; + public static readonly string SpaceUrl = "https://space.bilibili.com"; + + public static readonly string VideoUrl = $"{WwwUrl}/video/"; + public static readonly string BangumiUrl = $"{WwwUrl}/bangumi/play/"; + public static readonly string BangumiMediaUrl = $"{WwwUrl}/bangumi/media/"; + public static readonly string CheeseUrl = $"{WwwUrl}/cheese/play/"; + public static readonly string FavoritesUrl = $"{WwwUrl}/medialist/detail/"; + + #region 视频 + + /// + /// 是否为av id + /// + /// + /// + public static bool IsAvId(string input) + { + return IsIntId(input, "av"); + } + + /// + /// 是否为av url + /// + /// + /// + public static bool IsAvUrl(string input) + { + string id = GetVideoId(input); + return IsAvId(id); + } + + /// + /// 获取av id + /// + /// + /// + public static long GetAvId(string input) + { + if (IsAvId(input)) + { + return Number.GetInt(input.Remove(0, 2)); + } + else if (IsAvUrl(input)) + { + return Number.GetInt(GetVideoId(input).Remove(0, 2)); + } + else + { + return -1; + } + } + + /// + /// 是否为bv id + /// + /// + /// + public static bool IsBvId(string input) + { + return input.StartsWith("BV") && input.Length == 12; + } + + /// + /// 是否为bv url + /// + /// + /// + public static bool IsBvUrl(string input) + { + string id = GetVideoId(input); + return IsBvId(id); + } + + /// + /// 获取bv id + /// + /// + /// + public static string GetBvId(string input) + { + if (IsBvId(input)) + { + return input; + } + else if (IsBvUrl(input)) + { + return GetVideoId(input); + } + else + { + return ""; + } + } + + #endregion + + #region 番剧(电影、电视剧) + + /// + /// 是否为番剧season id + /// + /// + /// + public static bool IsBangumiSeasonId(string input) + { + return IsIntId(input, "ss"); + } + + /// + /// 是否为番剧season url + /// + /// + /// + public static bool IsBangumiSeasonUrl(string input) + { + string id = GetBangumiId(input); + return IsBangumiSeasonId(id); + } + + /// + /// 获取番剧season id + /// + /// + /// + public static long GetBangumiSeasonId(string input) + { + if (IsBangumiSeasonId(input)) + { + return Number.GetInt(input.Remove(0, 2)); + } + else if (IsBangumiSeasonUrl(input)) + { + return Number.GetInt(GetBangumiId(input).Remove(0, 2)); + } + else + { + return -1; + } + } + + /// + /// 是否为番剧episode id + /// + /// + /// + public static bool IsBangumiEpisodeId(string input) + { + return IsIntId(input, "ep"); + } + + /// + /// 是否为番剧episode url + /// + /// + /// + public static bool IsBangumiEpisodeUrl(string input) + { + string id = GetBangumiId(input); + return IsBangumiEpisodeId(id); + } + + /// + /// 获取番剧episode id + /// + /// + /// + public static long GetBangumiEpisodeId(string input) + { + if (IsBangumiEpisodeId(input)) + { + return Number.GetInt(input.Remove(0, 2)); + } + else if (IsBangumiEpisodeUrl(input)) + { + return Number.GetInt(GetBangumiId(input).Remove(0, 2)); + } + else + { + return -1; + } + } + + /// + /// 是否为番剧media id + /// + /// + /// + public static bool IsBangumiMediaId(string input) + { + return IsIntId(input, "md"); + } + + /// + /// 是否为番剧media url + /// + /// + /// + public static bool IsBangumiMediaUrl(string input) + { + string id = GetBangumiId(input); + return IsBangumiMediaId(id); + } + + /// + /// 获取番剧media id + /// + /// + /// + public static long GetBangumiMediaId(string input) + { + if (IsBangumiMediaId(input)) + { + return Number.GetInt(input.Remove(0, 2)); + } + else if (IsBangumiMediaUrl(input)) + { + return Number.GetInt(GetBangumiId(input).Remove(0, 2)); + } + else + { + return -1; + } + } + + #endregion + + #region 课程 + + /// + /// 是否为课程season url + /// + /// + /// + public static bool IsCheeseSeasonUrl(string input) + { + string id = GetCheeseId(input); + return IsIntId(id, "ss"); + } + + /// + /// 获取课程season id + /// + /// + /// + public static long GetCheeseSeasonId(string input) + { + return IsCheeseSeasonUrl(input) ? Number.GetInt(GetCheeseId(input).Remove(0, 2)) : -1; + } + + /// + /// 是否为课程episode url + /// + /// + /// + public static bool IsCheeseEpisodeUrl(string input) + { + string id = GetCheeseId(input); + return IsIntId(id, "ep"); + } + + /// + /// 获取课程episode id + /// + /// + /// + public static long GetCheeseEpisodeId(string input) + { + return IsCheeseEpisodeUrl(input) ? Number.GetInt(GetCheeseId(input).Remove(0, 2)) : -1; + } + + #endregion + + #region 收藏夹 + + /// + /// 是否为收藏夹id + /// + /// + /// + public static bool IsFavoritesId(string input) + { + return IsIntId(input, "ml"); + } + + /// + /// 是否为收藏夹url + /// + /// + /// + public static bool IsFavoritesUrl(string input) + { + string favoritesId = GetId(input, FavoritesUrl); + return IsFavoritesId(favoritesId); + } + + /// + /// 获取收藏夹id + /// + /// + /// + public static long GetFavoritesId(string input) + { + if (IsFavoritesId(input)) + { + return Number.GetInt(input.Remove(0, 2)); + } + else if (IsFavoritesUrl(input)) + { + return Number.GetInt(GetId(input, FavoritesUrl).Remove(0, 2)); + } + else + { + return -1; + } + } + + #endregion + + #region 用户空间 + + /// + /// 是否为用户id + /// + /// + /// + public static bool IsUserId(string input) + { + if (input.ToLower().StartsWith("uid:")) + { + return Regex.IsMatch(input.Remove(0, 4), @"^\d+$"); + } + else if (input.ToLower().StartsWith("uid")) + { + return Regex.IsMatch(input.Remove(0, 3), @"^\d+$"); + } + else { return false; } + } + + /// + /// 是否为用户空间url + /// + /// + /// + public static bool IsUserUrl(string input) + { + string baseUrl = $"{SpaceUrl}/"; + string id = GetId(input, baseUrl); + return Number.IsInt(id); + } + + /// + /// 获取用户mid + /// + /// + /// + public static long GetUserId(string input) + { + if (input.ToLower().StartsWith("uid:")) + { + return Number.GetInt(input.Remove(0, 4)); + } + else if (input.ToLower().StartsWith("uid")) + { + return Number.GetInt(input.Remove(0, 3)); + } + else if (IsUserUrl(input)) + { + string baseUrl = $"{SpaceUrl}/"; + string id = GetId(input, baseUrl); + return Number.GetInt(id); + } + else + { + return -1; + } + } + + #endregion + + /// + /// 是否为网址 + /// + /// + /// + private static bool IsUrl(string input) + { + return input.StartsWith("http://") || input.StartsWith("https://"); + } + + /// + /// 将http转为https + /// + /// + private static string EnableHttps(string url) + { + if (!IsUrl(url)) { return null; } + + return url.Replace("http://", "https://"); + } + + /// + /// 去除url中的参数 + /// + /// + /// + private static string DeleteUrlParam(string url) + { + string[] strList = url.Split('?'); + + return strList[0].EndsWith("/") ? strList[0].TrimEnd('/') : strList[0]; + } + + /// + /// 从url中获取视频id(avid/bvid) + /// + /// + /// + private static string GetVideoId(string input) + { + return GetId(input, VideoUrl); + } + + /// + /// 从url中获取番剧id(ss/ep/md) + /// + /// + /// + private static string GetBangumiId(string input) + { + string id = GetId(input, BangumiUrl); + if (id != "") { return id; } + return GetId(input, BangumiMediaUrl); + } + + /// + /// 从url中获取课程id(ss/ep) + /// + /// + /// + private static string GetCheeseId(string input) + { + return GetId(input, CheeseUrl); + } + + /// + /// 是否为数字型id + /// + /// + /// + /// + private static bool IsIntId(string input, string prefix) + { + if (input.ToLower().StartsWith(prefix)) + { + return Regex.IsMatch(input.Remove(0, 2), @"^\d+$"); + } + return false; + } + + /// + /// 从url中获取id + /// + /// + /// + /// + private static string GetId(string input, string baseUrl) + { + if (!IsUrl(input)) { return ""; } + + string url = EnableHttps(input); + url = DeleteUrlParam(url); + + url = url.Replace(MobileUrl, WwwUrl); + + if (!url.StartsWith(baseUrl)) { return ""; } + + return url.Replace(baseUrl, ""); + } + + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/CheeseInfo.cs b/DownKyi.Core/BiliApi/Cheese/CheeseInfo.cs new file mode 100644 index 0000000..1393d5a --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/CheeseInfo.cs @@ -0,0 +1,70 @@ +using DownKyi.Core.BiliApi.Cheese.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; + +namespace DownKyi.Core.BiliApi.Cheese +{ + public static class CheeseInfo + { + + /// + /// 获取课程基本信息 + /// + /// + /// + /// + public static CheeseView CheeseViewInfo(long seasonId = -1, long episodeId = -1) + { + string baseUrl = "https://api.bilibili.com/pugv/view/web/season"; + string referer = "https://www.bilibili.com"; + string url; + if (seasonId > -1) { url = $"{baseUrl}?season_id={seasonId}"; } + else if (episodeId > -1) { url = $"{baseUrl}?ep_id={episodeId}"; } + else { return null; } + + string response = WebClient.RequestWeb(url, referer); + + try + { + var cheese = JsonConvert.DeserializeObject(response); + if (cheese != null) { return cheese.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("CheeseViewInfo()发生异常: {0}", e); + LogManager.Error("CheeseInfo", e); + return null; + } + } + + /// + /// 获取课程分集列表 + /// + /// + /// + /// + /// + public static CheeseEpisodeList CheeseEpisodeList(long seasonId, int ps = 50, int pn = 1) + { + string url = $"https://api.bilibili.com/pugv/view/web/ep/list?season_id={seasonId}&pn={pn}&ps={ps}"; + string referer = "https://www.bilibili.com"; + string response = WebClient.RequestWeb(url, referer); + + try + { + var cheese = JsonConvert.DeserializeObject(response); + if (cheese != null) { return cheese.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("CheeseEpisodeList()发生异常: {0}", e); + LogManager.Error("CheeseInfo", e); + return null; + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseBrief.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseBrief.cs new file mode 100644 index 0000000..2b0159a --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseBrief.cs @@ -0,0 +1,17 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + public class CheeseBrief : BaseModel + { + // content + [JsonProperty("img")] + public List Img { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisode.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisode.cs new file mode 100644 index 0000000..5643e3d --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisode.cs @@ -0,0 +1,43 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + public class CheeseEpisode : BaseModel + { + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("catalogue_index")] + public int CatalogueIndex { get; set; } + [JsonProperty("cid")] + public long Cid { get; set; } + [JsonProperty("cover")] + public string Cover { get; set; } + [JsonProperty("duration")] + public long Duration { get; set; } + [JsonProperty("from")] + public string From { get; set; } + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("index")] + public int Index { get; set; } + [JsonProperty("page")] + public int Page { get; set; } + [JsonProperty("play")] + public long Play { get; set; } + [JsonProperty("play_way")] + public int PlayWay { get; set; } + [JsonProperty("play_way_format")] + public string PlayWayFormat { get; set; } + [JsonProperty("release_date")] + public long ReleaseDate { get; set; } + [JsonProperty("status")] + public int Status { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("watched")] + public bool Watched { get; set; } + [JsonProperty("watchedHistory")] + public int WatchedHistory { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodeList.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodeList.cs new file mode 100644 index 0000000..aebc4c5 --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodeList.cs @@ -0,0 +1,26 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + // https://api.bilibili.com/pugv/view/web/ep/list + public class CheeseEpisodeListOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + [JsonProperty("data")] + public CheeseEpisodeList Data { get; set; } + } + + public class CheeseEpisodeList : BaseModel + { + [JsonProperty("items")] + public List Items { get; set; } + [JsonProperty("page")] + public CheeseEpisodePage Page { get; set; } + } + +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodePage.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodePage.cs new file mode 100644 index 0000000..d3145a3 --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodePage.cs @@ -0,0 +1,17 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + public class CheeseEpisodePage : BaseModel + { + [JsonProperty("next")] + public bool Next { get; set; } + [JsonProperty("num")] + public int Num { get; set; } + [JsonProperty("size")] + public int Size { get; set; } + [JsonProperty("total")] + public int Total { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseImg.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseImg.cs new file mode 100644 index 0000000..12a1fa1 --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseImg.cs @@ -0,0 +1,13 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + public class CheeseImg : BaseModel + { + [JsonProperty("aspect_ratio")] + public double AspectRatio { get; set; } + [JsonProperty("url")] + public string Url { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseStat.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseStat.cs new file mode 100644 index 0000000..226a41e --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseStat.cs @@ -0,0 +1,13 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + public class CheeseStat : BaseModel + { + [JsonProperty("play")] + public long Play { get; set; } + [JsonProperty("play_desc")] + public string PlayDesc { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseUpInfo.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseUpInfo.cs new file mode 100644 index 0000000..f1a8da8 --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseUpInfo.cs @@ -0,0 +1,23 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + public class CheeseUpInfo : BaseModel + { + [JsonProperty("avatar")] + public string Avatar { get; set; } + [JsonProperty("brief")] + public string Brief { get; set; } + [JsonProperty("follower")] + public long Follower { get; set; } + [JsonProperty("is_follow")] + public int IsFollow { get; set; } + [JsonProperty("link")] + public string Link { get; set; } + [JsonProperty("mid")] + public long Mid { get; set; } + [JsonProperty("uname")] + public string Name { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Cheese/Models/CheeseView.cs b/DownKyi.Core/BiliApi/Cheese/Models/CheeseView.cs new file mode 100644 index 0000000..a6349a3 --- /dev/null +++ b/DownKyi.Core/BiliApi/Cheese/Models/CheeseView.cs @@ -0,0 +1,69 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Cheese.Models +{ + // https://api.bilibili.com/pugv/view/web/season + public class CheeseViewOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + [JsonProperty("data")] + public CheeseView Data { get; set; } + } + + public class CheeseView : BaseModel + { + // active_market + // activity_list + [JsonProperty("brief")] + public CheeseBrief Brief { get; set; } + // cooperation + // coupon + // course_content + // courses + [JsonProperty("cover")] + public string Cover { get; set; } + // ep_catalogue + // ep_count + // episode_page + // episode_sort + // episode_tag + [JsonProperty("episodes")] + public List Episodes { get; set; } + // faq + // faq1 + // live_ep_count + // opened_ep_count + // payment + // previewed_purchase_note + // purchase_format_note + // purchase_note + // purchase_protocol + // recommend_seasons 推荐课程 + // release_bottom_info + // release_info + // release_info2 + // release_status + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("share_url")] + public string ShareUrl { get; set; } + // short_link + [JsonProperty("stat")] + public CheeseStat Stat { get; set; } + // status + [JsonProperty("subtitle")] + public string Subtitle { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("up_info")] + public CheeseUpInfo UpInfo { get; set; } + // update_status + // user_status + } + +} diff --git a/DownKyi.Core/BiliApi/Danmaku/DanmakuProtobuf.cs b/DownKyi.Core/BiliApi/Danmaku/DanmakuProtobuf.cs new file mode 100644 index 0000000..4bee84e --- /dev/null +++ b/DownKyi.Core/BiliApi/Danmaku/DanmakuProtobuf.cs @@ -0,0 +1,104 @@ +using Bilibili.Community.Service.Dm.V1; +using DownKyi.Core.BiliApi.Danmaku.Models; +using System; +using System.Collections.Generic; +using System.IO; + +namespace DownKyi.Core.BiliApi.Danmaku +{ + public static class DanmakuProtobuf + { + + /// + /// 下载6分钟内的弹幕,返回弹幕列表 + /// + /// 稿件avID + /// 视频CID + /// 分包,每6分钟一包 + /// + public static List GetDanmakuProto(long avid, long cid, int segmentIndex) + { + string url = $"https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid={cid}&pid={avid}&segment_index={segmentIndex}"; + //string referer = "https://www.bilibili.com"; + + string directory = Path.Combine(Storage.StorageManager.GetDanmaku(), $"{cid}"); + string filePath = Path.Combine(directory, $"{segmentIndex}.proto"); + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + try + { + System.Net.WebClient mywebclient = new System.Net.WebClient(); + mywebclient.DownloadFile(url, filePath); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetDanmakuProto()发生异常: {0}", e); + //Logging.LogManager.Error(e); + } + + var danmakuList = new List(); + try + { + using (var input = File.OpenRead(filePath)) + { + DmSegMobileReply danmakus = DmSegMobileReply.Parser.ParseFrom(input); + if (danmakus == null || danmakus.Elems == null) + { + return danmakuList; + } + + foreach (var dm in danmakus.Elems) + { + var danmaku = new BiliDanmaku + { + Id = dm.Id, + Progress = dm.Progress, + Mode = dm.Mode, + Fontsize = dm.Fontsize, + Color = dm.Color, + MidHash = dm.MidHash, + Content = dm.Content, + Ctime = dm.Ctime, + Weight = dm.Weight, + //Action = dm.Action, + Pool = dm.Pool + }; + danmakuList.Add(danmaku); + } + } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetDanmakuProto()发生异常: {0}", e); + //Logging.LogManager.Error(e); + return null; + } + + return danmakuList; + } + + /// + /// 下载所有弹幕,返回弹幕列表 + /// + /// 稿件avID + /// 视频CID + /// + public static List GetAllDanmakuProto(long avid, long cid) + { + var danmakuList = new List(); + + int segmentIndex = 0; + while (true) + { + segmentIndex += 1; + var danmakus = GetDanmakuProto(avid, cid, segmentIndex); + if (danmakus == null) { break; } + danmakuList.AddRange(danmakus); + } + return danmakuList; + } + } +} diff --git a/DownKyi.Core/BiliApi/Danmaku/Models/BiliDanmaku.cs b/DownKyi.Core/BiliApi/Danmaku/Models/BiliDanmaku.cs new file mode 100644 index 0000000..48892ba --- /dev/null +++ b/DownKyi.Core/BiliApi/Danmaku/Models/BiliDanmaku.cs @@ -0,0 +1,33 @@ +namespace DownKyi.Core.BiliApi.Danmaku.Models +{ + public class BiliDanmaku + { + public long Id { get; set; } //弹幕dmID + public int Progress { get; set; } //出现时间 + public int Mode { get; set; } //弹幕类型 + public int Fontsize { get; set; } //文字大小 + public uint Color { get; set; } //弹幕颜色 + public string MidHash { get; set; } //发送者UID的HASH + public string Content { get; set; } //弹幕内容 + public long Ctime { get; set; } //发送时间 + public int Weight { get; set; } //权重 + //public string Action { get; set; } //动作? + public int Pool { get; set; } //弹幕池 + + public override string ToString() + { + string separator = "\n"; + return $"id: {Id}{separator}" + + $"progress: {Progress}{separator}" + + $"mode: {Mode}{separator}" + + $"fontsize: {Fontsize}{separator}" + + $"color: {Color}{separator}" + + $"midHash: {MidHash}{separator}" + + $"content: {Content}{separator}" + + $"ctime: {Ctime}{separator}" + + $"weight: {Weight}{separator}" + + //$"action: {Action}{separator}" + + $"pool: {Pool}"; + } + } +} diff --git a/DownKyi.Core/BiliApi/Login/LoginHelper.cs b/DownKyi.Core/BiliApi/Login/LoginHelper.cs new file mode 100644 index 0000000..342c893 --- /dev/null +++ b/DownKyi.Core/BiliApi/Login/LoginHelper.cs @@ -0,0 +1,147 @@ +using DownKyi.Core.Settings; +using DownKyi.Core.Settings.Models; +using DownKyi.Core.Utils; +using DownKyi.Core.Utils.Encryptor; +using System; +using System.IO; +using System.Net; + +namespace DownKyi.Core.BiliApi.Login +{ + public static class LoginHelper + { + // 本地位置 + private static readonly string LOCAL_LOGIN_INFO = Storage.StorageManager.GetLogin(); + + // 16位密码,ps:密码位数没有限制,可任意设置 + private static readonly string SecretKey = "EsOat*^y1QR!&0J6"; + + /// + /// 保存登录的cookies到文件 + /// + /// + /// + public static bool SaveLoginInfoCookies(string url) + { + string tempFile = LOCAL_LOGIN_INFO + "-" + Guid.NewGuid().ToString("N"); + CookieContainer cookieContainer = ObjectHelper.ParseCookie(url); + + bool isSucceed = ObjectHelper.WriteCookiesToDisk(tempFile, cookieContainer); + if (isSucceed) + { + // 加密密钥,增加机器码 + string password = SecretKey + MachineCode.GetMachineCodeString(); + + try + { + Encryptor.EncryptFile(tempFile, LOCAL_LOGIN_INFO, password); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("SaveLoginInfoCookies()发生异常: {0}", e); + Logging.LogManager.Error(e); + return false; + } + } + + if (File.Exists(tempFile)) + { + File.Delete(tempFile); + } + return isSucceed; + } + + + /// + /// 获得登录的cookies + /// + /// + public static CookieContainer GetLoginInfoCookies() + { + string tempFile = LOCAL_LOGIN_INFO + "-" + Guid.NewGuid().ToString("N"); + + if (File.Exists(LOCAL_LOGIN_INFO)) + { + try + { + // 加密密钥,增加机器码 + string password = SecretKey + MachineCode.GetMachineCodeString(); + Encryptor.DecryptFile(LOCAL_LOGIN_INFO, tempFile, password); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetLoginInfoCookies()发生异常: {0}", e); + Logging.LogManager.Error(e); + if (File.Exists(tempFile)) + { + File.Delete(tempFile); + } + return null; + } + } + else { return null; } + + CookieContainer cookies = ObjectHelper.ReadCookiesFromDisk(tempFile); + + if (File.Exists(tempFile)) + { + File.Delete(tempFile); + } + return cookies; + } + + /// + /// 返回登录信息的cookies的字符串 + /// + /// + public static string GetLoginInfoCookiesString() + { + var cookieContainer = GetLoginInfoCookies(); + if (cookieContainer == null) + { + return ""; + } + + var cookies = ObjectHelper.GetAllCookies(cookieContainer); + + string cookie = string.Empty; + foreach (var item in cookies) + { + cookie += item.ToString() + ";"; + } + return cookie.TrimEnd(';'); + } + + /// + /// 注销登录 + /// + /// + public static bool Logout() + { + if (File.Exists(LOCAL_LOGIN_INFO)) + { + try + { + File.Delete(LOCAL_LOGIN_INFO); + + SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings + { + Mid = -1, + Name = "", + IsLogin = false, + IsVip = false + }); + return true; + } + catch (IOException e) + { + Utils.Debug.Console.PrintLine("Logout()发生异常: {0}", e); + Logging.LogManager.Error(e); + return false; + } + } + return false; + } + + } +} diff --git a/DownKyi.Core/BiliApi/Login/LoginInfo.cs b/DownKyi.Core/BiliApi/Login/LoginInfo.cs new file mode 100644 index 0000000..2931f0c --- /dev/null +++ b/DownKyi.Core/BiliApi/Login/LoginInfo.cs @@ -0,0 +1,40 @@ +using DownKyi.Core.BiliApi.Login.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; + +namespace DownKyi.Core.BiliApi.Login +{ + /// + /// 登录基本信息 + /// + public static class LoginInfo + { + + /// + /// 导航栏用户信息 + /// + /// + public static UserInfoForNavigation GetUserInfoForNavigation() + { + string url = "https://api.bilibili.com/x/web-interface/nav"; + string referer = "https://www.bilibili.com"; + string response = WebClient.RequestWeb(url, referer); + + try + { + var userInfo = JsonConvert.DeserializeObject(response); + if (userInfo == null || userInfo.Data == null) { return null; } + + if (userInfo.Data.IsLogin) { return userInfo.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetUserInfoForNavigation()发生异常: {0}", e); + LogManager.Error("LoginInfo", e); + return null; + } + } + } +} diff --git a/DownKyi.Core/BiliApi/Login/LoginQR.cs b/DownKyi.Core/BiliApi/Login/LoginQR.cs new file mode 100644 index 0000000..1ad3544 --- /dev/null +++ b/DownKyi.Core/BiliApi/Login/LoginQR.cs @@ -0,0 +1,138 @@ +using DownKyi.Core.BiliApi.Login.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Windows.Media.Imaging; + +namespace DownKyi.Core.BiliApi.Login +{ + /// + /// 二维码登录 + /// + public static class LoginQR + { + /// + /// 申请二维码URL及扫码密钥(web端) + /// + /// + public static LoginUrlOrigin GetLoginUrl() + { + string getLoginUrl = "https://passport.bilibili.com/qrcode/getLoginUrl"; + string referer = "https://passport.bilibili.com/login"; + string response = WebClient.RequestWeb(getLoginUrl, referer); + + try + { + var loginUrl = JsonConvert.DeserializeObject(response); + return loginUrl; + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetLoginUrl()发生异常: {0}", e); + LogManager.Error("LoginQR", e); + return null; + } + } + + /// + /// 使用扫码登录(web端) + /// + /// + /// + /// + public static LoginStatus GetLoginStatus(string oauthKey, string goUrl = "https://www.bilibili.com") + { + string url = "https://passport.bilibili.com/qrcode/getLoginInfo"; + string referer = "https://passport.bilibili.com/login"; + + Dictionary parameters = new Dictionary + { + { "oauthKey", oauthKey }, + { "gourl", goUrl } + }; + + string response = WebClient.RequestWeb(url, referer, "POST", parameters); + var loginInfo = new LoginStatus(); + + try + { + if (response.Contains("\"code\":0") || response.Contains("\"code\": 0")) + { + var ready = JsonConvert.DeserializeObject(response); + if (ready == null) + { return null; } + + loginInfo.Code = ready.Code; + loginInfo.Status = ready.Status; + loginInfo.Message = "登录成功"; + loginInfo.Url = ready.Data.Url; + } + else + { + var scanning = JsonConvert.DeserializeObject(response); + if (scanning == null) + { return null; } + + loginInfo.Code = scanning.Data; + loginInfo.Status = scanning.Status; + loginInfo.Message = scanning.Message; + loginInfo.Url = ""; + } + + return loginInfo; + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetLoginInfo()发生异常: {0}", e); + LogManager.Error("LoginQR", e); + return null; + } + } + + + /// + /// 获得登录二维码 + /// + /// + public static BitmapImage GetLoginQRCode() + { + try + { + string loginUrl = GetLoginUrl().Data.Url; + return GetLoginQRCode(loginUrl); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetLoginQRCode()发生异常: {0}", e); + LogManager.Error("LoginQR", e); + return null; + } + } + + /// + /// 根据输入url生成二维码 + /// + /// + /// + public static BitmapImage GetLoginQRCode(string url) + { + // 设置的参数影响app能否成功扫码 + Bitmap qrCode = Utils.QRCode.EncodeQRCode(url, 10, 10, null, 0, 0, false); + + MemoryStream ms = new MemoryStream(); + qrCode.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); + byte[] bytes = ms.GetBuffer(); + ms.Close(); + + BitmapImage image = new BitmapImage(); + image.BeginInit(); + image.StreamSource = new MemoryStream(bytes); + image.EndInit(); + return image; + } + + } +} diff --git a/DownKyi.Core/BiliApi/Login/Models/LoginStatus.cs b/DownKyi.Core/BiliApi/Login/Models/LoginStatus.cs new file mode 100644 index 0000000..2d6a599 --- /dev/null +++ b/DownKyi.Core/BiliApi/Login/Models/LoginStatus.cs @@ -0,0 +1,49 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Login.Models +{ + // https://passport.bilibili.com/qrcode/getLoginInfo + [JsonObject] + public class LoginStatus : BaseModel + { + [JsonProperty("code")] + public int Code { get; set; } + [JsonProperty("status")] + public bool Status { get; set; } + [JsonProperty("message")] + public string Message { get; set; } + [JsonProperty("url")] + public string Url { get; set; } + } + + [JsonObject] + public class LoginStatusScanning : BaseModel + { + [JsonProperty("status")] + public bool Status { get; set; } + [JsonProperty("data")] + public int Data { get; set; } + [JsonProperty("message")] + public string Message { get; set; } + } + + [JsonObject] + public class LoginStatusReady : BaseModel + { + [JsonProperty("code")] + public int Code { get; set; } + [JsonProperty("status")] + public bool Status { get; set; } + //public long ts { get; set; } + [JsonProperty("data")] + public LoginStatusData Data { get; set; } + } + + [JsonObject] + public class LoginStatusData : BaseModel + { + [JsonProperty("url")] + public string Url { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Login/Models/LoginUrl.cs b/DownKyi.Core/BiliApi/Login/Models/LoginUrl.cs new file mode 100644 index 0000000..f494a78 --- /dev/null +++ b/DownKyi.Core/BiliApi/Login/Models/LoginUrl.cs @@ -0,0 +1,26 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Login.Models +{ + // https://passport.bilibili.com/qrcode/getLoginUrl + [JsonObject] + public class LoginUrlOrigin : BaseModel + { + //public int code { get; set; } + [JsonProperty("data")] + public LoginUrl Data { get; set; } + [JsonProperty("status")] + public bool Status { get; set; } + //public long ts { get; set; } + } + + [JsonObject] + public class LoginUrl : BaseModel + { + [JsonProperty("oauthKey")] + public string OauthKey { get; set; } + [JsonProperty("url")] + public string Url { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Login/Models/UserInfoForNavigation.cs b/DownKyi.Core/BiliApi/Login/Models/UserInfoForNavigation.cs new file mode 100644 index 0000000..42eedf5 --- /dev/null +++ b/DownKyi.Core/BiliApi/Login/Models/UserInfoForNavigation.cs @@ -0,0 +1,108 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Login.Models +{ + // https://api.bilibili.com/x/web-interface/nav + [JsonObject] + public class UserInfoForNavigationOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + [JsonProperty("data")] + public UserInfoForNavigation Data { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + } + + [JsonObject] + public class UserInfoForNavigation : BaseModel + { + //public int allowance_count { get; set; } + //public int answer_status { get; set; } + //public int email_verified { get; set; } + [JsonProperty("face")] + public string Face { get; set; } + //public bool has_shop { get; set; } + [JsonProperty("isLogin")] + public bool IsLogin { get; set; } + //public NavDataLevelInfo level_info { get; set; } + [JsonProperty("mid")] + public long Mid { get; set; } + //public int mobile_verified { get; set; } + [JsonProperty("money")] + public float Money { get; set; } + //public int moral { get; set; } + //public NavDataOfficial official { get; set; } + //public NavDataOfficialVerify officialVerify { get; set; } + //public NavDataPendant pendant { get; set; } + //public int scores { get; set; } + //public string shop_url { get; set; } + [JsonProperty("uname")] + public string Name { get; set; } + //public long vipDueDate { get; set; } + [JsonProperty("vipStatus")] + public int VipStatus { get; set; } + //public int vipType { get; set; } + //public int vip_avatar_subscript { get; set; } + //public NavDataVipLabel vip_label { get; set; } + //public string vip_nickname_color { get; set; } + //public int vip_pay_type { get; set; } + //public int vip_theme_type { get; set; } + [JsonProperty("wallet")] + public UserInfoWallet Wallet { get; set; } + } + + //public class NavDataLevelInfo + //{ + // public int current_exp { get; set; } + // public int current_level { get; set; } + // public int current_min { get; set; } + // //public int next_exp { get; set; } // 当等级为6时,next_exp为string类型,值为"--" + //} + + //public class NavDataOfficial + //{ + // public string desc { get; set; } + // public int role { get; set; } + // public string title { get; set; } + // public int type { get; set; } + //} + + //public class NavDataOfficialVerify + //{ + // public string desc { get; set; } + // public int type { get; set; } + //} + + //public class NavDataPendant + //{ + // public int expire { get; set; } + // public string image { get; set; } + // public string image_enhance { get; set; } + // public string name { get; set; } + // public int pid { get; set; } + //} + + //public class NavDataVipLabel + //{ + // public string label_theme { get; set; } + // public string path { get; set; } + // public string text { get; set; } + //} + + [JsonObject] + public class UserInfoWallet : BaseModel + { + [JsonProperty("bcoin_balance")] + public float BcoinBalance { get; set; } + [JsonProperty("coupon_balance")] + public float CouponBalance { get; set; } + [JsonProperty("coupon_due_time")] + public long CouponDueTime { get; set; } + [JsonProperty("mid")] + public long Mid { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Models/BaseModel.cs b/DownKyi.Core/BiliApi/Models/BaseModel.cs new file mode 100644 index 0000000..c0d4152 --- /dev/null +++ b/DownKyi.Core/BiliApi/Models/BaseModel.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Models +{ + public abstract class BaseModel + { + public string ToString(string format = "") + { + // 设置为去掉null + var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + + switch (format) + { + case "": + return JsonConvert.SerializeObject(this); + case "F": + // 整理json格式 + return JsonConvert.SerializeObject(this, Formatting.Indented); + case "N": + // 去掉null后,转换为json字符串 + return JsonConvert.SerializeObject(this, Formatting.None, jsonSetting); + case "FN": + case "NF": + return JsonConvert.SerializeObject(this, Formatting.Indented, jsonSetting); + default: + return ToString(); + } + } + } +} diff --git a/DownKyi.Core/BiliApi/Models/Dimension.cs b/DownKyi.Core/BiliApi/Models/Dimension.cs new file mode 100644 index 0000000..41ea536 --- /dev/null +++ b/DownKyi.Core/BiliApi/Models/Dimension.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Models +{ + public class Dimension : BaseModel + { + [JsonProperty("width")] + public int Width { get; set; } + [JsonProperty("height")] + public int Height { get; set; } + [JsonProperty("rotate")] + public int Rotate { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Models/VideoOwner.cs b/DownKyi.Core/BiliApi/Models/VideoOwner.cs new file mode 100644 index 0000000..eaeb6d3 --- /dev/null +++ b/DownKyi.Core/BiliApi/Models/VideoOwner.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Models +{ + public class VideoOwner : BaseModel + { + [JsonProperty("mid")] + public long Mid { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("face")] + public string Face { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Dynamic.cs b/DownKyi.Core/BiliApi/Video/Dynamic.cs new file mode 100644 index 0000000..330b8c8 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Dynamic.cs @@ -0,0 +1,40 @@ +using DownKyi.Core.BiliApi.Video.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video +{ + public static class Dynamic + { + + /// + /// 获取分区最新视频列表 + /// + /// 目标分区tid + /// 页码 + /// 每页项数(最大50) + /// + public static List RegionDynamicList(int rid, int pn = 1, int ps = 5) + { + string url = $"https://api.bilibili.com/x/web-interface/dynamic/region?rid={rid}&pn={pn}&ps={ps}"; + string referer = "https://www.bilibili.com"; + string response = WebClient.RequestWeb(url, referer); + + try + { + var dynamic = JsonConvert.DeserializeObject(response); + if (dynamic != null && dynamic.Data != null) { return dynamic.Data.Archives; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("RegionDynamicList()发生异常: {0}", e); + LogManager.Error("Dynamic", e); + return null; + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/DynamicVideoView.cs b/DownKyi.Core/BiliApi/Video/Models/DynamicVideoView.cs new file mode 100644 index 0000000..1c59504 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/DynamicVideoView.cs @@ -0,0 +1,55 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class DynamicVideoView : BaseModel + { + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("videos")] + public int Videos { get; set; } + [JsonProperty("tid")] + public int Tid { get; set; } + [JsonProperty("tname")] + public string Tname { get; set; } + [JsonProperty("copyright")] + public int Copyright { get; set; } + [JsonProperty("pic")] + public string Pic { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("pubdate")] + public long Pubdate { get; set; } + [JsonProperty("ctime")] + public long Ctime { get; set; } + [JsonProperty("desc")] + public string Desc { get; set; } + [JsonProperty("state")] + public int State { get; set; } + [JsonProperty("duration")] + public long Duration { get; set; } + [JsonProperty("owner")] + public VideoOwner Owner { get; set; } + [JsonProperty("stat")] + public VideoStat Stat { get; set; } + [JsonProperty("dynamic")] + public string Dynamic { get; set; } + [JsonProperty("cid")] + public long Cid { get; set; } + [JsonProperty("dimension")] + public Dimension Dimension { get; set; } + [JsonProperty("short_link")] + public string ShortLink { get; set; } + [JsonProperty("short_link_v2")] + public string ShortLinkV2 { get; set; } + [JsonProperty("first_frame")] + public string FirstFrame { get; set; } + [JsonProperty("bvid")] + public string Bvid { get; set; } + [JsonProperty("season_type")] + public int SeasonType { get; set; } + [JsonProperty("is_ogv")] + public bool IsOgv { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/RankingVideoView.cs b/DownKyi.Core/BiliApi/Video/Models/RankingVideoView.cs new file mode 100644 index 0000000..87bc072 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/RankingVideoView.cs @@ -0,0 +1,47 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class RankingVideoView : BaseModel + { + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("bvid")] + public string Bvid { get; set; } + [JsonProperty("typename")] + public string TypeName { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("subtitle")] + public string Subtitle { get; set; } + [JsonProperty("play")] + public long Play { get; set; } + [JsonProperty("review")] + public long Review { get; set; } + [JsonProperty("video_review")] + public long VideoReview { get; set; } + [JsonProperty("favorites")] + public long Favorites { get; set; } + [JsonProperty("mid")] + public long Mid { get; set; } + [JsonProperty("author")] + public string Author { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("create")] + public string Create { get; set; } + [JsonProperty("pic")] + public string Pic { get; set; } + [JsonProperty("coins")] + public long Coins { get; set; } + [JsonProperty("duration")] + public string Duration { get; set; } + [JsonProperty("badgepay")] + public bool Badgepay { get; set; } + [JsonProperty("pts")] + public long Pts { get; set; } + [JsonProperty("redirect_url")] + public string RedirectUrl { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/RegionDynamic.cs b/DownKyi.Core/BiliApi/Video/Models/RegionDynamic.cs new file mode 100644 index 0000000..ffbb66d --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/RegionDynamic.cs @@ -0,0 +1,27 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + // https://api.bilibili.com/x/web-interface/dynamic/region + public class RegionDynamicOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("data")] + public RegionDynamic Data { get; set; } + } + + public class RegionDynamic : BaseModel + { + [JsonProperty("archives")] + public List Archives { get; set; } + // page + } + +} diff --git a/DownKyi.Core/BiliApi/Video/Models/RegionRanking.cs b/DownKyi.Core/BiliApi/Video/Models/RegionRanking.cs new file mode 100644 index 0000000..d0f7340 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/RegionRanking.cs @@ -0,0 +1,20 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + // https://api.bilibili.com/x/web-interface/ranking/region + public class RegionRanking : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("data")] + public List Data { get; set; } + } + +} diff --git a/DownKyi.Core/BiliApi/Video/Models/UgcArc.cs b/DownKyi.Core/BiliApi/Video/Models/UgcArc.cs new file mode 100644 index 0000000..301d44f --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/UgcArc.cs @@ -0,0 +1,43 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class UgcArc : BaseModel + { + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("videos")] + public int Videos { get; set; } + [JsonProperty("type_id")] + public int TypeId { get; set; } + [JsonProperty("type_name")] + public string TypeName { get; set; } + [JsonProperty("copyright")] + public int Copyright { get; set; } + [JsonProperty("pic")] + public string Pic { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("pubdate")] + public long Pubdate { get; set; } + [JsonProperty("ctime")] + public long Ctime { get; set; } + [JsonProperty("desc")] + public string Desc { get; set; } + [JsonProperty("state")] + public int State { get; set; } + [JsonProperty("duration")] + public long Duration { get; set; } + //[JsonProperty("rights")] + //public VideoRights Rights { get; set; } + [JsonProperty("author")] + public VideoOwner Author { get; set; } + [JsonProperty("stat")] + public VideoStat Stat { get; set; } + [JsonProperty("dynamic")] + public string Dynamic { get; set; } + [JsonProperty("dimension")] + public Dimension Dimension { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/UgcEpisode.cs b/DownKyi.Core/BiliApi/Video/Models/UgcEpisode.cs new file mode 100644 index 0000000..0a7a5e9 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/UgcEpisode.cs @@ -0,0 +1,29 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class UgcEpisode : BaseModel + { + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("section_id")] + public long SectionId { get; set; } + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("cid")] + public long Cid { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("attribute")] + public int Attribute { get; set; } + [JsonProperty("arc")] + public UgcArc Arc { get; set; } + [JsonProperty("page")] + public VideoPage Page { get; set; } + [JsonProperty("bvid")] + public string Bvid { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/UgcSeason.cs b/DownKyi.Core/BiliApi/Video/Models/UgcSeason.cs new file mode 100644 index 0000000..cf92b20 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/UgcSeason.cs @@ -0,0 +1,32 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class UgcSeason : BaseModel + { + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("cover")] + public string Cover { get; set; } + [JsonProperty("mid")] + public long Mid { get; set; } + [JsonProperty("intro")] + public string Intro { get; set; } + [JsonProperty("sign_state")] + public int SignState { get; set; } + [JsonProperty("attribute")] + public int Attribute { get; set; } + [JsonProperty("sections")] + public List Sections { get; set; } + [JsonProperty("stat")] + public UgcStat Stat { get; set; } + [JsonProperty("ep_count")] + public int EpCount { get; set; } + [JsonProperty("season_type")] + public int SeasonType { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/UgcSection.cs b/DownKyi.Core/BiliApi/Video/Models/UgcSection.cs new file mode 100644 index 0000000..e3eccd8 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/UgcSection.cs @@ -0,0 +1,20 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class UgcSection : BaseModel + { + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("type")] + public int Type { get; set; } + [JsonProperty("episodes")] + public List Episodes { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/UgcStat.cs b/DownKyi.Core/BiliApi/Video/Models/UgcStat.cs new file mode 100644 index 0000000..325eb16 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/UgcStat.cs @@ -0,0 +1,29 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class UgcStat : BaseModel + { + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("view")] + public long View { get; set; } + [JsonProperty("danmaku")] + public long Danmaku { get; set; } + [JsonProperty("reply")] + public long Reply { get; set; } + [JsonProperty("fav")] + public long Favorite { get; set; } + [JsonProperty("coin")] + public long Coin { get; set; } + [JsonProperty("share")] + public long Share { get; set; } + [JsonProperty("now_rank")] + public long NowRank { get; set; } + [JsonProperty("his_rank")] + public long HisRank { get; set; } + [JsonProperty("like")] + public long Like { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/VideoDescription.cs b/DownKyi.Core/BiliApi/Video/Models/VideoDescription.cs new file mode 100644 index 0000000..c03379c --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/VideoDescription.cs @@ -0,0 +1,18 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + // https://api.bilibili.com/x/web-interface/archive/desc + public class VideoDescription : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("data")] + public string Data { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/VideoPage.cs b/DownKyi.Core/BiliApi/Video/Models/VideoPage.cs new file mode 100644 index 0000000..bcde7ba --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/VideoPage.cs @@ -0,0 +1,25 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class VideoPage : BaseModel + { + [JsonProperty("cid")] + public long Cid { get; set; } + [JsonProperty("page")] + public int Page { get; set; } + [JsonProperty("from")] + public string From { get; set; } + [JsonProperty("part")] + public string Part { get; set; } + [JsonProperty("duration")] + public long Duration { get; set; } + [JsonProperty("vid")] + public string Vid { get; set; } + [JsonProperty("weblink")] + public string Weblink { get; set; } + [JsonProperty("dimension")] + public Dimension Dimension { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/VideoPagelist.cs b/DownKyi.Core/BiliApi/Video/Models/VideoPagelist.cs new file mode 100644 index 0000000..f958b50 --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/VideoPagelist.cs @@ -0,0 +1,19 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + // https://api.bilibili.com/x/player/pagelist + public class VideoPagelist : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("data")] + public List Data { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/VideoStat.cs b/DownKyi.Core/BiliApi/Video/Models/VideoStat.cs new file mode 100644 index 0000000..d76d56d --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/VideoStat.cs @@ -0,0 +1,35 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class VideoStat : BaseModel + { + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("view")] + public long View { get; set; } + [JsonProperty("danmaku")] + public long Danmaku { get; set; } + [JsonProperty("reply")] + public long Reply { get; set; } + [JsonProperty("favorite")] + public long Favorite { get; set; } + [JsonProperty("coin")] + public long Coin { get; set; } + [JsonProperty("share")] + public long Share { get; set; } + [JsonProperty("now_rank")] + public long NowRank { get; set; } + [JsonProperty("his_rank")] + public long HisRank { get; set; } + [JsonProperty("like")] + public long Like { get; set; } + [JsonProperty("dislike")] + public long Dislike { get; set; } + [JsonProperty("evaluation")] + public string Evaluation { get; set; } + [JsonProperty("argue_msg")] + public string ArgueMsg { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Models/VideoSubtitle.cs b/DownKyi.Core/BiliApi/Video/Models/VideoSubtitle.cs new file mode 100644 index 0000000..0d88d8e --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/VideoSubtitle.cs @@ -0,0 +1,55 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + public class VideoSubtitle : BaseModel + { + [JsonProperty("allow_submit")] + public bool AllowSubmit { get; set; } + [JsonProperty("list")] + public List List { get; set; } + } + + public class Subtitle : BaseModel + { + [JsonProperty("id")] + public long Id { get; set; } + [JsonProperty("lan")] + public string Lan { get; set; } + [JsonProperty("lan_doc")] + public string LanDoc { get; set; } + [JsonProperty("is_lock")] + public bool IsLock { get; set; } + [JsonProperty("author_mid")] + public long AuthorMid { get; set; } + [JsonProperty("subtitle_url")] + public string SubtitleUrl { get; set; } + [JsonProperty("author")] + public SubtitleAuthor Author { get; set; } + } + + public class SubtitleAuthor : BaseModel + { + [JsonProperty("mid")] + public long Mid { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("sex")] + public string Sex { get; set; } + [JsonProperty("face")] + public string Face { get; set; } + [JsonProperty("sign")] + public string Sign { get; set; } + //[JsonProperty("rank")] + //public int Rank { get; set; } + //[JsonProperty("birthday")] + //public int Birthday { get; set; } + //[JsonProperty("is_fake_account")] + //public int IsFakeAccount { get; set; } + //[JsonProperty("is_deleted")] + //public int IsDeleted { get; set; } + } + +} diff --git a/DownKyi.Core/BiliApi/Video/Models/VideoView.cs b/DownKyi.Core/BiliApi/Video/Models/VideoView.cs new file mode 100644 index 0000000..42a24cf --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Models/VideoView.cs @@ -0,0 +1,81 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video.Models +{ + // https://api.bilibili.com/x/web-interface/view + public class VideoViewOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("data")] + public VideoView Data { get; set; } + } + + public class VideoView : BaseModel + { + [JsonProperty("bvid")] + public string Bvid { get; set; } + [JsonProperty("aid")] + public long Aid { get; set; } + [JsonProperty("videos")] + public int Videos { get; set; } + [JsonProperty("tid")] + public int Tid { get; set; } + [JsonProperty("tname")] + public string Tname { get; set; } + [JsonProperty("copyright")] + public int Copyright { get; set; } + [JsonProperty("pic")] + public string Pic { get; set; } + [JsonProperty("title")] + public string Title { get; set; } + [JsonProperty("pubdate")] + public long Pubdate { get; set; } + [JsonProperty("ctime")] + public long Ctime { get; set; } + [JsonProperty("desc")] + public string Desc { get; set; } + [JsonProperty("state")] + public int State { get; set; } + [JsonProperty("duration")] + public long Duration { get; set; } + [JsonProperty("redirect_url")] + public string RedirectUrl { get; set; } + [JsonProperty("mission_id")] + public long MissionId { get; set; } + //[JsonProperty("rights")] + //public VideoRights Rights { get; set; } + [JsonProperty("owner")] + public VideoOwner Owner { get; set; } + [JsonProperty("stat")] + public VideoStat Stat { get; set; } + [JsonProperty("dynamic")] + public string Dynamic { get; set; } + [JsonProperty("cid")] + public long Cid { get; set; } + [JsonProperty("dimension")] + public Dimension Dimension { get; set; } + [JsonProperty("season_id")] + public long SeasonId { get; set; } + [JsonProperty("festival_jump_url")] + public string FestivalJumpUrl { get; set; } + //[JsonProperty("no_cache")] + //public bool no_cache { get; set; } + [JsonProperty("pages")] + public List Pages { get; set; } + [JsonProperty("subtitle")] + public VideoSubtitle Subtitle { get; set; } + [JsonProperty("ugc_season")] + public UgcSeason UgcSeason { get; set; } + //[JsonProperty("staff")] + //public List staff { get; set; } + //[JsonProperty("user_garb")] + //public user_garb user_garb { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/Video/Ranking.cs b/DownKyi.Core/BiliApi/Video/Ranking.cs new file mode 100644 index 0000000..16ac56d --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/Ranking.cs @@ -0,0 +1,40 @@ +using DownKyi.Core.BiliApi.Video.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video +{ + public static class Ranking + { + + /// + /// 获取分区视频排行榜列表 + /// + /// 目标分区tid + /// 3日榜或周榜(3/7) + /// + /// + public static List RegionRankingList(int rid, int day = 3, int original = 0) + { + string url = $"https://api.bilibili.com/x/web-interface/ranking/region?rid={rid}&day={day}&ps={original}"; + string referer = "https://www.bilibili.com"; + string response = WebClient.RequestWeb(url, referer); + + try + { + var ranking = JsonConvert.DeserializeObject(response); + if (ranking != null) { return ranking.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("RegionRankingList()发生异常: {0}", e); + LogManager.Error("Ranking", e); + return null; + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/Video/VideoInfo.cs b/DownKyi.Core/BiliApi/Video/VideoInfo.cs new file mode 100644 index 0000000..aa0764d --- /dev/null +++ b/DownKyi.Core/BiliApi/Video/VideoInfo.cs @@ -0,0 +1,105 @@ +using DownKyi.Core.BiliApi.Video.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Video +{ + public static class VideoInfo + { + /// + /// 获取视频详细信息(web端) + /// + /// + /// + /// + public static VideoView VideoViewInfo(string bvid = null, long aid = -1) + { + string baseUrl = "https://api.bilibili.com/x/web-interface/view"; + string referer = "https://www.bilibili.com"; + string url; + if (bvid != null) { url = $"{baseUrl}?bvid={bvid}"; } + else if (aid > -1) { url = $"{baseUrl}?aid={aid}"; } + else { return null; } + + string response = WebClient.RequestWeb(url, referer); + + try + { + var videoView = JsonConvert.DeserializeObject(response); + if (videoView != null) { return videoView.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("VideoInfo()发生异常: {0}", e); + LogManager.Error("VideoInfo", e); + return null; + } + } + + /// + /// 获取视频简介 + /// + /// + /// + /// + public static string VideoDescription(string bvid = null, long aid = -1) + { + string baseUrl = "https://api.bilibili.com/x/web-interface/archive/desc"; + string referer = "https://www.bilibili.com"; + string url; + if (bvid != null) { url = $"{baseUrl}?bvid={bvid}"; } + else if (aid >= -1) { url = $"{baseUrl}?aid={aid}"; } + else { return null; } + + string response = WebClient.RequestWeb(url, referer); + + try + { + var desc = JsonConvert.DeserializeObject(response); + if (desc != null) { return desc.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("VideoDescription()发生异常: {0}", e); + LogManager.Error("VideoInfo", e); + return null; + } + } + + /// + /// 查询视频分P列表 (avid/bvid转cid) + /// + /// + /// + /// + public static List VideoPagelist(string bvid = null, long aid = -1) + { + string baseUrl = "https://api.bilibili.com/x/player/pagelist"; + string referer = "https://www.bilibili.com"; + string url; + if (bvid != null) { url = $"{baseUrl}?bvid={bvid}"; } + else if (aid > -1) { url = $"{baseUrl}?aid={aid}"; } + else { return null; } + + string response = WebClient.RequestWeb(url, referer); + + try + { + var pagelist = JsonConvert.DeserializeObject(response); + if (pagelist != null) { return pagelist.Data; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("VideoPagelist()发生异常: {0}", e); + LogManager.Error("VideoInfo", e); + return null; + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrl.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrl.cs new file mode 100644 index 0000000..2457223 --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrl.cs @@ -0,0 +1,46 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.VideoStream.Models +{ + public class PlayUrlOrigin : BaseModel + { + //[JsonProperty("code")] + //public int Code { get; set; } + //[JsonProperty("message")] + //public string Message { get; set; } + //[JsonProperty("ttl")] + //public int Ttl { get; set; } + [JsonProperty("data")] + public PlayUrl Data { get; set; } + [JsonProperty("result")] + public PlayUrl Result { get; set; } + } + + public class PlayUrl : BaseModel + { + // from + // result + // message + // quality + // format + // timelength + // accept_format + [JsonProperty("accept_description")] + public List AcceptDescription { get; set; } + [JsonProperty("accept_quality")] + public List AcceptQuality { get; set; } + // video_codecid + // seek_param + // seek_type + [JsonProperty("durl")] + public List Durl { get; set; } + [JsonProperty("dash")] + public PlayUrlDash Dash { get; set; } + [JsonProperty("support_formats")] + public List SupportFormats { get; set; } + // high_format + } + +} diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs new file mode 100644 index 0000000..7b65a05 --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDash.cs @@ -0,0 +1,20 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.VideoStream.Models +{ + public class PlayUrlDash : BaseModel + { + [JsonProperty("duration")] + public long Duration { get; set; } + //[JsonProperty("minBufferTime")] + //public float minBufferTime { get; set; } + //[JsonProperty("min_buffer_time")] + //public float min_buffer_time { get; set; } + [JsonProperty("video")] + public List Video { get; set; } + [JsonProperty("audio")] + public List Audio { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs new file mode 100644 index 0000000..9c5cf20 --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDashVideo.cs @@ -0,0 +1,35 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.VideoStream.Models +{ + public class PlayUrlDashVideo : BaseModel + { + [JsonProperty("id")] + public int Id { get; set; } + [JsonProperty("baseUrl")] + public string BaseUrl { get; set; } + [JsonProperty("backupUrl")] + public List BackupUrl { get; set; } + // bandwidth + [JsonProperty("mimeType")] + public string MimeType { get; set; } + // mime_type + [JsonProperty("codecs")] + public string Codecs { get; set; } + [JsonProperty("width")] + public int Width { get; set; } + [JsonProperty("height")] + public int Height { get; set; } + [JsonProperty("frameRate")] + public string FrameRate { get; set; } + // frame_rate + // sar + // startWithSap + // start_with_sap + // SegmentBase + // segment_base + // codecid + } +} diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDurl.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDurl.cs new file mode 100644 index 0000000..a61f0ec --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlDurl.cs @@ -0,0 +1,22 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.VideoStream.Models +{ + public class PlayUrlDurl : BaseModel + { + [JsonProperty("order")] + public int Order { get; set; } + [JsonProperty("length")] + public long Length { get; set; } + [JsonProperty("size")] + public long Size { get; set; } + // ahead + // vhead + [JsonProperty("url")] + public string Url { get; set; } + [JsonProperty("backup_url")] + public List BackupUrl { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlSupportFormat.cs b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlSupportFormat.cs new file mode 100644 index 0000000..f7187ad --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/Models/PlayUrlSupportFormat.cs @@ -0,0 +1,19 @@ +using DownKyi.Core.BiliApi.Models; +using Newtonsoft.Json; + +namespace DownKyi.Core.BiliApi.VideoStream.Models +{ + public class PlayUrlSupportFormat : BaseModel + { + [JsonProperty("quality")] + public int Quality { get; set; } + [JsonProperty("format")] + public string Format { get; set; } + [JsonProperty("new_description")] + public string NewDescription { get; set; } + [JsonProperty("display_desc")] + public string DisplayDesc { get; set; } + [JsonProperty("superscript")] + public string Superscript { get; set; } + } +} diff --git a/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs b/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs new file mode 100644 index 0000000..e84cacc --- /dev/null +++ b/DownKyi.Core/BiliApi/VideoStream/VideoStream.cs @@ -0,0 +1,101 @@ +using DownKyi.Core.BiliApi.VideoStream.Models; +using DownKyi.Core.Logging; +using Newtonsoft.Json; +using System; + +namespace DownKyi.Core.BiliApi.VideoStream +{ + public static class VideoStream + { + + /// + /// 获取普通视频的视频流 + /// + /// + /// + /// + /// + /// + public static PlayUrl GetVideoPlayUrl(long avid, string bvid, long cid, int quality = 125) + { + string baseUrl = $"https://api.bilibili.com/x/player/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=80"; + string url; + if (bvid != null) { url = $"{baseUrl}&bvid={bvid}"; } + else if (avid > -1) { url = $"{baseUrl}&aid={avid}"; } + else { return null; } + + return GetPlayUrl(url); + } + + /// + /// 获取番剧的视频流 + /// + /// + /// + /// + /// + /// + public static PlayUrl GetBangumiPlayUrl(long avid, string bvid, long cid, int quality = 125) + { + string baseUrl = $"https://api.bilibili.com/pgc/player/web/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=80"; + string url; + if (bvid != null) { url = $"{baseUrl}&bvid={bvid}"; } + else if (avid > -1) { url = $"{baseUrl}&aid={avid}"; } + else { return null; } + + return GetPlayUrl(url); + } + + /// + /// 获取课程的视频流 + /// + /// + /// + /// + /// + /// + public static PlayUrl GetCheesePlayUrl(long avid, string bvid, long cid, long episodeId, int quality = 125) + { + string baseUrl = $"https://api.bilibili.com/pugv/player/web/playurl?cid={cid}&qn={quality}&fourk=1&fnver=0&fnval=80"; + string url; + if (bvid != null) { url = $"{baseUrl}&bvid={bvid}"; } + else if (avid > -1) { url = $"{baseUrl}&aid={avid}"; } + else { return null; } + + // 必须有episodeId,否则会返回请求错误 + if (episodeId != 0) + { + url += $"&ep_id={episodeId}"; + } + + return GetPlayUrl(url); + } + + /// + /// 获取视频流 + /// + /// + /// + private static PlayUrl GetPlayUrl(string url) + { + string referer = "https://www.bilibili.com"; + string response = WebClient.RequestWeb(url, referer); + + try + { + var playUrl = JsonConvert.DeserializeObject(response); + if (playUrl == null) { return null; } + else if (playUrl.Data != null) { return playUrl.Data; } + else if (playUrl.Result != null) { return playUrl.Result; } + else { return null; } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("GetPlayUrl()发生异常: {0}", e); + LogManager.Error("GetPlayUrl", e); + return null; + } + } + + } +} diff --git a/DownKyi.Core/BiliApi/WebClient.cs b/DownKyi.Core/BiliApi/WebClient.cs new file mode 100644 index 0000000..2fa1c28 --- /dev/null +++ b/DownKyi.Core/BiliApi/WebClient.cs @@ -0,0 +1,142 @@ +using Brotli; +using DownKyi.Core.BiliApi.Login; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Net; +using System.Text; + +namespace DownKyi.Core.BiliApi +{ + internal static class WebClient + { + + /// + /// 发送get或post请求 + /// + /// + /// + /// + /// + /// + public static string RequestWeb(string url, string referer = null, string method = "GET", Dictionary parameters = null, int retry = 3) + { + // 重试次数 + if (retry <= 0) { return ""; } + + // post请求,发送参数 + if (method == "POST" && parameters != null) + { + StringBuilder builder = new StringBuilder(); + int i = 0; + foreach (var item in parameters) + { + if (i > 0) + { + builder.Append("&"); + } + + builder.AppendFormat("{0}={1}", item.Key, item.Value); + i++; + } + + url += "?" + builder.ToString(); + } + + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = method; + request.Timeout = 30 * 1000; + request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"; + //request.ContentType = "application/json,text/html,application/xhtml+xml,application/xml;charset=UTF-8"; + request.Headers["accept-language"] = "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"; + request.Headers["accept-encoding"] = "gzip, deflate, br"; + + // referer + if (referer != null) + { + request.Referer = referer; + } + + // 构造cookie + if (!url.Contains("getLogin")) + { + request.Headers["origin"] = "https://www.bilibili.com"; + + CookieContainer cookies = LoginHelper.GetLoginInfoCookies(); + if (cookies != null) + { + request.CookieContainer = cookies; + } + } + + string html = string.Empty; + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + { + if (response.ContentEncoding.ToLower().Contains("gzip")) + { + using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)) + { + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + html = reader.ReadToEnd(); + } + } + } + else if (response.ContentEncoding.ToLower().Contains("deflate")) + { + using (DeflateStream stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress)) + { + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + html = reader.ReadToEnd(); + } + } + } + else if (response.ContentEncoding.ToLower().Contains("br")) + { + using (BrotliStream stream = new BrotliStream(response.GetResponseStream(), CompressionMode.Decompress)) + { + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + html = reader.ReadToEnd(); + } + } + } + else + { + using (Stream stream = response.GetResponseStream()) + { + using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) + { + html = reader.ReadToEnd(); + } + } + } + } + + return html; + } + catch (WebException e) + { + Console.WriteLine("RequestWeb()发生Web异常: {0}", e); + Logging.LogManager.Error(e); + return RequestWeb(url, referer, method, parameters, retry - 1); + } + catch (IOException e) + { + Console.WriteLine("RequestWeb()发生IO异常: {0}", e); + Logging.LogManager.Error(e); + return RequestWeb(url, referer, method, parameters, retry - 1); + } + catch (Exception e) + { + Console.WriteLine("RequestWeb()发生其他异常: {0}", e); + Logging.LogManager.Error(e); + return RequestWeb(url, referer, method, parameters, retry - 1); + } + } + } +} diff --git a/DownKyi.Core/BiliApi/Zone/VideoZone.cs b/DownKyi.Core/BiliApi/Zone/VideoZone.cs new file mode 100644 index 0000000..741a918 --- /dev/null +++ b/DownKyi.Core/BiliApi/Zone/VideoZone.cs @@ -0,0 +1,192 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.BiliApi.Zone +{ + + public class VideoZone + { + private static VideoZone that; + private readonly List zones = new List(); + + /// + /// 使用单例模式获取分区,注意未搜索到的分区需要额外处理 + /// + /// + public static VideoZone Instance() + { + if (that == null) + { + that = new VideoZone(); + } + return that; + } + + public List GetZone() + { + return zones; + } + + private VideoZone() + { + //动画 + zones.Add(new ZoneAttr(1, "douga", "动画")); // 主分区 + zones.Add(new ZoneAttr(24, "mad", "MAD·AMV", 1)); //具有一定制作程度的动画或静画的二次创作视频 + zones.Add(new ZoneAttr(25, "mmd", "MMD·3D", 1)); //使用MMD(MikuMikuDance)和其他3D建模类软件制作的视频 + zones.Add(new ZoneAttr(47, "voice", "短片·手书·配音", 1)); //追求创新并具有强烈特色的短片、手书(绘)及ACG相关配音 + zones.Add(new ZoneAttr(210, "garage_kit", "手办·模玩", 1)); //手办模玩的测评、改造或其他衍生内容 + zones.Add(new ZoneAttr(86, "tokusatsu", "特摄", 1)); //特摄相关衍生视频 + zones.Add(new ZoneAttr(27, "other", "综合", 1)); //以动画及动画相关内容为素材,包括但不仅限于音频替换、杂谈、排行榜等内容 + + //番剧 + zones.Add(new ZoneAttr(13, "anime", "番剧")); // 主分区 + zones.Add(new ZoneAttr(33, "serial", "连载动画", 13)); //当季连载的动画番剧 + zones.Add(new ZoneAttr(32, "finish", "完结动画", 13)); //已完结的动画番剧合集 + zones.Add(new ZoneAttr(51, "information", "资讯", 13)); //动画番剧相关资讯视频 + zones.Add(new ZoneAttr(152, "offical", "官方延伸", 13)); //动画番剧为主题的宣传节目、采访视频,及声优相关视频 + + //国创 + zones.Add(new ZoneAttr(167, "guochuang", "国创")); // 主分区 + zones.Add(new ZoneAttr(153, "chinese", "国产动画", 167)); //我国出品的PGC动画 + zones.Add(new ZoneAttr(168, "original", "国产原创相关", 167)); // + zones.Add(new ZoneAttr(169, "puppetry", "布袋戏", 167)); // + zones.Add(new ZoneAttr(195, "motioncomic", "动态漫·广播剧", 167)); // + zones.Add(new ZoneAttr(170, "information", "资讯", 167)); // + + //音乐 + zones.Add(new ZoneAttr(3, "music", "音乐")); // 主分区 + zones.Add(new ZoneAttr(28, "original", "原创音乐", 3)); //个人或团队制作以音乐为主要原创因素的歌曲或纯音乐 + zones.Add(new ZoneAttr(31, "cover", "翻唱", 3)); //一切非官方的人声再演绎歌曲作品 + zones.Add(new ZoneAttr(30, "vocaloid", "VOCALOID·UTAU", 3)); //以雅马哈Vocaloid和UTAU引擎为基础,包含其他调教引擎,运用各类音源进行的歌曲创作内容 + zones.Add(new ZoneAttr(194, "electronic", "电音", 3)); //以电子合成器、音乐软体等产生的电子声响制作的音乐 + zones.Add(new ZoneAttr(59, "perform", "演奏", 3)); //传统或非传统乐器及器材的演奏作品 + zones.Add(new ZoneAttr(193, "mv", "MV", 3)); //音乐录影带,为搭配音乐而拍摄的短片 + zones.Add(new ZoneAttr(29, "live", "音乐现场", 3)); //音乐实况表演视频 + zones.Add(new ZoneAttr(130, "other", "音乐综合", 3)); //收录无法定义到其他音乐子分区的音乐视频 + + //舞蹈 + zones.Add(new ZoneAttr(129, "dance", "舞蹈")); // 主分区 + zones.Add(new ZoneAttr(20, "otaku", "宅舞", 129)); //与ACG相关的翻跳、原创舞蹈 + zones.Add(new ZoneAttr(198, "hiphop", "街舞", 129)); //收录街舞相关内容,包括赛事现场、舞室作品、个人翻跳、FREESTYLE等 + zones.Add(new ZoneAttr(199, "star", "明星舞蹈", 129)); //国内外明星发布的官方舞蹈及其翻跳内容 + zones.Add(new ZoneAttr(200, "china", "中国舞", 129)); //传承中国艺术文化的舞蹈内容,包括古典舞、民族民间舞、汉唐舞、古风舞等 + zones.Add(new ZoneAttr(154, "three_d", "舞蹈综合", 129)); //收录无法定义到其他舞蹈子分区的舞蹈视频 + zones.Add(new ZoneAttr(156, "demo", "舞蹈教程", 129)); //镜面慢速,动作分解,基础教程等具有教学意义的舞蹈视频 + + //游戏 + zones.Add(new ZoneAttr(4, "game", "游戏")); // 主分区 + zones.Add(new ZoneAttr(17, "stand_alone", "单机游戏", 4)); //以所有平台(PC、主机、移动端)的单机或联机游戏为主的视频内容,包括游戏预告、CG、实况解说及相关的评测、杂谈与视频剪辑等 + zones.Add(new ZoneAttr(171, "esports", "电子竞技", 4)); //具有高对抗性的电子竞技游戏项目,其相关的赛事、实况、攻略、解说、短剧等视频。 + zones.Add(new ZoneAttr(172, "mobile", "手机游戏", 4)); //以手机及平板设备为主要平台的游戏,其相关的实况、攻略、解说、短剧、演示等视频。 + zones.Add(new ZoneAttr(65, "online", "网络游戏", 4)); //由网络运营商运营的多人在线游戏,以及电子竞技的相关游戏内容。包括赛事、攻略、实况、解说等相关视频 + zones.Add(new ZoneAttr(173, "board", "桌游棋牌", 4)); //桌游、棋牌、卡牌对战等及其相关电子版游戏的实况、攻略、解说、演示等视频。 + zones.Add(new ZoneAttr(121, "gmv", "GMV", 4)); //由游戏素材制作的MV视频。以游戏内容或CG为主制作的,具有一定创作程度的MV类型的视频 + zones.Add(new ZoneAttr(136, "music", "音游", 4)); //各个平台上,通过配合音乐与节奏而进行的音乐类游戏视频 + zones.Add(new ZoneAttr(19, "mugen", "Mugen", 4)); //以Mugen引擎为平台制作、或与Mugen相关的游戏视频 + + //知识 + zones.Add(new ZoneAttr(36, "technology", "知识")); // 主分区 + zones.Add(new ZoneAttr(201, "science", "科学科普", 36)); //回答你的十万个为什么 + zones.Add(new ZoneAttr(124, "fun", "社科人文", 36)); //聊聊互联网社会法律,看看历史趣闻艺术,品品文化心理人物 + zones.Add(new ZoneAttr(207, "finance", "财经", 36)); //宏观经济分析,证券市场动态,商业帝国故事,知识与财富齐飞~ + zones.Add(new ZoneAttr(208, "campus", "校园学习", 36)); //老师很有趣,同学多人才,我们都爱搞学习 + zones.Add(new ZoneAttr(209, "career", "职业职场", 36)); //职场加油站,成为最有料的职场人 + zones.Add(new ZoneAttr(122, "wild", "野生技术协会", 36)); //炫酷技能大集合,是时候展现真正的技术了 + + //数码 + zones.Add(new ZoneAttr(188, "digital", "数码")); // 主分区 + zones.Add(new ZoneAttr(95, "mobile", "手机平板", 188)); //手机平板、app 和产品教程等相关视频 + zones.Add(new ZoneAttr(189, "pc", "电脑装机", 188)); //电脑、笔记本、装机配件、外设和软件教程等相关视频 + zones.Add(new ZoneAttr(190, "photography", "摄影摄像", 188)); //摄影摄像器材、拍摄剪辑技巧、拍摄作品分享等相关视频 + zones.Add(new ZoneAttr(191, "intelligence_av", "影音智能", 188)); //影音设备、智能硬件、生活家电等相关视频 + + //汽车 + zones.Add(new ZoneAttr(223, "car", "汽车")); // 主分区 + zones.Add(new ZoneAttr(176, "life", "汽车生活", 223)); //分享汽车及出行相关的生活体验类视频 + zones.Add(new ZoneAttr(224, "culture", "汽车文化", 223)); //车迷的精神圣地,包括汽车赛事、品牌历史、汽车改装、经典车型和汽车模型等 + zones.Add(new ZoneAttr(225, "geek", "汽车极客", 223)); //汽车硬核达人聚集地,包括DIY造车、专业评测和技术知识分享 + zones.Add(new ZoneAttr(226, "smart", "智能出行", 223)); //探索新能源汽车和未来智能出行的前沿阵地 + zones.Add(new ZoneAttr(227, "strategy", "购车攻略", 223)); //丰富详实的购车建议和新车体验 + + //生活 + zones.Add(new ZoneAttr(160, "life", "生活")); // 主分区 + zones.Add(new ZoneAttr(138, "funny", "搞笑", 160)); //各种沙雕有趣的搞笑剪辑,挑战,表演,配音等视频 + zones.Add(new ZoneAttr(21, "daily", "日常", 160)); //记录日常生活,分享生活故事 + zones.Add(new ZoneAttr(161, "handmake", "手工", 160)); //手工制品的制作过程或成品展示、教程、测评类视频 + zones.Add(new ZoneAttr(162, "painting", "绘画", 160)); //绘画过程或绘画教程,以及绘画相关的所有视频 + zones.Add(new ZoneAttr(163, "sports", "运动", 160)); //运动相关的记录、教程、装备评测和精彩瞬间剪辑视频 + zones.Add(new ZoneAttr(174, "other", "其他", 160)); //对分区归属不明的视频进行归纳整合的特定分区 + + //美食 + zones.Add(new ZoneAttr(211, "food", "美食")); // 主分区 + zones.Add(new ZoneAttr(76, "make", "美食制作", 211)); //学做人间美味,展示精湛厨艺 + zones.Add(new ZoneAttr(212, "detective", "美食侦探", 211)); //寻找美味餐厅,发现街头美食 + zones.Add(new ZoneAttr(213, "measurement", "美食测评", 211)); //吃货世界,品尝世间美味 + zones.Add(new ZoneAttr(214, "rural", "田园美食", 211)); //品味乡野美食,寻找山与海的味道 + zones.Add(new ZoneAttr(215, "record", "美食记录", 211)); //记录一日三餐,给生活添一点幸福感 + + //动物圈 + zones.Add(new ZoneAttr(217, "animal", "动物圈")); // 主分区 + zones.Add(new ZoneAttr(218, "cat", "喵星人", 217)); //喵喵喵喵喵 + zones.Add(new ZoneAttr(219, "dog", "汪星人", 217)); //汪汪汪汪汪 + zones.Add(new ZoneAttr(220, "panda", "大熊猫", 217)); //芝麻汤圆营业中 + zones.Add(new ZoneAttr(221, "wild_animal", "野生动物", 217)); //内有“猛兽”出没 + zones.Add(new ZoneAttr(222, "reptiles", "爬宠", 217)); //鳞甲有灵 + zones.Add(new ZoneAttr(75, "animal_composite", "动物综合", 217)); //收录除上述子分区外,其余动物相关视频以及非动物主体或多个动物主体的动物相关延伸内容 + + //鬼畜 + zones.Add(new ZoneAttr(119, "kichiku", "鬼畜")); // 主分区 + zones.Add(new ZoneAttr(22, "guide", "鬼畜调教", 119)); //使用素材在音频、画面上做一定处理,达到与BGM一定的同步感 + zones.Add(new ZoneAttr(26, "mad", "音MAD", 119)); //使用素材音频进行一定的二次创作来达到还原原曲的非商业性质稿件 + zones.Add(new ZoneAttr(126, "manual_vocaloid", "人力VOCALOID", 119)); //将人物或者角色的无伴奏素材进行人工调音,使其就像VOCALOID一样歌唱的技术 + zones.Add(new ZoneAttr(216, "theatre", "鬼畜剧场", 119)); //使用素材进行人工剪辑编排的有剧情的作品 + zones.Add(new ZoneAttr(127, "course", "教程演示", 119)); //鬼畜相关的教程演示 + + //时尚 + zones.Add(new ZoneAttr(155, "fashion", "时尚")); // 主分区 + zones.Add(new ZoneAttr(157, "makeup", "美妆", 155)); //涵盖妆容、发型、美甲等教程,彩妆、护肤相关产品测评、分享等 + zones.Add(new ZoneAttr(158, "clothing", "服饰", 155)); //服饰风格、搭配技巧相关的展示和教程视频 + zones.Add(new ZoneAttr(164, "aerobics", "健身", 155)); //器械、有氧、拉伸运动等,以达到强身健体、减肥瘦身、形体塑造目的 + zones.Add(new ZoneAttr(159, "catwalk", "T台", 155)); //发布会走秀现场及模特相关时尚片、采访、后台花絮 + zones.Add(new ZoneAttr(192, "trends", "风尚标", 155)); //时尚明星专访、街拍、时尚购物相关知识科普 + + //资讯 + zones.Add(new ZoneAttr(202, "information", "资讯")); // 主分区 + zones.Add(new ZoneAttr(203, "hotspot", "热点", 202)); //全民关注的时政热门资讯 + zones.Add(new ZoneAttr(204, "global", "环球", 202)); //全球范围内发生的具有重大影响力的事件动态 + zones.Add(new ZoneAttr(205, "social", "社会", 202)); //日常生活的社会事件、社会问题、社会风貌的报道 + zones.Add(new ZoneAttr(206, "multiple", "综合", 202)); //除上述领域外其它垂直领域的综合资讯 + + //娱乐 + zones.Add(new ZoneAttr(5, "ent", "娱乐")); // 主分区 + zones.Add(new ZoneAttr(71, "variety", "综艺", 5)); //国内外有趣的综艺和综艺相关精彩剪辑 + zones.Add(new ZoneAttr(137, "star", "明星", 5)); //娱乐圈动态、明星资讯相关 + + //影视 + zones.Add(new ZoneAttr(181, "cinephile", "影视")); // 主分区 + zones.Add(new ZoneAttr(182, "cinecism", "影视杂谈", 181)); //影视评论、解说、吐槽、科普等 + zones.Add(new ZoneAttr(183, "montage", "影视剪辑", 181)); //对影视素材进行剪辑再创作的视频 + zones.Add(new ZoneAttr(85, "shortfilm", "短片", 181)); //追求自我表达且具有特色的短片 + zones.Add(new ZoneAttr(184, "trailer_info", "预告·资讯", 181)); //影视类相关资讯,预告,花絮等视频 + + //纪录片 + zones.Add(new ZoneAttr(177, "documentary", "纪录片")); // 主分区 + zones.Add(new ZoneAttr(37, "history", "人文·历史", 177)); // + zones.Add(new ZoneAttr(178, "science", "科学·探索·自然", 177)); // + zones.Add(new ZoneAttr(179, "military", "军事", 177)); // + zones.Add(new ZoneAttr(180, "travel", "社会·美食·旅行", 177)); // + + //电影 + zones.Add(new ZoneAttr(23, "movie", "电影")); // 主分区 + zones.Add(new ZoneAttr(147, "chinese", "华语电影", 23)); // + zones.Add(new ZoneAttr(145, "west", "欧美电影", 23)); // + zones.Add(new ZoneAttr(146, "japan", "日本电影", 23)); // + zones.Add(new ZoneAttr(83, "movie", "其他国家", 23)); // + + //电视剧 + zones.Add(new ZoneAttr(11, "tv", "电视剧")); // 主分区 + zones.Add(new ZoneAttr(185, "mainland", "国产剧", 11)); // + zones.Add(new ZoneAttr(187, "overseas", "海外剧", 11)); // + + } + } +} diff --git a/DownKyi.Core/BiliApi/Zone/ZoneAttr.cs b/DownKyi.Core/BiliApi/Zone/ZoneAttr.cs new file mode 100644 index 0000000..ff3876a --- /dev/null +++ b/DownKyi.Core/BiliApi/Zone/ZoneAttr.cs @@ -0,0 +1,19 @@ +namespace DownKyi.Core.BiliApi.Zone +{ + public class ZoneAttr + { + public int Id { get; } + public string Type { get; } + public string Name { get; } + public int ParentId { get; } + + public ZoneAttr(int id, string type, string name, int parentId = 0) + { + Id = id; + Type = type; + Name = name; + ParentId = parentId; + } + + } +} diff --git a/DownKyi.Core/BiliApi/protobuf/bilibili/community/service/dm/v1/Dm.cs b/DownKyi.Core/BiliApi/protobuf/bilibili/community/service/dm/v1/Dm.cs new file mode 100644 index 0000000..a423dbb --- /dev/null +++ b/DownKyi.Core/BiliApi/protobuf/bilibili/community/service/dm/v1/Dm.cs @@ -0,0 +1,14819 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: bilibili/community/service/dm/v1/dm.proto +// +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Bilibili.Community.Service.Dm.V1 { + + /// Holder for reflection information generated from bilibili/community/service/dm/v1/dm.proto + public static partial class DmReflection { + + #region Descriptor + /// File descriptor for bilibili/community/service/dm/v1/dm.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static DmReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CiliaWxpYmlsaS9jb21tdW5pdHkvc2VydmljZS9kbS92MS9kbS5wcm90bxIg", + "YmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEiTAoLRG1TZWdTREtS", + "ZXESCwoDcGlkGAEgASgDEgsKA29pZBgCIAEoAxIMCgR0eXBlGAMgASgFEhUK", + "DXNlZ21lbnRfaW5kZXgYBCABKAMiXQoNRG1TZWdTREtSZXBseRIOCgZjbG9z", + "ZWQYASABKAgSPAoFZWxlbXMYAiADKAsyLS5iaWxpYmlsaS5jb21tdW5pdHku", + "c2VydmljZS5kbS52MS5EYW5tYWt1RWxlbSJMCgtEbVNlZ090dFJlcRILCgNw", + "aWQYASABKAMSCwoDb2lkGAIgASgDEgwKBHR5cGUYAyABKAUSFQoNc2VnbWVu", + "dF9pbmRleBgEIAEoAyJdCg1EbVNlZ090dFJlcGx5Eg4KBmNsb3NlZBgBIAEo", + "CBI8CgVlbGVtcxgCIAMoCzItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNl", + "LmRtLnYxLkRhbm1ha3VFbGVtImcKDkRtU2VnTW9iaWxlUmVxEgsKA3BpZBgB", + "IAEoAxILCgNvaWQYAiABKAMSDAoEdHlwZRgDIAEoBRIVCg1zZWdtZW50X2lu", + "ZGV4GAQgASgDEhYKDnRlZW5hZ2Vyc19tb2RlGAUgASgFIqEBChBEbVNlZ01v", + "YmlsZVJlcGx5EjwKBWVsZW1zGAEgAygLMi0uYmlsaWJpbGkuY29tbXVuaXR5", + "LnNlcnZpY2UuZG0udjEuRGFubWFrdUVsZW0SDQoFc3RhdGUYAiABKAUSQAoH", + "YWlfZmxhZxgDIAEoCzIvLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRt", + "LnYxLkRhbm1ha3VBSUZsYWciWAoJRG1WaWV3UmVxEgsKA3BpZBgBIAEoAxIL", + "CgNvaWQYAiABKAMSDAoEdHlwZRgDIAEoBRINCgVzcG1pZBgEIAEoCRIUCgxp", + "c19oYXJkX2Jvb3QYBSABKAUi8AMKC0RtVmlld1JlcGx5Eg4KBmNsb3NlZBgB", + "IAEoCBI5CgRtYXNrGAIgASgLMisuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZp", + "Y2UuZG0udjEuVmlkZW9NYXNrEkEKCHN1YnRpdGxlGAMgASgLMi8uYmlsaWJp", + "bGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuVmlkZW9TdWJ0aXRsZRITCgtz", + "cGVjaWFsX2RtcxgEIAMoCRJECgdhaV9mbGFnGAUgASgLMjMuYmlsaWJpbGku", + "Y29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubWFrdUZsYWdDb25maWcSTgoN", + "cGxheWVyX2NvbmZpZxgGIAEoCzI3LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2", + "aWNlLmRtLnYxLkRhbm11UGxheWVyVmlld0NvbmZpZxIWCg5zZW5kX2JveF9z", + "dHlsZRgHIAEoBRINCgVhbGxvdxgIIAEoCBIRCgljaGVja19ib3gYCSABKAkS", + "GgoSY2hlY2tfYm94X3Nob3dfbXNnGAogASgJEhgKEHRleHRfcGxhY2Vob2xk", + "ZXIYCyABKAkSGQoRaW5wdXRfcGxhY2Vob2xkZXIYDCABKAkSHQoVcmVwb3J0", + "X2ZpbHRlcl9jb250ZW50GA0gAygJIqgDCg5EbVdlYlZpZXdSZXBseRINCgVz", + "dGF0ZRgBIAEoBRIMCgR0ZXh0GAIgASgJEhEKCXRleHRfc2lkZRgDIAEoCRI9", + "CgZkbV9zZ2UYBCABKAsyLS5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5k", + "bS52MS5EbVNlZ0NvbmZpZxJBCgRmbGFnGAUgASgLMjMuYmlsaWJpbGkuY29t", + "bXVuaXR5LnNlcnZpY2UuZG0udjEuRGFubWFrdUZsYWdDb25maWcSEwoLc3Bl", + "Y2lhbF9kbXMYBiADKAkSEQoJY2hlY2tfYm94GAcgASgIEg0KBWNvdW50GAgg", + "ASgDEj8KCmNvbW1hbmREbXMYCSADKAsyKy5iaWxpYmlsaS5jb21tdW5pdHku", + "c2VydmljZS5kbS52MS5Db21tYW5kRG0STQoNcGxheWVyX2NvbmZpZxgKIAEo", + "CzI2LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm11V2Vi", + "UGxheWVyQ29uZmlnEh0KFXJlcG9ydF9maWx0ZXJfY29udGVudBgLIAMoCSKh", + "AQoJQ29tbWFuZERtEgoKAmlkGAEgASgDEgsKA29pZBgCIAEoAxILCgNtaWQY", + "AyABKAkSDwoHY29tbWFuZBgEIAEoCRIPCgdjb250ZW50GAUgASgJEhAKCHBy", + "b2dyZXNzGAYgASgFEg0KBWN0aW1lGAcgASgJEg0KBW10aW1lGAggASgJEg0K", + "BWV4dHJhGAkgASgJEg0KBWlkU3RyGAogASgJIi8KC0RtU2VnQ29uZmlnEhEK", + "CXBhZ2Vfc2l6ZRgBIAEoAxINCgV0b3RhbBgCIAEoAyJTCglWaWRlb01hc2sS", + "CwoDY2lkGAEgASgDEgwKBHBsYXQYAiABKAUSCwoDZnBzGAMgASgFEgwKBHRp", + "bWUYBCABKAMSEAoIbWFza191cmwYBSABKAkibwoNVmlkZW9TdWJ0aXRsZRIL", + "CgNsYW4YASABKAkSDgoGbGFuRG9jGAIgASgJEkEKCXN1YnRpdGxlcxgDIAMo", + "CzIuLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlN1YnRpdGxl", + "SXRlbSKPAwoURGFubXVXZWJQbGF5ZXJDb25maWcSEQoJZG1fc3dpdGNoGAEg", + "ASgIEhEKCWFpX3N3aXRjaBgCIAEoCBIQCghhaV9sZXZlbBgDIAEoBRIQCghi", + "bG9ja3RvcBgEIAEoCBITCgtibG9ja3Njcm9sbBgFIAEoCBITCgtibG9ja2Jv", + "dHRvbRgGIAEoCBISCgpibG9ja2NvbG9yGAcgASgIEhQKDGJsb2Nrc3BlY2lh", + "bBgIIAEoCBIUCgxwcmV2ZW50c2hhZGUYCSABKAgSDQoFZG1hc2sYCiABKAgS", + "DwoHb3BhY2l0eRgLIAEoAhIOCgZkbWFyZWEYDCABKAUSEQoJc3BlZWRwbHVz", + "GA0gASgCEhAKCGZvbnRzaXplGA4gASgCEhIKCnNjcmVlbnN5bmMYDyABKAgS", + "EQoJc3BlZWRzeW5jGBAgASgIEhIKCmZvbnRmYW1pbHkYESABKAkSDAoEYm9s", + "ZBgSIAEoCBISCgpmb250Ym9yZGVyGBMgASgFEhEKCWRyYXdfdHlwZRgUIAEo", + "CSKaAQoMU3VidGl0bGVJdGVtEgoKAmlkGAEgASgDEg4KBmlkX3N0chgCIAEo", + "CRILCgNsYW4YAyABKAkSDwoHbGFuX2RvYxgEIAEoCRIUCgxzdWJ0aXRsZV91", + "cmwYBSABKAkSOgoGYXV0aG9yGAYgASgLMiouYmlsaWJpbGkuY29tbXVuaXR5", + "LnNlcnZpY2UuZG0udjEuVXNlckluZm8iXAoIVXNlckluZm8SCwoDbWlkGAEg", + "ASgDEgwKBG5hbWUYAiABKAkSCwoDc2V4GAMgASgJEgwKBGZhY2UYBCABKAkS", + "DAoEc2lnbhgFIAEoCRIMCgRyYW5rGAYgASgFItYBCgtEYW5tYWt1RWxlbRIK", + "CgJpZBgBIAEoAxIQCghwcm9ncmVzcxgCIAEoBRIMCgRtb2RlGAMgASgFEhAK", + "CGZvbnRzaXplGAQgASgFEg0KBWNvbG9yGAUgASgNEg8KB21pZEhhc2gYBiAB", + "KAkSDwoHY29udGVudBgHIAEoCRINCgVjdGltZRgIIAEoAxIOCgZ3ZWlnaHQY", + "CSABKAUSDgoGYWN0aW9uGAogASgJEgwKBHBvb2wYCyABKAUSDQoFaWRTdHIY", + "DCABKAkSDAoEYXR0chgNIAEoBSKgCwoRRG1QbGF5ZXJDb25maWdSZXESCgoC", + "dHMYASABKAMSRQoGc3dpdGNoGAIgASgLMjUuYmlsaWJpbGkuY29tbXVuaXR5", + "LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdVN3aXRjaBJOCgtzd2l0Y2hf", + "c2F2ZRgDIAEoCzI5LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYx", + "LlBsYXllckRhbm1ha3VTd2l0Y2hTYXZlElsKEnVzZV9kZWZhdWx0X2NvbmZp", + "ZxgEIAEoCzI/LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBs", + "YXllckRhbm1ha3VVc2VEZWZhdWx0Q29uZmlnEmEKFWFpX3JlY29tbWVuZGVk", + "X3N3aXRjaBgFIAEoCzJCLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRt", + "LnYxLlBsYXllckRhbm1ha3VBaVJlY29tbWVuZGVkU3dpdGNoEl8KFGFpX3Jl", + "Y29tbWVuZGVkX2xldmVsGAYgASgLMkEuYmlsaWJpbGkuY29tbXVuaXR5LnNl", + "cnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRMZXZlbBJJ", + "CghibG9ja3RvcBgHIAEoCzI3LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNl", + "LmRtLnYxLlBsYXllckRhbm1ha3VCbG9ja3RvcBJPCgtibG9ja3Njcm9sbBgI", + "IAEoCzI6LmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXll", + "ckRhbm1ha3VCbG9ja3Njcm9sbBJPCgtibG9ja2JvdHRvbRgJIAEoCzI6LmJp", + "bGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VC", + "bG9ja2JvdHRvbRJTCg1ibG9ja2NvbG9yZnVsGAogASgLMjwuYmlsaWJpbGku", + "Y29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFrdUJsb2NrY29s", + "b3JmdWwSTwoLYmxvY2tyZXBlYXQYCyABKAsyOi5iaWxpYmlsaS5jb21tdW5p", + "dHkuc2VydmljZS5kbS52MS5QbGF5ZXJEYW5tYWt1QmxvY2tyZXBlYXQSUQoM", + "YmxvY2tzcGVjaWFsGAwgASgLMjsuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZp", + "Y2UuZG0udjEuUGxheWVyRGFubWFrdUJsb2Nrc3BlY2lhbBJHCgdvcGFjaXR5", + "GA0gASgLMjYuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxh", + "eWVyRGFubWFrdU9wYWNpdHkSUwoNc2NhbGluZ2ZhY3RvchgOIAEoCzI8LmJp", + "bGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VT", + "Y2FsaW5nZmFjdG9yEkUKBmRvbWFpbhgPIAEoCzI1LmJpbGliaWxpLmNvbW11", + "bml0eS5zZXJ2aWNlLmRtLnYxLlBsYXllckRhbm1ha3VEb21haW4SQwoFc3Bl", + "ZWQYECABKAsyNC5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5Q", + "bGF5ZXJEYW5tYWt1U3BlZWQSVwoPZW5hYmxlYmxvY2tsaXN0GBEgASgLMj4u", + "YmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuUGxheWVyRGFubWFr", + "dUVuYWJsZWJsb2NrbGlzdBJeChlpbmxpbmVQbGF5ZXJEYW5tYWt1U3dpdGNo", + "GBIgASgLMjsuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuSW5s", + "aW5lUGxheWVyRGFubWFrdVN3aXRjaCIpCghSZXNwb25zZRIMCgRjb2RlGAEg", + "ASgFEg8KB21lc3NhZ2UYAiABKAkiKQoLRGFubWFrdUZsYWcSDAoEZG1pZBgB", + "IAEoAxIMCgRmbGFnGAIgASgNIksKEURhbm1ha3VGbGFnQ29uZmlnEhAKCHJl", + "Y19mbGFnGAEgASgFEhAKCHJlY190ZXh0GAIgASgJEhIKCnJlY19zd2l0Y2gY", + "AyABKAUiUAoNRGFubWFrdUFJRmxhZxI/CghkbV9mbGFncxgBIAMoCzItLmJp", + "bGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRtLnYxLkRhbm1ha3VGbGFnIrEC", + "ChVEYW5tdVBsYXllclZpZXdDb25maWcSYQodZGFubXVrdV9kZWZhdWx0X3Bs", + "YXllcl9jb25maWcYASABKAsyOi5iaWxpYmlsaS5jb21tdW5pdHkuc2Vydmlj", + "ZS5kbS52MS5EYW5tdURlZmF1bHRQbGF5ZXJDb25maWcSUgoVZGFubXVrdV9w", + "bGF5ZXJfY29uZmlnGAIgASgLMjMuYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZp", + "Y2UuZG0udjEuRGFubXVQbGF5ZXJDb25maWcSYQodZGFubXVrdV9wbGF5ZXJf", + "ZHluYW1pY19jb25maWcYAyADKAsyOi5iaWxpYmlsaS5jb21tdW5pdHkuc2Vy", + "dmljZS5kbS52MS5EYW5tdVBsYXllckR5bmFtaWNDb25maWcioQQKGERhbm11", + "RGVmYXVsdFBsYXllckNvbmZpZxIpCiFwbGF5ZXJfZGFubWFrdV91c2VfZGVm", + "YXVsdF9jb25maWcYASABKAgSLAokcGxheWVyX2Rhbm1ha3VfYWlfcmVjb21t", + "ZW5kZWRfc3dpdGNoGAQgASgIEisKI3BsYXllcl9kYW5tYWt1X2FpX3JlY29t", + "bWVuZGVkX2xldmVsGAUgASgFEh8KF3BsYXllcl9kYW5tYWt1X2Jsb2NrdG9w", + "GAYgASgIEiIKGnBsYXllcl9kYW5tYWt1X2Jsb2Nrc2Nyb2xsGAcgASgIEiIK", + "GnBsYXllcl9kYW5tYWt1X2Jsb2NrYm90dG9tGAggASgIEiQKHHBsYXllcl9k", + "YW5tYWt1X2Jsb2NrY29sb3JmdWwYCSABKAgSIgoacGxheWVyX2Rhbm1ha3Vf", + "YmxvY2tyZXBlYXQYCiABKAgSIwobcGxheWVyX2Rhbm1ha3VfYmxvY2tzcGVj", + "aWFsGAsgASgIEh4KFnBsYXllcl9kYW5tYWt1X29wYWNpdHkYDCABKAISJAoc", + "cGxheWVyX2Rhbm1ha3Vfc2NhbGluZ2ZhY3RvchgNIAEoAhIdChVwbGF5ZXJf", + "ZGFubWFrdV9kb21haW4YDiABKAISHAoUcGxheWVyX2Rhbm1ha3Vfc3BlZWQY", + "DyABKAUSJAocaW5saW5lX3BsYXllcl9kYW5tYWt1X3N3aXRjaBgQIAEoCCKr", + "BQoRRGFubXVQbGF5ZXJDb25maWcSHQoVcGxheWVyX2Rhbm1ha3Vfc3dpdGNo", + "GAEgASgIEiIKGnBsYXllcl9kYW5tYWt1X3N3aXRjaF9zYXZlGAIgASgIEikK", + "IXBsYXllcl9kYW5tYWt1X3VzZV9kZWZhdWx0X2NvbmZpZxgDIAEoCBIsCiRw", + "bGF5ZXJfZGFubWFrdV9haV9yZWNvbW1lbmRlZF9zd2l0Y2gYBCABKAgSKwoj", + "cGxheWVyX2Rhbm1ha3VfYWlfcmVjb21tZW5kZWRfbGV2ZWwYBSABKAUSHwoX", + "cGxheWVyX2Rhbm1ha3VfYmxvY2t0b3AYBiABKAgSIgoacGxheWVyX2Rhbm1h", + "a3VfYmxvY2tzY3JvbGwYByABKAgSIgoacGxheWVyX2Rhbm1ha3VfYmxvY2ti", + "b3R0b20YCCABKAgSJAoccGxheWVyX2Rhbm1ha3VfYmxvY2tjb2xvcmZ1bBgJ", + "IAEoCBIiChpwbGF5ZXJfZGFubWFrdV9ibG9ja3JlcGVhdBgKIAEoCBIjChtw", + "bGF5ZXJfZGFubWFrdV9ibG9ja3NwZWNpYWwYCyABKAgSHgoWcGxheWVyX2Rh", + "bm1ha3Vfb3BhY2l0eRgMIAEoAhIkChxwbGF5ZXJfZGFubWFrdV9zY2FsaW5n", + "ZmFjdG9yGA0gASgCEh0KFXBsYXllcl9kYW5tYWt1X2RvbWFpbhgOIAEoAhIc", + "ChRwbGF5ZXJfZGFubWFrdV9zcGVlZBgPIAEoBRImCh5wbGF5ZXJfZGFubWFr", + "dV9lbmFibGVibG9ja2xpc3QYECABKAgSJAocaW5saW5lX3BsYXllcl9kYW5t", + "YWt1X3N3aXRjaBgRIAEoCBIkChxpbmxpbmVfcGxheWVyX2Rhbm1ha3VfY29u", + "ZmlnGBIgASgFIksKGERhbm11UGxheWVyRHluYW1pY0NvbmZpZxIQCghwcm9n", + "cmVzcxgBIAEoBRIdChVwbGF5ZXJfZGFubWFrdV9kb21haW4YAiABKAIiNwoT", + "UGxheWVyRGFubWFrdVN3aXRjaBINCgV2YWx1ZRgBIAEoCBIRCgljYW5JZ25v", + "cmUYAiABKAgiKAoXUGxheWVyRGFubWFrdVN3aXRjaFNhdmUSDQoFdmFsdWUY", + "ASABKAgiLgodUGxheWVyRGFubWFrdVVzZURlZmF1bHRDb25maWcSDQoFdmFs", + "dWUYASABKAgiMQogUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRTd2l0Y2gS", + "DQoFdmFsdWUYASABKAgiMAofUGxheWVyRGFubWFrdUFpUmVjb21tZW5kZWRM", + "ZXZlbBINCgV2YWx1ZRgBIAEoCCImChVQbGF5ZXJEYW5tYWt1QmxvY2t0b3AS", + "DQoFdmFsdWUYASABKAgiKQoYUGxheWVyRGFubWFrdUJsb2Nrc2Nyb2xsEg0K", + "BXZhbHVlGAEgASgIIikKGFBsYXllckRhbm1ha3VCbG9ja2JvdHRvbRINCgV2", + "YWx1ZRgBIAEoCCIrChpQbGF5ZXJEYW5tYWt1QmxvY2tjb2xvcmZ1bBINCgV2", + "YWx1ZRgBIAEoCCIpChhQbGF5ZXJEYW5tYWt1QmxvY2tyZXBlYXQSDQoFdmFs", + "dWUYASABKAgiKgoZUGxheWVyRGFubWFrdUJsb2Nrc3BlY2lhbBINCgV2YWx1", + "ZRgBIAEoCCIlChRQbGF5ZXJEYW5tYWt1T3BhY2l0eRINCgV2YWx1ZRgBIAEo", + "AiIrChpQbGF5ZXJEYW5tYWt1U2NhbGluZ2ZhY3RvchINCgV2YWx1ZRgBIAEo", + "AiIkChNQbGF5ZXJEYW5tYWt1RG9tYWluEg0KBXZhbHVlGAEgASgCIiMKElBs", + "YXllckRhbm1ha3VTcGVlZBINCgV2YWx1ZRgBIAEoBSItChxQbGF5ZXJEYW5t", + "YWt1RW5hYmxlYmxvY2tsaXN0Eg0KBXZhbHVlGAEgASgIIioKGUlubGluZVBs", + "YXllckRhbm1ha3VTd2l0Y2gSDQoFdmFsdWUYASABKAgqTAoJRE1BdHRyQml0", + "EhQKEERNQXR0ckJpdFByb3RlY3QQABIVChFETUF0dHJCaXRGcm9tTGl2ZRAB", + "EhIKDkRNQXR0ckhpZ2hMaWtlEAIyqgQKAkRNEnMKC0RtU2VnTW9iaWxlEjAu", + "YmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1TZWdNb2JpbGVS", + "ZXEaMi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5EbVNlZ01v", + "YmlsZVJlcGx5EmQKBkRtVmlldxIrLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2", + "aWNlLmRtLnYxLkRtVmlld1JlcRotLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2", + "aWNlLmRtLnYxLkRtVmlld1JlcGx5EnEKDkRtUGxheWVyQ29uZmlnEjMuYmls", + "aWJpbGkuY29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1QbGF5ZXJDb25maWdS", + "ZXEaKi5iaWxpYmlsaS5jb21tdW5pdHkuc2VydmljZS5kbS52MS5SZXNwb25z", + "ZRJqCghEbVNlZ090dBItLmJpbGliaWxpLmNvbW11bml0eS5zZXJ2aWNlLmRt", + "LnYxLkRtU2VnT3R0UmVxGi8uYmlsaWJpbGkuY29tbXVuaXR5LnNlcnZpY2Uu", + "ZG0udjEuRG1TZWdPdHRSZXBseRJqCghEbVNlZ1NESxItLmJpbGliaWxpLmNv", + "bW11bml0eS5zZXJ2aWNlLmRtLnYxLkRtU2VnU0RLUmVxGi8uYmlsaWJpbGku", + "Y29tbXVuaXR5LnNlcnZpY2UuZG0udjEuRG1TZWdTREtSZXBseWIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Bilibili.Community.Service.Dm.V1.DMAttrBit), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegSDKReq), global::Bilibili.Community.Service.Dm.V1.DmSegSDKReq.Parser, new[]{ "Pid", "Oid", "Type", "SegmentIndex" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegSDKReply), global::Bilibili.Community.Service.Dm.V1.DmSegSDKReply.Parser, new[]{ "Closed", "Elems" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegOttReq), global::Bilibili.Community.Service.Dm.V1.DmSegOttReq.Parser, new[]{ "Pid", "Oid", "Type", "SegmentIndex" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegOttReply), global::Bilibili.Community.Service.Dm.V1.DmSegOttReply.Parser, new[]{ "Closed", "Elems" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegMobileReq), global::Bilibili.Community.Service.Dm.V1.DmSegMobileReq.Parser, new[]{ "Pid", "Oid", "Type", "SegmentIndex", "TeenagersMode" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegMobileReply), global::Bilibili.Community.Service.Dm.V1.DmSegMobileReply.Parser, new[]{ "Elems", "State", "AiFlag" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmViewReq), global::Bilibili.Community.Service.Dm.V1.DmViewReq.Parser, new[]{ "Pid", "Oid", "Type", "Spmid", "IsHardBoot" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmViewReply), global::Bilibili.Community.Service.Dm.V1.DmViewReply.Parser, new[]{ "Closed", "Mask", "Subtitle", "SpecialDms", "AiFlag", "PlayerConfig", "SendBoxStyle", "Allow", "CheckBox", "CheckBoxShowMsg", "TextPlaceholder", "InputPlaceholder", "ReportFilterContent" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmWebViewReply), global::Bilibili.Community.Service.Dm.V1.DmWebViewReply.Parser, new[]{ "State", "Text", "TextSide", "DmSge", "Flag", "SpecialDms", "CheckBox", "Count", "CommandDms", "PlayerConfig", "ReportFilterContent" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.CommandDm), global::Bilibili.Community.Service.Dm.V1.CommandDm.Parser, new[]{ "Id", "Oid", "Mid", "Command", "Content", "Progress", "Ctime", "Mtime", "Extra", "IdStr" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmSegConfig), global::Bilibili.Community.Service.Dm.V1.DmSegConfig.Parser, new[]{ "PageSize", "Total" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.VideoMask), global::Bilibili.Community.Service.Dm.V1.VideoMask.Parser, new[]{ "Cid", "Plat", "Fps", "Time", "MaskUrl" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.VideoSubtitle), global::Bilibili.Community.Service.Dm.V1.VideoSubtitle.Parser, new[]{ "Lan", "LanDoc", "Subtitles" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig), global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig.Parser, new[]{ "DmSwitch", "AiSwitch", "AiLevel", "Blocktop", "Blockscroll", "Blockbottom", "Blockcolor", "Blockspecial", "Preventshade", "Dmask", "Opacity", "Dmarea", "Speedplus", "Fontsize", "Screensync", "Speedsync", "Fontfamily", "Bold", "Fontborder", "DrawType" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.SubtitleItem), global::Bilibili.Community.Service.Dm.V1.SubtitleItem.Parser, new[]{ "Id", "IdStr", "Lan", "LanDoc", "SubtitleUrl", "Author" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.UserInfo), global::Bilibili.Community.Service.Dm.V1.UserInfo.Parser, new[]{ "Mid", "Name", "Sex", "Face", "Sign", "Rank" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmakuElem), global::Bilibili.Community.Service.Dm.V1.DanmakuElem.Parser, new[]{ "Id", "Progress", "Mode", "Fontsize", "Color", "MidHash", "Content", "Ctime", "Weight", "Action", "Pool", "IdStr", "Attr" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DmPlayerConfigReq), global::Bilibili.Community.Service.Dm.V1.DmPlayerConfigReq.Parser, new[]{ "Ts", "Switch", "SwitchSave", "UseDefaultConfig", "AiRecommendedSwitch", "AiRecommendedLevel", "Blocktop", "Blockscroll", "Blockbottom", "Blockcolorful", "Blockrepeat", "Blockspecial", "Opacity", "Scalingfactor", "Domain", "Speed", "Enableblocklist", "InlinePlayerDanmakuSwitch" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.Response), global::Bilibili.Community.Service.Dm.V1.Response.Parser, new[]{ "Code", "Message" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmakuFlag), global::Bilibili.Community.Service.Dm.V1.DanmakuFlag.Parser, new[]{ "Dmid", "Flag" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig), global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig.Parser, new[]{ "RecFlag", "RecText", "RecSwitch" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag), global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag.Parser, new[]{ "DmFlags" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig), global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig.Parser, new[]{ "DanmukuDefaultPlayerConfig", "DanmukuPlayerConfig", "DanmukuPlayerDynamicConfig" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig), global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig.Parser, new[]{ "PlayerDanmakuUseDefaultConfig", "PlayerDanmakuAiRecommendedSwitch", "PlayerDanmakuAiRecommendedLevel", "PlayerDanmakuBlocktop", "PlayerDanmakuBlockscroll", "PlayerDanmakuBlockbottom", "PlayerDanmakuBlockcolorful", "PlayerDanmakuBlockrepeat", "PlayerDanmakuBlockspecial", "PlayerDanmakuOpacity", "PlayerDanmakuScalingfactor", "PlayerDanmakuDomain", "PlayerDanmakuSpeed", "InlinePlayerDanmakuSwitch" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig), global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig.Parser, new[]{ "PlayerDanmakuSwitch", "PlayerDanmakuSwitchSave", "PlayerDanmakuUseDefaultConfig", "PlayerDanmakuAiRecommendedSwitch", "PlayerDanmakuAiRecommendedLevel", "PlayerDanmakuBlocktop", "PlayerDanmakuBlockscroll", "PlayerDanmakuBlockbottom", "PlayerDanmakuBlockcolorful", "PlayerDanmakuBlockrepeat", "PlayerDanmakuBlockspecial", "PlayerDanmakuOpacity", "PlayerDanmakuScalingfactor", "PlayerDanmakuDomain", "PlayerDanmakuSpeed", "PlayerDanmakuEnableblocklist", "InlinePlayerDanmakuSwitch", "InlinePlayerDanmakuConfig" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.DanmuPlayerDynamicConfig), global::Bilibili.Community.Service.Dm.V1.DanmuPlayerDynamicConfig.Parser, new[]{ "Progress", "PlayerDanmakuDomain" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch.Parser, new[]{ "Value", "CanIgnore" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist), global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch), global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch.Parser, new[]{ "Value" }, null, null, null, null) + })); + } + #endregion + + } + #region Enums + /// + /// 弹幕属性位值 + /// + public enum DMAttrBit { + /// + /// 保护弹幕 + /// + [pbr::OriginalName("DMAttrBitProtect")] Protect = 0, + /// + /// 直播弹幕 + /// + [pbr::OriginalName("DMAttrBitFromLive")] FromLive = 1, + /// + /// 高赞弹幕 + /// + [pbr::OriginalName("DMAttrHighLike")] DmattrHighLike = 2, + } + + #endregion + + #region Messages + /// + /// 弹幕SDK-请求 + /// + public sealed partial class DmSegSDKReq : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegSDKReq()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegSDKReq() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegSDKReq(DmSegSDKReq other) : this() { + pid_ = other.pid_; + oid_ = other.oid_; + type_ = other.type_; + segmentIndex_ = other.segmentIndex_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegSDKReq Clone() { + return new DmSegSDKReq(this); + } + + /// Field number for the "pid" field. + public const int PidFieldNumber = 1; + private long pid_; + /// + /// 稿件avid/漫画epid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Pid { + get { return pid_; } + set { + pid_ = value; + } + } + + /// Field number for the "oid" field. + public const int OidFieldNumber = 2; + private long oid_; + /// + /// 视频cid/漫画cid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Oid { + get { return oid_; } + set { + oid_ = value; + } + } + + /// Field number for the "type" field. + public const int TypeFieldNumber = 3; + private int type_; + /// + /// 弹幕类型 + /// 1:视频 2:漫画 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Type { + get { return type_; } + set { + type_ = value; + } + } + + /// Field number for the "segment_index" field. + public const int SegmentIndexFieldNumber = 4; + private long segmentIndex_; + /// + /// 分段(6min) + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long SegmentIndex { + get { return segmentIndex_; } + set { + segmentIndex_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegSDKReq); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegSDKReq other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Pid != other.Pid) return false; + if (Oid != other.Oid) return false; + if (Type != other.Type) return false; + if (SegmentIndex != other.SegmentIndex) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Pid != 0L) hash ^= Pid.GetHashCode(); + if (Oid != 0L) hash ^= Oid.GetHashCode(); + if (Type != 0) hash ^= Type.GetHashCode(); + if (SegmentIndex != 0L) hash ^= SegmentIndex.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (SegmentIndex != 0L) { + output.WriteRawTag(32); + output.WriteInt64(SegmentIndex); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (SegmentIndex != 0L) { + output.WriteRawTag(32); + output.WriteInt64(SegmentIndex); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Pid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Pid); + } + if (Oid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Oid); + } + if (Type != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Type); + } + if (SegmentIndex != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(SegmentIndex); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegSDKReq other) { + if (other == null) { + return; + } + if (other.Pid != 0L) { + Pid = other.Pid; + } + if (other.Oid != 0L) { + Oid = other.Oid; + } + if (other.Type != 0) { + Type = other.Type; + } + if (other.SegmentIndex != 0L) { + SegmentIndex = other.SegmentIndex; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 32: { + SegmentIndex = input.ReadInt64(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 32: { + SegmentIndex = input.ReadInt64(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕SDK-响应 + /// + public sealed partial class DmSegSDKReply : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegSDKReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegSDKReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegSDKReply(DmSegSDKReply other) : this() { + closed_ = other.closed_; + elems_ = other.elems_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegSDKReply Clone() { + return new DmSegSDKReply(this); + } + + /// Field number for the "closed" field. + public const int ClosedFieldNumber = 1; + private bool closed_; + /// + /// 是否已关闭弹幕 + /// 0:未关闭 1:已关闭 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Closed { + get { return closed_; } + set { + closed_ = value; + } + } + + /// Field number for the "elems" field. + public const int ElemsFieldNumber = 2; + private static readonly pb::FieldCodec _repeated_elems_codec + = pb::FieldCodec.ForMessage(18, global::Bilibili.Community.Service.Dm.V1.DanmakuElem.Parser); + private readonly pbc::RepeatedField elems_ = new pbc::RepeatedField(); + /// + /// 弹幕列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField Elems { + get { return elems_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegSDKReply); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegSDKReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Closed != other.Closed) return false; + if(!elems_.Equals(other.elems_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Closed != false) hash ^= Closed.GetHashCode(); + hash ^= elems_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Closed != false) { + output.WriteRawTag(8); + output.WriteBool(Closed); + } + elems_.WriteTo(output, _repeated_elems_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Closed != false) { + output.WriteRawTag(8); + output.WriteBool(Closed); + } + elems_.WriteTo(ref output, _repeated_elems_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Closed != false) { + size += 1 + 1; + } + size += elems_.CalculateSize(_repeated_elems_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegSDKReply other) { + if (other == null) { + return; + } + if (other.Closed != false) { + Closed = other.Closed; + } + elems_.Add(other.elems_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Closed = input.ReadBool(); + break; + } + case 18: { + elems_.AddEntriesFrom(input, _repeated_elems_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Closed = input.ReadBool(); + break; + } + case 18: { + elems_.AddEntriesFrom(ref input, _repeated_elems_codec); + break; + } + } + } + } + #endif + + } + + /// + /// ott弹幕列表-请求 + /// + public sealed partial class DmSegOttReq : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegOttReq()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[2]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegOttReq() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegOttReq(DmSegOttReq other) : this() { + pid_ = other.pid_; + oid_ = other.oid_; + type_ = other.type_; + segmentIndex_ = other.segmentIndex_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegOttReq Clone() { + return new DmSegOttReq(this); + } + + /// Field number for the "pid" field. + public const int PidFieldNumber = 1; + private long pid_; + /// + /// 稿件avid/漫画epid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Pid { + get { return pid_; } + set { + pid_ = value; + } + } + + /// Field number for the "oid" field. + public const int OidFieldNumber = 2; + private long oid_; + /// + /// 视频cid/漫画cid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Oid { + get { return oid_; } + set { + oid_ = value; + } + } + + /// Field number for the "type" field. + public const int TypeFieldNumber = 3; + private int type_; + /// + /// 弹幕类型 + /// 1:视频 2:漫画 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Type { + get { return type_; } + set { + type_ = value; + } + } + + /// Field number for the "segment_index" field. + public const int SegmentIndexFieldNumber = 4; + private long segmentIndex_; + /// + /// 分段(6min) + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long SegmentIndex { + get { return segmentIndex_; } + set { + segmentIndex_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegOttReq); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegOttReq other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Pid != other.Pid) return false; + if (Oid != other.Oid) return false; + if (Type != other.Type) return false; + if (SegmentIndex != other.SegmentIndex) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Pid != 0L) hash ^= Pid.GetHashCode(); + if (Oid != 0L) hash ^= Oid.GetHashCode(); + if (Type != 0) hash ^= Type.GetHashCode(); + if (SegmentIndex != 0L) hash ^= SegmentIndex.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (SegmentIndex != 0L) { + output.WriteRawTag(32); + output.WriteInt64(SegmentIndex); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (SegmentIndex != 0L) { + output.WriteRawTag(32); + output.WriteInt64(SegmentIndex); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Pid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Pid); + } + if (Oid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Oid); + } + if (Type != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Type); + } + if (SegmentIndex != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(SegmentIndex); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegOttReq other) { + if (other == null) { + return; + } + if (other.Pid != 0L) { + Pid = other.Pid; + } + if (other.Oid != 0L) { + Oid = other.Oid; + } + if (other.Type != 0) { + Type = other.Type; + } + if (other.SegmentIndex != 0L) { + SegmentIndex = other.SegmentIndex; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 32: { + SegmentIndex = input.ReadInt64(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 32: { + SegmentIndex = input.ReadInt64(); + break; + } + } + } + } + #endif + + } + + /// + /// ott弹幕列表-响应 + /// + public sealed partial class DmSegOttReply : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegOttReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[3]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegOttReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegOttReply(DmSegOttReply other) : this() { + closed_ = other.closed_; + elems_ = other.elems_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegOttReply Clone() { + return new DmSegOttReply(this); + } + + /// Field number for the "closed" field. + public const int ClosedFieldNumber = 1; + private bool closed_; + /// + /// 是否已关闭弹幕 + /// 0:未关闭 1:已关闭 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Closed { + get { return closed_; } + set { + closed_ = value; + } + } + + /// Field number for the "elems" field. + public const int ElemsFieldNumber = 2; + private static readonly pb::FieldCodec _repeated_elems_codec + = pb::FieldCodec.ForMessage(18, global::Bilibili.Community.Service.Dm.V1.DanmakuElem.Parser); + private readonly pbc::RepeatedField elems_ = new pbc::RepeatedField(); + /// + /// 弹幕列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField Elems { + get { return elems_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegOttReply); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegOttReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Closed != other.Closed) return false; + if(!elems_.Equals(other.elems_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Closed != false) hash ^= Closed.GetHashCode(); + hash ^= elems_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Closed != false) { + output.WriteRawTag(8); + output.WriteBool(Closed); + } + elems_.WriteTo(output, _repeated_elems_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Closed != false) { + output.WriteRawTag(8); + output.WriteBool(Closed); + } + elems_.WriteTo(ref output, _repeated_elems_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Closed != false) { + size += 1 + 1; + } + size += elems_.CalculateSize(_repeated_elems_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegOttReply other) { + if (other == null) { + return; + } + if (other.Closed != false) { + Closed = other.Closed; + } + elems_.Add(other.elems_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Closed = input.ReadBool(); + break; + } + case 18: { + elems_.AddEntriesFrom(input, _repeated_elems_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Closed = input.ReadBool(); + break; + } + case 18: { + elems_.AddEntriesFrom(ref input, _repeated_elems_codec); + break; + } + } + } + } + #endif + + } + + /// + /// 获取弹幕-请求 + /// + public sealed partial class DmSegMobileReq : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegMobileReq()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[4]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegMobileReq() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegMobileReq(DmSegMobileReq other) : this() { + pid_ = other.pid_; + oid_ = other.oid_; + type_ = other.type_; + segmentIndex_ = other.segmentIndex_; + teenagersMode_ = other.teenagersMode_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegMobileReq Clone() { + return new DmSegMobileReq(this); + } + + /// Field number for the "pid" field. + public const int PidFieldNumber = 1; + private long pid_; + /// + /// 稿件avid/漫画epid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Pid { + get { return pid_; } + set { + pid_ = value; + } + } + + /// Field number for the "oid" field. + public const int OidFieldNumber = 2; + private long oid_; + /// + /// 视频cid/漫画cid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Oid { + get { return oid_; } + set { + oid_ = value; + } + } + + /// Field number for the "type" field. + public const int TypeFieldNumber = 3; + private int type_; + /// + /// 弹幕类型 + /// 1:视频 2:漫画 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Type { + get { return type_; } + set { + type_ = value; + } + } + + /// Field number for the "segment_index" field. + public const int SegmentIndexFieldNumber = 4; + private long segmentIndex_; + /// + /// 分段(6min) + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long SegmentIndex { + get { return segmentIndex_; } + set { + segmentIndex_ = value; + } + } + + /// Field number for the "teenagers_mode" field. + public const int TeenagersModeFieldNumber = 5; + private int teenagersMode_; + /// + /// 是否青少年模式 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int TeenagersMode { + get { return teenagersMode_; } + set { + teenagersMode_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegMobileReq); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegMobileReq other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Pid != other.Pid) return false; + if (Oid != other.Oid) return false; + if (Type != other.Type) return false; + if (SegmentIndex != other.SegmentIndex) return false; + if (TeenagersMode != other.TeenagersMode) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Pid != 0L) hash ^= Pid.GetHashCode(); + if (Oid != 0L) hash ^= Oid.GetHashCode(); + if (Type != 0) hash ^= Type.GetHashCode(); + if (SegmentIndex != 0L) hash ^= SegmentIndex.GetHashCode(); + if (TeenagersMode != 0) hash ^= TeenagersMode.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (SegmentIndex != 0L) { + output.WriteRawTag(32); + output.WriteInt64(SegmentIndex); + } + if (TeenagersMode != 0) { + output.WriteRawTag(40); + output.WriteInt32(TeenagersMode); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (SegmentIndex != 0L) { + output.WriteRawTag(32); + output.WriteInt64(SegmentIndex); + } + if (TeenagersMode != 0) { + output.WriteRawTag(40); + output.WriteInt32(TeenagersMode); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Pid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Pid); + } + if (Oid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Oid); + } + if (Type != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Type); + } + if (SegmentIndex != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(SegmentIndex); + } + if (TeenagersMode != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(TeenagersMode); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegMobileReq other) { + if (other == null) { + return; + } + if (other.Pid != 0L) { + Pid = other.Pid; + } + if (other.Oid != 0L) { + Oid = other.Oid; + } + if (other.Type != 0) { + Type = other.Type; + } + if (other.SegmentIndex != 0L) { + SegmentIndex = other.SegmentIndex; + } + if (other.TeenagersMode != 0) { + TeenagersMode = other.TeenagersMode; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 32: { + SegmentIndex = input.ReadInt64(); + break; + } + case 40: { + TeenagersMode = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 32: { + SegmentIndex = input.ReadInt64(); + break; + } + case 40: { + TeenagersMode = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 获取弹幕-响应 + /// + public sealed partial class DmSegMobileReply : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegMobileReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[5]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegMobileReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegMobileReply(DmSegMobileReply other) : this() { + elems_ = other.elems_.Clone(); + state_ = other.state_; + aiFlag_ = other.aiFlag_ != null ? other.aiFlag_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegMobileReply Clone() { + return new DmSegMobileReply(this); + } + + /// Field number for the "elems" field. + public const int ElemsFieldNumber = 1; + private static readonly pb::FieldCodec _repeated_elems_codec + = pb::FieldCodec.ForMessage(10, global::Bilibili.Community.Service.Dm.V1.DanmakuElem.Parser); + private readonly pbc::RepeatedField elems_ = new pbc::RepeatedField(); + /// + /// 弹幕列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField Elems { + get { return elems_; } + } + + /// Field number for the "state" field. + public const int StateFieldNumber = 2; + private int state_; + /// + /// 是否已关闭弹幕 + /// 0:未关闭 1:已关闭 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int State { + get { return state_; } + set { + state_ = value; + } + } + + /// Field number for the "ai_flag" field. + public const int AiFlagFieldNumber = 3; + private global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag aiFlag_; + /// + /// 弹幕云屏蔽ai评分值 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag AiFlag { + get { return aiFlag_; } + set { + aiFlag_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegMobileReply); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegMobileReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if(!elems_.Equals(other.elems_)) return false; + if (State != other.State) return false; + if (!object.Equals(AiFlag, other.AiFlag)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + hash ^= elems_.GetHashCode(); + if (State != 0) hash ^= State.GetHashCode(); + if (aiFlag_ != null) hash ^= AiFlag.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + elems_.WriteTo(output, _repeated_elems_codec); + if (State != 0) { + output.WriteRawTag(16); + output.WriteInt32(State); + } + if (aiFlag_ != null) { + output.WriteRawTag(26); + output.WriteMessage(AiFlag); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + elems_.WriteTo(ref output, _repeated_elems_codec); + if (State != 0) { + output.WriteRawTag(16); + output.WriteInt32(State); + } + if (aiFlag_ != null) { + output.WriteRawTag(26); + output.WriteMessage(AiFlag); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + size += elems_.CalculateSize(_repeated_elems_codec); + if (State != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(State); + } + if (aiFlag_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(AiFlag); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegMobileReply other) { + if (other == null) { + return; + } + elems_.Add(other.elems_); + if (other.State != 0) { + State = other.State; + } + if (other.aiFlag_ != null) { + if (aiFlag_ == null) { + AiFlag = new global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag(); + } + AiFlag.MergeFrom(other.AiFlag); + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + elems_.AddEntriesFrom(input, _repeated_elems_codec); + break; + } + case 16: { + State = input.ReadInt32(); + break; + } + case 26: { + if (aiFlag_ == null) { + AiFlag = new global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag(); + } + input.ReadMessage(AiFlag); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + elems_.AddEntriesFrom(ref input, _repeated_elems_codec); + break; + } + case 16: { + State = input.ReadInt32(); + break; + } + case 26: { + if (aiFlag_ == null) { + AiFlag = new global::Bilibili.Community.Service.Dm.V1.DanmakuAIFlag(); + } + input.ReadMessage(AiFlag); + break; + } + } + } + } + #endif + + } + + /// + /// 客户端弹幕元数据-请求 + /// + public sealed partial class DmViewReq : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmViewReq()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[6]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmViewReq() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmViewReq(DmViewReq other) : this() { + pid_ = other.pid_; + oid_ = other.oid_; + type_ = other.type_; + spmid_ = other.spmid_; + isHardBoot_ = other.isHardBoot_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmViewReq Clone() { + return new DmViewReq(this); + } + + /// Field number for the "pid" field. + public const int PidFieldNumber = 1; + private long pid_; + /// + /// 稿件avid/漫画epid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Pid { + get { return pid_; } + set { + pid_ = value; + } + } + + /// Field number for the "oid" field. + public const int OidFieldNumber = 2; + private long oid_; + /// + /// 视频cid/漫画cid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Oid { + get { return oid_; } + set { + oid_ = value; + } + } + + /// Field number for the "type" field. + public const int TypeFieldNumber = 3; + private int type_; + /// + /// 弹幕类型 + /// 1:视频 2:漫画 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Type { + get { return type_; } + set { + type_ = value; + } + } + + /// Field number for the "spmid" field. + public const int SpmidFieldNumber = 4; + private string spmid_ = ""; + /// + /// 页面spm + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Spmid { + get { return spmid_; } + set { + spmid_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "is_hard_boot" field. + public const int IsHardBootFieldNumber = 5; + private int isHardBoot_; + /// + /// 是否冷启 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int IsHardBoot { + get { return isHardBoot_; } + set { + isHardBoot_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmViewReq); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmViewReq other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Pid != other.Pid) return false; + if (Oid != other.Oid) return false; + if (Type != other.Type) return false; + if (Spmid != other.Spmid) return false; + if (IsHardBoot != other.IsHardBoot) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Pid != 0L) hash ^= Pid.GetHashCode(); + if (Oid != 0L) hash ^= Oid.GetHashCode(); + if (Type != 0) hash ^= Type.GetHashCode(); + if (Spmid.Length != 0) hash ^= Spmid.GetHashCode(); + if (IsHardBoot != 0) hash ^= IsHardBoot.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (Spmid.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Spmid); + } + if (IsHardBoot != 0) { + output.WriteRawTag(40); + output.WriteInt32(IsHardBoot); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Pid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Pid); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Type != 0) { + output.WriteRawTag(24); + output.WriteInt32(Type); + } + if (Spmid.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Spmid); + } + if (IsHardBoot != 0) { + output.WriteRawTag(40); + output.WriteInt32(IsHardBoot); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Pid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Pid); + } + if (Oid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Oid); + } + if (Type != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Type); + } + if (Spmid.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Spmid); + } + if (IsHardBoot != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(IsHardBoot); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmViewReq other) { + if (other == null) { + return; + } + if (other.Pid != 0L) { + Pid = other.Pid; + } + if (other.Oid != 0L) { + Oid = other.Oid; + } + if (other.Type != 0) { + Type = other.Type; + } + if (other.Spmid.Length != 0) { + Spmid = other.Spmid; + } + if (other.IsHardBoot != 0) { + IsHardBoot = other.IsHardBoot; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 34: { + Spmid = input.ReadString(); + break; + } + case 40: { + IsHardBoot = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Pid = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 24: { + Type = input.ReadInt32(); + break; + } + case 34: { + Spmid = input.ReadString(); + break; + } + case 40: { + IsHardBoot = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 客户端弹幕元数据-响应 + /// + public sealed partial class DmViewReply : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmViewReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[7]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmViewReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmViewReply(DmViewReply other) : this() { + closed_ = other.closed_; + mask_ = other.mask_ != null ? other.mask_.Clone() : null; + subtitle_ = other.subtitle_ != null ? other.subtitle_.Clone() : null; + specialDms_ = other.specialDms_.Clone(); + aiFlag_ = other.aiFlag_ != null ? other.aiFlag_.Clone() : null; + playerConfig_ = other.playerConfig_ != null ? other.playerConfig_.Clone() : null; + sendBoxStyle_ = other.sendBoxStyle_; + allow_ = other.allow_; + checkBox_ = other.checkBox_; + checkBoxShowMsg_ = other.checkBoxShowMsg_; + textPlaceholder_ = other.textPlaceholder_; + inputPlaceholder_ = other.inputPlaceholder_; + reportFilterContent_ = other.reportFilterContent_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmViewReply Clone() { + return new DmViewReply(this); + } + + /// Field number for the "closed" field. + public const int ClosedFieldNumber = 1; + private bool closed_; + /// + /// 是否已关闭弹幕 + /// 0:未关闭 1:已关闭 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Closed { + get { return closed_; } + set { + closed_ = value; + } + } + + /// Field number for the "mask" field. + public const int MaskFieldNumber = 2; + private global::Bilibili.Community.Service.Dm.V1.VideoMask mask_; + /// + /// 智能防挡弹幕蒙版信息 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.VideoMask Mask { + get { return mask_; } + set { + mask_ = value; + } + } + + /// Field number for the "subtitle" field. + public const int SubtitleFieldNumber = 3; + private global::Bilibili.Community.Service.Dm.V1.VideoSubtitle subtitle_; + /// + /// 视频字幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.VideoSubtitle Subtitle { + get { return subtitle_; } + set { + subtitle_ = value; + } + } + + /// Field number for the "special_dms" field. + public const int SpecialDmsFieldNumber = 4; + private static readonly pb::FieldCodec _repeated_specialDms_codec + = pb::FieldCodec.ForString(34); + private readonly pbc::RepeatedField specialDms_ = new pbc::RepeatedField(); + /// + /// 高级弹幕专包url(bfs) + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField SpecialDms { + get { return specialDms_; } + } + + /// Field number for the "ai_flag" field. + public const int AiFlagFieldNumber = 5; + private global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig aiFlag_; + /// + /// 云屏蔽配置信息 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig AiFlag { + get { return aiFlag_; } + set { + aiFlag_ = value; + } + } + + /// Field number for the "player_config" field. + public const int PlayerConfigFieldNumber = 6; + private global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig playerConfig_; + /// + /// 弹幕配置信息 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig PlayerConfig { + get { return playerConfig_; } + set { + playerConfig_ = value; + } + } + + /// Field number for the "send_box_style" field. + public const int SendBoxStyleFieldNumber = 7; + private int sendBoxStyle_; + /// + /// 弹幕发送框样式 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int SendBoxStyle { + get { return sendBoxStyle_; } + set { + sendBoxStyle_ = value; + } + } + + /// Field number for the "allow" field. + public const int AllowFieldNumber = 8; + private bool allow_; + /// + /// 是否允许 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Allow { + get { return allow_; } + set { + allow_ = value; + } + } + + /// Field number for the "check_box" field. + public const int CheckBoxFieldNumber = 9; + private string checkBox_ = ""; + /// + /// check box 是否展示 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string CheckBox { + get { return checkBox_; } + set { + checkBox_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "check_box_show_msg" field. + public const int CheckBoxShowMsgFieldNumber = 10; + private string checkBoxShowMsg_ = ""; + /// + /// check box 展示文本 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string CheckBoxShowMsg { + get { return checkBoxShowMsg_; } + set { + checkBoxShowMsg_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "text_placeholder" field. + public const int TextPlaceholderFieldNumber = 11; + private string textPlaceholder_ = ""; + /// + /// 展示文案 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string TextPlaceholder { + get { return textPlaceholder_; } + set { + textPlaceholder_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "input_placeholder" field. + public const int InputPlaceholderFieldNumber = 12; + private string inputPlaceholder_ = ""; + /// + /// 弹幕输入框文案 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string InputPlaceholder { + get { return inputPlaceholder_; } + set { + inputPlaceholder_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "report_filter_content" field. + public const int ReportFilterContentFieldNumber = 13; + private static readonly pb::FieldCodec _repeated_reportFilterContent_codec + = pb::FieldCodec.ForString(106); + private readonly pbc::RepeatedField reportFilterContent_ = new pbc::RepeatedField(); + /// + /// 用户举报弹幕 cid维度屏蔽的正则规则 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField ReportFilterContent { + get { return reportFilterContent_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmViewReply); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmViewReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Closed != other.Closed) return false; + if (!object.Equals(Mask, other.Mask)) return false; + if (!object.Equals(Subtitle, other.Subtitle)) return false; + if(!specialDms_.Equals(other.specialDms_)) return false; + if (!object.Equals(AiFlag, other.AiFlag)) return false; + if (!object.Equals(PlayerConfig, other.PlayerConfig)) return false; + if (SendBoxStyle != other.SendBoxStyle) return false; + if (Allow != other.Allow) return false; + if (CheckBox != other.CheckBox) return false; + if (CheckBoxShowMsg != other.CheckBoxShowMsg) return false; + if (TextPlaceholder != other.TextPlaceholder) return false; + if (InputPlaceholder != other.InputPlaceholder) return false; + if(!reportFilterContent_.Equals(other.reportFilterContent_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Closed != false) hash ^= Closed.GetHashCode(); + if (mask_ != null) hash ^= Mask.GetHashCode(); + if (subtitle_ != null) hash ^= Subtitle.GetHashCode(); + hash ^= specialDms_.GetHashCode(); + if (aiFlag_ != null) hash ^= AiFlag.GetHashCode(); + if (playerConfig_ != null) hash ^= PlayerConfig.GetHashCode(); + if (SendBoxStyle != 0) hash ^= SendBoxStyle.GetHashCode(); + if (Allow != false) hash ^= Allow.GetHashCode(); + if (CheckBox.Length != 0) hash ^= CheckBox.GetHashCode(); + if (CheckBoxShowMsg.Length != 0) hash ^= CheckBoxShowMsg.GetHashCode(); + if (TextPlaceholder.Length != 0) hash ^= TextPlaceholder.GetHashCode(); + if (InputPlaceholder.Length != 0) hash ^= InputPlaceholder.GetHashCode(); + hash ^= reportFilterContent_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Closed != false) { + output.WriteRawTag(8); + output.WriteBool(Closed); + } + if (mask_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Mask); + } + if (subtitle_ != null) { + output.WriteRawTag(26); + output.WriteMessage(Subtitle); + } + specialDms_.WriteTo(output, _repeated_specialDms_codec); + if (aiFlag_ != null) { + output.WriteRawTag(42); + output.WriteMessage(AiFlag); + } + if (playerConfig_ != null) { + output.WriteRawTag(50); + output.WriteMessage(PlayerConfig); + } + if (SendBoxStyle != 0) { + output.WriteRawTag(56); + output.WriteInt32(SendBoxStyle); + } + if (Allow != false) { + output.WriteRawTag(64); + output.WriteBool(Allow); + } + if (CheckBox.Length != 0) { + output.WriteRawTag(74); + output.WriteString(CheckBox); + } + if (CheckBoxShowMsg.Length != 0) { + output.WriteRawTag(82); + output.WriteString(CheckBoxShowMsg); + } + if (TextPlaceholder.Length != 0) { + output.WriteRawTag(90); + output.WriteString(TextPlaceholder); + } + if (InputPlaceholder.Length != 0) { + output.WriteRawTag(98); + output.WriteString(InputPlaceholder); + } + reportFilterContent_.WriteTo(output, _repeated_reportFilterContent_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Closed != false) { + output.WriteRawTag(8); + output.WriteBool(Closed); + } + if (mask_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Mask); + } + if (subtitle_ != null) { + output.WriteRawTag(26); + output.WriteMessage(Subtitle); + } + specialDms_.WriteTo(ref output, _repeated_specialDms_codec); + if (aiFlag_ != null) { + output.WriteRawTag(42); + output.WriteMessage(AiFlag); + } + if (playerConfig_ != null) { + output.WriteRawTag(50); + output.WriteMessage(PlayerConfig); + } + if (SendBoxStyle != 0) { + output.WriteRawTag(56); + output.WriteInt32(SendBoxStyle); + } + if (Allow != false) { + output.WriteRawTag(64); + output.WriteBool(Allow); + } + if (CheckBox.Length != 0) { + output.WriteRawTag(74); + output.WriteString(CheckBox); + } + if (CheckBoxShowMsg.Length != 0) { + output.WriteRawTag(82); + output.WriteString(CheckBoxShowMsg); + } + if (TextPlaceholder.Length != 0) { + output.WriteRawTag(90); + output.WriteString(TextPlaceholder); + } + if (InputPlaceholder.Length != 0) { + output.WriteRawTag(98); + output.WriteString(InputPlaceholder); + } + reportFilterContent_.WriteTo(ref output, _repeated_reportFilterContent_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Closed != false) { + size += 1 + 1; + } + if (mask_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Mask); + } + if (subtitle_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Subtitle); + } + size += specialDms_.CalculateSize(_repeated_specialDms_codec); + if (aiFlag_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(AiFlag); + } + if (playerConfig_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(PlayerConfig); + } + if (SendBoxStyle != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(SendBoxStyle); + } + if (Allow != false) { + size += 1 + 1; + } + if (CheckBox.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(CheckBox); + } + if (CheckBoxShowMsg.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(CheckBoxShowMsg); + } + if (TextPlaceholder.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(TextPlaceholder); + } + if (InputPlaceholder.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(InputPlaceholder); + } + size += reportFilterContent_.CalculateSize(_repeated_reportFilterContent_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmViewReply other) { + if (other == null) { + return; + } + if (other.Closed != false) { + Closed = other.Closed; + } + if (other.mask_ != null) { + if (mask_ == null) { + Mask = new global::Bilibili.Community.Service.Dm.V1.VideoMask(); + } + Mask.MergeFrom(other.Mask); + } + if (other.subtitle_ != null) { + if (subtitle_ == null) { + Subtitle = new global::Bilibili.Community.Service.Dm.V1.VideoSubtitle(); + } + Subtitle.MergeFrom(other.Subtitle); + } + specialDms_.Add(other.specialDms_); + if (other.aiFlag_ != null) { + if (aiFlag_ == null) { + AiFlag = new global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig(); + } + AiFlag.MergeFrom(other.AiFlag); + } + if (other.playerConfig_ != null) { + if (playerConfig_ == null) { + PlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig(); + } + PlayerConfig.MergeFrom(other.PlayerConfig); + } + if (other.SendBoxStyle != 0) { + SendBoxStyle = other.SendBoxStyle; + } + if (other.Allow != false) { + Allow = other.Allow; + } + if (other.CheckBox.Length != 0) { + CheckBox = other.CheckBox; + } + if (other.CheckBoxShowMsg.Length != 0) { + CheckBoxShowMsg = other.CheckBoxShowMsg; + } + if (other.TextPlaceholder.Length != 0) { + TextPlaceholder = other.TextPlaceholder; + } + if (other.InputPlaceholder.Length != 0) { + InputPlaceholder = other.InputPlaceholder; + } + reportFilterContent_.Add(other.reportFilterContent_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Closed = input.ReadBool(); + break; + } + case 18: { + if (mask_ == null) { + Mask = new global::Bilibili.Community.Service.Dm.V1.VideoMask(); + } + input.ReadMessage(Mask); + break; + } + case 26: { + if (subtitle_ == null) { + Subtitle = new global::Bilibili.Community.Service.Dm.V1.VideoSubtitle(); + } + input.ReadMessage(Subtitle); + break; + } + case 34: { + specialDms_.AddEntriesFrom(input, _repeated_specialDms_codec); + break; + } + case 42: { + if (aiFlag_ == null) { + AiFlag = new global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig(); + } + input.ReadMessage(AiFlag); + break; + } + case 50: { + if (playerConfig_ == null) { + PlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig(); + } + input.ReadMessage(PlayerConfig); + break; + } + case 56: { + SendBoxStyle = input.ReadInt32(); + break; + } + case 64: { + Allow = input.ReadBool(); + break; + } + case 74: { + CheckBox = input.ReadString(); + break; + } + case 82: { + CheckBoxShowMsg = input.ReadString(); + break; + } + case 90: { + TextPlaceholder = input.ReadString(); + break; + } + case 98: { + InputPlaceholder = input.ReadString(); + break; + } + case 106: { + reportFilterContent_.AddEntriesFrom(input, _repeated_reportFilterContent_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Closed = input.ReadBool(); + break; + } + case 18: { + if (mask_ == null) { + Mask = new global::Bilibili.Community.Service.Dm.V1.VideoMask(); + } + input.ReadMessage(Mask); + break; + } + case 26: { + if (subtitle_ == null) { + Subtitle = new global::Bilibili.Community.Service.Dm.V1.VideoSubtitle(); + } + input.ReadMessage(Subtitle); + break; + } + case 34: { + specialDms_.AddEntriesFrom(ref input, _repeated_specialDms_codec); + break; + } + case 42: { + if (aiFlag_ == null) { + AiFlag = new global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig(); + } + input.ReadMessage(AiFlag); + break; + } + case 50: { + if (playerConfig_ == null) { + PlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuPlayerViewConfig(); + } + input.ReadMessage(PlayerConfig); + break; + } + case 56: { + SendBoxStyle = input.ReadInt32(); + break; + } + case 64: { + Allow = input.ReadBool(); + break; + } + case 74: { + CheckBox = input.ReadString(); + break; + } + case 82: { + CheckBoxShowMsg = input.ReadString(); + break; + } + case 90: { + TextPlaceholder = input.ReadString(); + break; + } + case 98: { + InputPlaceholder = input.ReadString(); + break; + } + case 106: { + reportFilterContent_.AddEntriesFrom(ref input, _repeated_reportFilterContent_codec); + break; + } + } + } + } + #endif + + } + + /// + /// web端弹幕元数据-响应 + /// + public sealed partial class DmWebViewReply : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmWebViewReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[8]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmWebViewReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmWebViewReply(DmWebViewReply other) : this() { + state_ = other.state_; + text_ = other.text_; + textSide_ = other.textSide_; + dmSge_ = other.dmSge_ != null ? other.dmSge_.Clone() : null; + flag_ = other.flag_ != null ? other.flag_.Clone() : null; + specialDms_ = other.specialDms_.Clone(); + checkBox_ = other.checkBox_; + count_ = other.count_; + commandDms_ = other.commandDms_.Clone(); + playerConfig_ = other.playerConfig_ != null ? other.playerConfig_.Clone() : null; + reportFilterContent_ = other.reportFilterContent_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmWebViewReply Clone() { + return new DmWebViewReply(this); + } + + /// Field number for the "state" field. + public const int StateFieldNumber = 1; + private int state_; + /// + /// 是否已关闭弹幕 + /// 0:未关闭 1:已关闭 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int State { + get { return state_; } + set { + state_ = value; + } + } + + /// Field number for the "text" field. + public const int TextFieldNumber = 2; + private string text_ = ""; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Text { + get { return text_; } + set { + text_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "text_side" field. + public const int TextSideFieldNumber = 3; + private string textSide_ = ""; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string TextSide { + get { return textSide_; } + set { + textSide_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "dm_sge" field. + public const int DmSgeFieldNumber = 4; + private global::Bilibili.Community.Service.Dm.V1.DmSegConfig dmSge_; + /// + /// 分段弹幕配置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DmSegConfig DmSge { + get { return dmSge_; } + set { + dmSge_ = value; + } + } + + /// Field number for the "flag" field. + public const int FlagFieldNumber = 5; + private global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig flag_; + /// + /// 云屏蔽配置信息 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig Flag { + get { return flag_; } + set { + flag_ = value; + } + } + + /// Field number for the "special_dms" field. + public const int SpecialDmsFieldNumber = 6; + private static readonly pb::FieldCodec _repeated_specialDms_codec + = pb::FieldCodec.ForString(50); + private readonly pbc::RepeatedField specialDms_ = new pbc::RepeatedField(); + /// + /// 高级弹幕专包url(bfs) + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField SpecialDms { + get { return specialDms_; } + } + + /// Field number for the "check_box" field. + public const int CheckBoxFieldNumber = 7; + private bool checkBox_; + /// + /// check box 是否展示 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool CheckBox { + get { return checkBox_; } + set { + checkBox_ = value; + } + } + + /// Field number for the "count" field. + public const int CountFieldNumber = 8; + private long count_; + /// + /// 弹幕数 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Count { + get { return count_; } + set { + count_ = value; + } + } + + /// Field number for the "commandDms" field. + public const int CommandDmsFieldNumber = 9; + private static readonly pb::FieldCodec _repeated_commandDms_codec + = pb::FieldCodec.ForMessage(74, global::Bilibili.Community.Service.Dm.V1.CommandDm.Parser); + private readonly pbc::RepeatedField commandDms_ = new pbc::RepeatedField(); + /// + /// 互动弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField CommandDms { + get { return commandDms_; } + } + + /// Field number for the "player_config" field. + public const int PlayerConfigFieldNumber = 10; + private global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig playerConfig_; + /// + /// 用户弹幕配置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig PlayerConfig { + get { return playerConfig_; } + set { + playerConfig_ = value; + } + } + + /// Field number for the "report_filter_content" field. + public const int ReportFilterContentFieldNumber = 11; + private static readonly pb::FieldCodec _repeated_reportFilterContent_codec + = pb::FieldCodec.ForString(90); + private readonly pbc::RepeatedField reportFilterContent_ = new pbc::RepeatedField(); + /// + /// 用户举报弹幕 cid维度屏蔽 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField ReportFilterContent { + get { return reportFilterContent_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmWebViewReply); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmWebViewReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (State != other.State) return false; + if (Text != other.Text) return false; + if (TextSide != other.TextSide) return false; + if (!object.Equals(DmSge, other.DmSge)) return false; + if (!object.Equals(Flag, other.Flag)) return false; + if(!specialDms_.Equals(other.specialDms_)) return false; + if (CheckBox != other.CheckBox) return false; + if (Count != other.Count) return false; + if(!commandDms_.Equals(other.commandDms_)) return false; + if (!object.Equals(PlayerConfig, other.PlayerConfig)) return false; + if(!reportFilterContent_.Equals(other.reportFilterContent_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (State != 0) hash ^= State.GetHashCode(); + if (Text.Length != 0) hash ^= Text.GetHashCode(); + if (TextSide.Length != 0) hash ^= TextSide.GetHashCode(); + if (dmSge_ != null) hash ^= DmSge.GetHashCode(); + if (flag_ != null) hash ^= Flag.GetHashCode(); + hash ^= specialDms_.GetHashCode(); + if (CheckBox != false) hash ^= CheckBox.GetHashCode(); + if (Count != 0L) hash ^= Count.GetHashCode(); + hash ^= commandDms_.GetHashCode(); + if (playerConfig_ != null) hash ^= PlayerConfig.GetHashCode(); + hash ^= reportFilterContent_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (State != 0) { + output.WriteRawTag(8); + output.WriteInt32(State); + } + if (Text.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Text); + } + if (TextSide.Length != 0) { + output.WriteRawTag(26); + output.WriteString(TextSide); + } + if (dmSge_ != null) { + output.WriteRawTag(34); + output.WriteMessage(DmSge); + } + if (flag_ != null) { + output.WriteRawTag(42); + output.WriteMessage(Flag); + } + specialDms_.WriteTo(output, _repeated_specialDms_codec); + if (CheckBox != false) { + output.WriteRawTag(56); + output.WriteBool(CheckBox); + } + if (Count != 0L) { + output.WriteRawTag(64); + output.WriteInt64(Count); + } + commandDms_.WriteTo(output, _repeated_commandDms_codec); + if (playerConfig_ != null) { + output.WriteRawTag(82); + output.WriteMessage(PlayerConfig); + } + reportFilterContent_.WriteTo(output, _repeated_reportFilterContent_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (State != 0) { + output.WriteRawTag(8); + output.WriteInt32(State); + } + if (Text.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Text); + } + if (TextSide.Length != 0) { + output.WriteRawTag(26); + output.WriteString(TextSide); + } + if (dmSge_ != null) { + output.WriteRawTag(34); + output.WriteMessage(DmSge); + } + if (flag_ != null) { + output.WriteRawTag(42); + output.WriteMessage(Flag); + } + specialDms_.WriteTo(ref output, _repeated_specialDms_codec); + if (CheckBox != false) { + output.WriteRawTag(56); + output.WriteBool(CheckBox); + } + if (Count != 0L) { + output.WriteRawTag(64); + output.WriteInt64(Count); + } + commandDms_.WriteTo(ref output, _repeated_commandDms_codec); + if (playerConfig_ != null) { + output.WriteRawTag(82); + output.WriteMessage(PlayerConfig); + } + reportFilterContent_.WriteTo(ref output, _repeated_reportFilterContent_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (State != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(State); + } + if (Text.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Text); + } + if (TextSide.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(TextSide); + } + if (dmSge_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(DmSge); + } + if (flag_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Flag); + } + size += specialDms_.CalculateSize(_repeated_specialDms_codec); + if (CheckBox != false) { + size += 1 + 1; + } + if (Count != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Count); + } + size += commandDms_.CalculateSize(_repeated_commandDms_codec); + if (playerConfig_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(PlayerConfig); + } + size += reportFilterContent_.CalculateSize(_repeated_reportFilterContent_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmWebViewReply other) { + if (other == null) { + return; + } + if (other.State != 0) { + State = other.State; + } + if (other.Text.Length != 0) { + Text = other.Text; + } + if (other.TextSide.Length != 0) { + TextSide = other.TextSide; + } + if (other.dmSge_ != null) { + if (dmSge_ == null) { + DmSge = new global::Bilibili.Community.Service.Dm.V1.DmSegConfig(); + } + DmSge.MergeFrom(other.DmSge); + } + if (other.flag_ != null) { + if (flag_ == null) { + Flag = new global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig(); + } + Flag.MergeFrom(other.Flag); + } + specialDms_.Add(other.specialDms_); + if (other.CheckBox != false) { + CheckBox = other.CheckBox; + } + if (other.Count != 0L) { + Count = other.Count; + } + commandDms_.Add(other.commandDms_); + if (other.playerConfig_ != null) { + if (playerConfig_ == null) { + PlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig(); + } + PlayerConfig.MergeFrom(other.PlayerConfig); + } + reportFilterContent_.Add(other.reportFilterContent_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + State = input.ReadInt32(); + break; + } + case 18: { + Text = input.ReadString(); + break; + } + case 26: { + TextSide = input.ReadString(); + break; + } + case 34: { + if (dmSge_ == null) { + DmSge = new global::Bilibili.Community.Service.Dm.V1.DmSegConfig(); + } + input.ReadMessage(DmSge); + break; + } + case 42: { + if (flag_ == null) { + Flag = new global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig(); + } + input.ReadMessage(Flag); + break; + } + case 50: { + specialDms_.AddEntriesFrom(input, _repeated_specialDms_codec); + break; + } + case 56: { + CheckBox = input.ReadBool(); + break; + } + case 64: { + Count = input.ReadInt64(); + break; + } + case 74: { + commandDms_.AddEntriesFrom(input, _repeated_commandDms_codec); + break; + } + case 82: { + if (playerConfig_ == null) { + PlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig(); + } + input.ReadMessage(PlayerConfig); + break; + } + case 90: { + reportFilterContent_.AddEntriesFrom(input, _repeated_reportFilterContent_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + State = input.ReadInt32(); + break; + } + case 18: { + Text = input.ReadString(); + break; + } + case 26: { + TextSide = input.ReadString(); + break; + } + case 34: { + if (dmSge_ == null) { + DmSge = new global::Bilibili.Community.Service.Dm.V1.DmSegConfig(); + } + input.ReadMessage(DmSge); + break; + } + case 42: { + if (flag_ == null) { + Flag = new global::Bilibili.Community.Service.Dm.V1.DanmakuFlagConfig(); + } + input.ReadMessage(Flag); + break; + } + case 50: { + specialDms_.AddEntriesFrom(ref input, _repeated_specialDms_codec); + break; + } + case 56: { + CheckBox = input.ReadBool(); + break; + } + case 64: { + Count = input.ReadInt64(); + break; + } + case 74: { + commandDms_.AddEntriesFrom(ref input, _repeated_commandDms_codec); + break; + } + case 82: { + if (playerConfig_ == null) { + PlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuWebPlayerConfig(); + } + input.ReadMessage(PlayerConfig); + break; + } + case 90: { + reportFilterContent_.AddEntriesFrom(ref input, _repeated_reportFilterContent_codec); + break; + } + } + } + } + #endif + + } + + /// + /// 互动弹幕条目信息 + /// + public sealed partial class CommandDm : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CommandDm()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[9]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public CommandDm() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public CommandDm(CommandDm other) : this() { + id_ = other.id_; + oid_ = other.oid_; + mid_ = other.mid_; + command_ = other.command_; + content_ = other.content_; + progress_ = other.progress_; + ctime_ = other.ctime_; + mtime_ = other.mtime_; + extra_ = other.extra_; + idStr_ = other.idStr_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public CommandDm Clone() { + return new CommandDm(this); + } + + /// Field number for the "id" field. + public const int IdFieldNumber = 1; + private long id_; + /// + /// 弹幕id + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Id { + get { return id_; } + set { + id_ = value; + } + } + + /// Field number for the "oid" field. + public const int OidFieldNumber = 2; + private long oid_; + /// + /// 对象视频cid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Oid { + get { return oid_; } + set { + oid_ = value; + } + } + + /// Field number for the "mid" field. + public const int MidFieldNumber = 3; + private string mid_ = ""; + /// + /// 发送者mid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Mid { + get { return mid_; } + set { + mid_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "command" field. + public const int CommandFieldNumber = 4; + private string command_ = ""; + /// + /// 互动弹幕指令 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Command { + get { return command_; } + set { + command_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "content" field. + public const int ContentFieldNumber = 5; + private string content_ = ""; + /// + /// 互动弹幕正文 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Content { + get { return content_; } + set { + content_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "progress" field. + public const int ProgressFieldNumber = 6; + private int progress_; + /// + /// 出现时间 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Progress { + get { return progress_; } + set { + progress_ = value; + } + } + + /// Field number for the "ctime" field. + public const int CtimeFieldNumber = 7; + private string ctime_ = ""; + /// + /// 创建时间 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Ctime { + get { return ctime_; } + set { + ctime_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "mtime" field. + public const int MtimeFieldNumber = 8; + private string mtime_ = ""; + /// + /// 发布时间 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Mtime { + get { return mtime_; } + set { + mtime_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "extra" field. + public const int ExtraFieldNumber = 9; + private string extra_ = ""; + /// + /// 扩展json数据 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Extra { + get { return extra_; } + set { + extra_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "idStr" field. + public const int IdStrFieldNumber = 10; + private string idStr_ = ""; + /// + /// 弹幕id str类型 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string IdStr { + get { return idStr_; } + set { + idStr_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as CommandDm); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(CommandDm other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Id != other.Id) return false; + if (Oid != other.Oid) return false; + if (Mid != other.Mid) return false; + if (Command != other.Command) return false; + if (Content != other.Content) return false; + if (Progress != other.Progress) return false; + if (Ctime != other.Ctime) return false; + if (Mtime != other.Mtime) return false; + if (Extra != other.Extra) return false; + if (IdStr != other.IdStr) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Id != 0L) hash ^= Id.GetHashCode(); + if (Oid != 0L) hash ^= Oid.GetHashCode(); + if (Mid.Length != 0) hash ^= Mid.GetHashCode(); + if (Command.Length != 0) hash ^= Command.GetHashCode(); + if (Content.Length != 0) hash ^= Content.GetHashCode(); + if (Progress != 0) hash ^= Progress.GetHashCode(); + if (Ctime.Length != 0) hash ^= Ctime.GetHashCode(); + if (Mtime.Length != 0) hash ^= Mtime.GetHashCode(); + if (Extra.Length != 0) hash ^= Extra.GetHashCode(); + if (IdStr.Length != 0) hash ^= IdStr.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Id != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Id); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Mid.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Mid); + } + if (Command.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Command); + } + if (Content.Length != 0) { + output.WriteRawTag(42); + output.WriteString(Content); + } + if (Progress != 0) { + output.WriteRawTag(48); + output.WriteInt32(Progress); + } + if (Ctime.Length != 0) { + output.WriteRawTag(58); + output.WriteString(Ctime); + } + if (Mtime.Length != 0) { + output.WriteRawTag(66); + output.WriteString(Mtime); + } + if (Extra.Length != 0) { + output.WriteRawTag(74); + output.WriteString(Extra); + } + if (IdStr.Length != 0) { + output.WriteRawTag(82); + output.WriteString(IdStr); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Id != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Id); + } + if (Oid != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oid); + } + if (Mid.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Mid); + } + if (Command.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Command); + } + if (Content.Length != 0) { + output.WriteRawTag(42); + output.WriteString(Content); + } + if (Progress != 0) { + output.WriteRawTag(48); + output.WriteInt32(Progress); + } + if (Ctime.Length != 0) { + output.WriteRawTag(58); + output.WriteString(Ctime); + } + if (Mtime.Length != 0) { + output.WriteRawTag(66); + output.WriteString(Mtime); + } + if (Extra.Length != 0) { + output.WriteRawTag(74); + output.WriteString(Extra); + } + if (IdStr.Length != 0) { + output.WriteRawTag(82); + output.WriteString(IdStr); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Id != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Id); + } + if (Oid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Oid); + } + if (Mid.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Mid); + } + if (Command.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Command); + } + if (Content.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Content); + } + if (Progress != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Progress); + } + if (Ctime.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Ctime); + } + if (Mtime.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Mtime); + } + if (Extra.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Extra); + } + if (IdStr.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(IdStr); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(CommandDm other) { + if (other == null) { + return; + } + if (other.Id != 0L) { + Id = other.Id; + } + if (other.Oid != 0L) { + Oid = other.Oid; + } + if (other.Mid.Length != 0) { + Mid = other.Mid; + } + if (other.Command.Length != 0) { + Command = other.Command; + } + if (other.Content.Length != 0) { + Content = other.Content; + } + if (other.Progress != 0) { + Progress = other.Progress; + } + if (other.Ctime.Length != 0) { + Ctime = other.Ctime; + } + if (other.Mtime.Length != 0) { + Mtime = other.Mtime; + } + if (other.Extra.Length != 0) { + Extra = other.Extra; + } + if (other.IdStr.Length != 0) { + IdStr = other.IdStr; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Id = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 26: { + Mid = input.ReadString(); + break; + } + case 34: { + Command = input.ReadString(); + break; + } + case 42: { + Content = input.ReadString(); + break; + } + case 48: { + Progress = input.ReadInt32(); + break; + } + case 58: { + Ctime = input.ReadString(); + break; + } + case 66: { + Mtime = input.ReadString(); + break; + } + case 74: { + Extra = input.ReadString(); + break; + } + case 82: { + IdStr = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Id = input.ReadInt64(); + break; + } + case 16: { + Oid = input.ReadInt64(); + break; + } + case 26: { + Mid = input.ReadString(); + break; + } + case 34: { + Command = input.ReadString(); + break; + } + case 42: { + Content = input.ReadString(); + break; + } + case 48: { + Progress = input.ReadInt32(); + break; + } + case 58: { + Ctime = input.ReadString(); + break; + } + case 66: { + Mtime = input.ReadString(); + break; + } + case 74: { + Extra = input.ReadString(); + break; + } + case 82: { + IdStr = input.ReadString(); + break; + } + } + } + } + #endif + + } + + /// + /// + public sealed partial class DmSegConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmSegConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[10]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegConfig(DmSegConfig other) : this() { + pageSize_ = other.pageSize_; + total_ = other.total_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmSegConfig Clone() { + return new DmSegConfig(this); + } + + /// Field number for the "page_size" field. + public const int PageSizeFieldNumber = 1; + private long pageSize_; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long PageSize { + get { return pageSize_; } + set { + pageSize_ = value; + } + } + + /// Field number for the "total" field. + public const int TotalFieldNumber = 2; + private long total_; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Total { + get { return total_; } + set { + total_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmSegConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmSegConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (PageSize != other.PageSize) return false; + if (Total != other.Total) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (PageSize != 0L) hash ^= PageSize.GetHashCode(); + if (Total != 0L) hash ^= Total.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (PageSize != 0L) { + output.WriteRawTag(8); + output.WriteInt64(PageSize); + } + if (Total != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Total); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (PageSize != 0L) { + output.WriteRawTag(8); + output.WriteInt64(PageSize); + } + if (Total != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Total); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (PageSize != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(PageSize); + } + if (Total != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Total); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmSegConfig other) { + if (other == null) { + return; + } + if (other.PageSize != 0L) { + PageSize = other.PageSize; + } + if (other.Total != 0L) { + Total = other.Total; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + PageSize = input.ReadInt64(); + break; + } + case 16: { + Total = input.ReadInt64(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + PageSize = input.ReadInt64(); + break; + } + case 16: { + Total = input.ReadInt64(); + break; + } + } + } + } + #endif + + } + + /// + /// 智能防挡弹幕蒙版信息 + /// + public sealed partial class VideoMask : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new VideoMask()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[11]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public VideoMask() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public VideoMask(VideoMask other) : this() { + cid_ = other.cid_; + plat_ = other.plat_; + fps_ = other.fps_; + time_ = other.time_; + maskUrl_ = other.maskUrl_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public VideoMask Clone() { + return new VideoMask(this); + } + + /// Field number for the "cid" field. + public const int CidFieldNumber = 1; + private long cid_; + /// + /// 视频cid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Cid { + get { return cid_; } + set { + cid_ = value; + } + } + + /// Field number for the "plat" field. + public const int PlatFieldNumber = 2; + private int plat_; + /// + /// 平台 + /// 0:web端 1:客户端 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Plat { + get { return plat_; } + set { + plat_ = value; + } + } + + /// Field number for the "fps" field. + public const int FpsFieldNumber = 3; + private int fps_; + /// + /// 帧率 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Fps { + get { return fps_; } + set { + fps_ = value; + } + } + + /// Field number for the "time" field. + public const int TimeFieldNumber = 4; + private long time_; + /// + /// 间隔时间 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Time { + get { return time_; } + set { + time_ = value; + } + } + + /// Field number for the "mask_url" field. + public const int MaskUrlFieldNumber = 5; + private string maskUrl_ = ""; + /// + /// 蒙版url + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string MaskUrl { + get { return maskUrl_; } + set { + maskUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as VideoMask); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(VideoMask other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Cid != other.Cid) return false; + if (Plat != other.Plat) return false; + if (Fps != other.Fps) return false; + if (Time != other.Time) return false; + if (MaskUrl != other.MaskUrl) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Cid != 0L) hash ^= Cid.GetHashCode(); + if (Plat != 0) hash ^= Plat.GetHashCode(); + if (Fps != 0) hash ^= Fps.GetHashCode(); + if (Time != 0L) hash ^= Time.GetHashCode(); + if (MaskUrl.Length != 0) hash ^= MaskUrl.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Cid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Cid); + } + if (Plat != 0) { + output.WriteRawTag(16); + output.WriteInt32(Plat); + } + if (Fps != 0) { + output.WriteRawTag(24); + output.WriteInt32(Fps); + } + if (Time != 0L) { + output.WriteRawTag(32); + output.WriteInt64(Time); + } + if (MaskUrl.Length != 0) { + output.WriteRawTag(42); + output.WriteString(MaskUrl); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Cid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Cid); + } + if (Plat != 0) { + output.WriteRawTag(16); + output.WriteInt32(Plat); + } + if (Fps != 0) { + output.WriteRawTag(24); + output.WriteInt32(Fps); + } + if (Time != 0L) { + output.WriteRawTag(32); + output.WriteInt64(Time); + } + if (MaskUrl.Length != 0) { + output.WriteRawTag(42); + output.WriteString(MaskUrl); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Cid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Cid); + } + if (Plat != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Plat); + } + if (Fps != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Fps); + } + if (Time != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Time); + } + if (MaskUrl.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(MaskUrl); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(VideoMask other) { + if (other == null) { + return; + } + if (other.Cid != 0L) { + Cid = other.Cid; + } + if (other.Plat != 0) { + Plat = other.Plat; + } + if (other.Fps != 0) { + Fps = other.Fps; + } + if (other.Time != 0L) { + Time = other.Time; + } + if (other.MaskUrl.Length != 0) { + MaskUrl = other.MaskUrl; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Cid = input.ReadInt64(); + break; + } + case 16: { + Plat = input.ReadInt32(); + break; + } + case 24: { + Fps = input.ReadInt32(); + break; + } + case 32: { + Time = input.ReadInt64(); + break; + } + case 42: { + MaskUrl = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Cid = input.ReadInt64(); + break; + } + case 16: { + Plat = input.ReadInt32(); + break; + } + case 24: { + Fps = input.ReadInt32(); + break; + } + case 32: { + Time = input.ReadInt64(); + break; + } + case 42: { + MaskUrl = input.ReadString(); + break; + } + } + } + } + #endif + + } + + /// + /// 视频字幕信息 + /// + public sealed partial class VideoSubtitle : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new VideoSubtitle()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[12]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public VideoSubtitle() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public VideoSubtitle(VideoSubtitle other) : this() { + lan_ = other.lan_; + lanDoc_ = other.lanDoc_; + subtitles_ = other.subtitles_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public VideoSubtitle Clone() { + return new VideoSubtitle(this); + } + + /// Field number for the "lan" field. + public const int LanFieldNumber = 1; + private string lan_ = ""; + /// + /// 视频原语言代码 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Lan { + get { return lan_; } + set { + lan_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "lanDoc" field. + public const int LanDocFieldNumber = 2; + private string lanDoc_ = ""; + /// + /// 视频原语言 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string LanDoc { + get { return lanDoc_; } + set { + lanDoc_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "subtitles" field. + public const int SubtitlesFieldNumber = 3; + private static readonly pb::FieldCodec _repeated_subtitles_codec + = pb::FieldCodec.ForMessage(26, global::Bilibili.Community.Service.Dm.V1.SubtitleItem.Parser); + private readonly pbc::RepeatedField subtitles_ = new pbc::RepeatedField(); + /// + /// 视频字幕列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField Subtitles { + get { return subtitles_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as VideoSubtitle); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(VideoSubtitle other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Lan != other.Lan) return false; + if (LanDoc != other.LanDoc) return false; + if(!subtitles_.Equals(other.subtitles_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Lan.Length != 0) hash ^= Lan.GetHashCode(); + if (LanDoc.Length != 0) hash ^= LanDoc.GetHashCode(); + hash ^= subtitles_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Lan.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Lan); + } + if (LanDoc.Length != 0) { + output.WriteRawTag(18); + output.WriteString(LanDoc); + } + subtitles_.WriteTo(output, _repeated_subtitles_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Lan.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Lan); + } + if (LanDoc.Length != 0) { + output.WriteRawTag(18); + output.WriteString(LanDoc); + } + subtitles_.WriteTo(ref output, _repeated_subtitles_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Lan.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Lan); + } + if (LanDoc.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(LanDoc); + } + size += subtitles_.CalculateSize(_repeated_subtitles_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(VideoSubtitle other) { + if (other == null) { + return; + } + if (other.Lan.Length != 0) { + Lan = other.Lan; + } + if (other.LanDoc.Length != 0) { + LanDoc = other.LanDoc; + } + subtitles_.Add(other.subtitles_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + Lan = input.ReadString(); + break; + } + case 18: { + LanDoc = input.ReadString(); + break; + } + case 26: { + subtitles_.AddEntriesFrom(input, _repeated_subtitles_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Lan = input.ReadString(); + break; + } + case 18: { + LanDoc = input.ReadString(); + break; + } + case 26: { + subtitles_.AddEntriesFrom(ref input, _repeated_subtitles_codec); + break; + } + } + } + } + #endif + + } + + /// + /// web端用户弹幕配置 + /// + public sealed partial class DanmuWebPlayerConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmuWebPlayerConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[13]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuWebPlayerConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuWebPlayerConfig(DanmuWebPlayerConfig other) : this() { + dmSwitch_ = other.dmSwitch_; + aiSwitch_ = other.aiSwitch_; + aiLevel_ = other.aiLevel_; + blocktop_ = other.blocktop_; + blockscroll_ = other.blockscroll_; + blockbottom_ = other.blockbottom_; + blockcolor_ = other.blockcolor_; + blockspecial_ = other.blockspecial_; + preventshade_ = other.preventshade_; + dmask_ = other.dmask_; + opacity_ = other.opacity_; + dmarea_ = other.dmarea_; + speedplus_ = other.speedplus_; + fontsize_ = other.fontsize_; + screensync_ = other.screensync_; + speedsync_ = other.speedsync_; + fontfamily_ = other.fontfamily_; + bold_ = other.bold_; + fontborder_ = other.fontborder_; + drawType_ = other.drawType_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuWebPlayerConfig Clone() { + return new DanmuWebPlayerConfig(this); + } + + /// Field number for the "dm_switch" field. + public const int DmSwitchFieldNumber = 1; + private bool dmSwitch_; + /// + /// 是否开启弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool DmSwitch { + get { return dmSwitch_; } + set { + dmSwitch_ = value; + } + } + + /// Field number for the "ai_switch" field. + public const int AiSwitchFieldNumber = 2; + private bool aiSwitch_; + /// + /// 是否开启智能云屏蔽 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool AiSwitch { + get { return aiSwitch_; } + set { + aiSwitch_ = value; + } + } + + /// Field number for the "ai_level" field. + public const int AiLevelFieldNumber = 3; + private int aiLevel_; + /// + /// 智能云屏蔽等级 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int AiLevel { + get { return aiLevel_; } + set { + aiLevel_ = value; + } + } + + /// Field number for the "blocktop" field. + public const int BlocktopFieldNumber = 4; + private bool blocktop_; + /// + /// 是否屏蔽顶端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Blocktop { + get { return blocktop_; } + set { + blocktop_ = value; + } + } + + /// Field number for the "blockscroll" field. + public const int BlockscrollFieldNumber = 5; + private bool blockscroll_; + /// + /// 是否屏蔽滚动弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Blockscroll { + get { return blockscroll_; } + set { + blockscroll_ = value; + } + } + + /// Field number for the "blockbottom" field. + public const int BlockbottomFieldNumber = 6; + private bool blockbottom_; + /// + /// 是否屏蔽底端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Blockbottom { + get { return blockbottom_; } + set { + blockbottom_ = value; + } + } + + /// Field number for the "blockcolor" field. + public const int BlockcolorFieldNumber = 7; + private bool blockcolor_; + /// + /// 是否屏蔽彩色弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Blockcolor { + get { return blockcolor_; } + set { + blockcolor_ = value; + } + } + + /// Field number for the "blockspecial" field. + public const int BlockspecialFieldNumber = 8; + private bool blockspecial_; + /// + /// 是否屏蔽重复弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Blockspecial { + get { return blockspecial_; } + set { + blockspecial_ = value; + } + } + + /// Field number for the "preventshade" field. + public const int PreventshadeFieldNumber = 9; + private bool preventshade_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Preventshade { + get { return preventshade_; } + set { + preventshade_ = value; + } + } + + /// Field number for the "dmask" field. + public const int DmaskFieldNumber = 10; + private bool dmask_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Dmask { + get { return dmask_; } + set { + dmask_ = value; + } + } + + /// Field number for the "opacity" field. + public const int OpacityFieldNumber = 11; + private float opacity_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float Opacity { + get { return opacity_; } + set { + opacity_ = value; + } + } + + /// Field number for the "dmarea" field. + public const int DmareaFieldNumber = 12; + private int dmarea_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Dmarea { + get { return dmarea_; } + set { + dmarea_ = value; + } + } + + /// Field number for the "speedplus" field. + public const int SpeedplusFieldNumber = 13; + private float speedplus_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float Speedplus { + get { return speedplus_; } + set { + speedplus_ = value; + } + } + + /// Field number for the "fontsize" field. + public const int FontsizeFieldNumber = 14; + private float fontsize_; + /// + /// 弹幕字号 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float Fontsize { + get { return fontsize_; } + set { + fontsize_ = value; + } + } + + /// Field number for the "screensync" field. + public const int ScreensyncFieldNumber = 15; + private bool screensync_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Screensync { + get { return screensync_; } + set { + screensync_ = value; + } + } + + /// Field number for the "speedsync" field. + public const int SpeedsyncFieldNumber = 16; + private bool speedsync_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Speedsync { + get { return speedsync_; } + set { + speedsync_ = value; + } + } + + /// Field number for the "fontfamily" field. + public const int FontfamilyFieldNumber = 17; + private string fontfamily_ = ""; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Fontfamily { + get { return fontfamily_; } + set { + fontfamily_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "bold" field. + public const int BoldFieldNumber = 18; + private bool bold_; + /// + /// 是否使用加粗 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Bold { + get { return bold_; } + set { + bold_ = value; + } + } + + /// Field number for the "fontborder" field. + public const int FontborderFieldNumber = 19; + private int fontborder_; + /// + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Fontborder { + get { return fontborder_; } + set { + fontborder_ = value; + } + } + + /// Field number for the "draw_type" field. + public const int DrawTypeFieldNumber = 20; + private string drawType_ = ""; + /// + /// 弹幕渲染类型 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string DrawType { + get { return drawType_; } + set { + drawType_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmuWebPlayerConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmuWebPlayerConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (DmSwitch != other.DmSwitch) return false; + if (AiSwitch != other.AiSwitch) return false; + if (AiLevel != other.AiLevel) return false; + if (Blocktop != other.Blocktop) return false; + if (Blockscroll != other.Blockscroll) return false; + if (Blockbottom != other.Blockbottom) return false; + if (Blockcolor != other.Blockcolor) return false; + if (Blockspecial != other.Blockspecial) return false; + if (Preventshade != other.Preventshade) return false; + if (Dmask != other.Dmask) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Opacity, other.Opacity)) return false; + if (Dmarea != other.Dmarea) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Speedplus, other.Speedplus)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Fontsize, other.Fontsize)) return false; + if (Screensync != other.Screensync) return false; + if (Speedsync != other.Speedsync) return false; + if (Fontfamily != other.Fontfamily) return false; + if (Bold != other.Bold) return false; + if (Fontborder != other.Fontborder) return false; + if (DrawType != other.DrawType) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (DmSwitch != false) hash ^= DmSwitch.GetHashCode(); + if (AiSwitch != false) hash ^= AiSwitch.GetHashCode(); + if (AiLevel != 0) hash ^= AiLevel.GetHashCode(); + if (Blocktop != false) hash ^= Blocktop.GetHashCode(); + if (Blockscroll != false) hash ^= Blockscroll.GetHashCode(); + if (Blockbottom != false) hash ^= Blockbottom.GetHashCode(); + if (Blockcolor != false) hash ^= Blockcolor.GetHashCode(); + if (Blockspecial != false) hash ^= Blockspecial.GetHashCode(); + if (Preventshade != false) hash ^= Preventshade.GetHashCode(); + if (Dmask != false) hash ^= Dmask.GetHashCode(); + if (Opacity != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Opacity); + if (Dmarea != 0) hash ^= Dmarea.GetHashCode(); + if (Speedplus != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Speedplus); + if (Fontsize != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Fontsize); + if (Screensync != false) hash ^= Screensync.GetHashCode(); + if (Speedsync != false) hash ^= Speedsync.GetHashCode(); + if (Fontfamily.Length != 0) hash ^= Fontfamily.GetHashCode(); + if (Bold != false) hash ^= Bold.GetHashCode(); + if (Fontborder != 0) hash ^= Fontborder.GetHashCode(); + if (DrawType.Length != 0) hash ^= DrawType.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (DmSwitch != false) { + output.WriteRawTag(8); + output.WriteBool(DmSwitch); + } + if (AiSwitch != false) { + output.WriteRawTag(16); + output.WriteBool(AiSwitch); + } + if (AiLevel != 0) { + output.WriteRawTag(24); + output.WriteInt32(AiLevel); + } + if (Blocktop != false) { + output.WriteRawTag(32); + output.WriteBool(Blocktop); + } + if (Blockscroll != false) { + output.WriteRawTag(40); + output.WriteBool(Blockscroll); + } + if (Blockbottom != false) { + output.WriteRawTag(48); + output.WriteBool(Blockbottom); + } + if (Blockcolor != false) { + output.WriteRawTag(56); + output.WriteBool(Blockcolor); + } + if (Blockspecial != false) { + output.WriteRawTag(64); + output.WriteBool(Blockspecial); + } + if (Preventshade != false) { + output.WriteRawTag(72); + output.WriteBool(Preventshade); + } + if (Dmask != false) { + output.WriteRawTag(80); + output.WriteBool(Dmask); + } + if (Opacity != 0F) { + output.WriteRawTag(93); + output.WriteFloat(Opacity); + } + if (Dmarea != 0) { + output.WriteRawTag(96); + output.WriteInt32(Dmarea); + } + if (Speedplus != 0F) { + output.WriteRawTag(109); + output.WriteFloat(Speedplus); + } + if (Fontsize != 0F) { + output.WriteRawTag(117); + output.WriteFloat(Fontsize); + } + if (Screensync != false) { + output.WriteRawTag(120); + output.WriteBool(Screensync); + } + if (Speedsync != false) { + output.WriteRawTag(128, 1); + output.WriteBool(Speedsync); + } + if (Fontfamily.Length != 0) { + output.WriteRawTag(138, 1); + output.WriteString(Fontfamily); + } + if (Bold != false) { + output.WriteRawTag(144, 1); + output.WriteBool(Bold); + } + if (Fontborder != 0) { + output.WriteRawTag(152, 1); + output.WriteInt32(Fontborder); + } + if (DrawType.Length != 0) { + output.WriteRawTag(162, 1); + output.WriteString(DrawType); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (DmSwitch != false) { + output.WriteRawTag(8); + output.WriteBool(DmSwitch); + } + if (AiSwitch != false) { + output.WriteRawTag(16); + output.WriteBool(AiSwitch); + } + if (AiLevel != 0) { + output.WriteRawTag(24); + output.WriteInt32(AiLevel); + } + if (Blocktop != false) { + output.WriteRawTag(32); + output.WriteBool(Blocktop); + } + if (Blockscroll != false) { + output.WriteRawTag(40); + output.WriteBool(Blockscroll); + } + if (Blockbottom != false) { + output.WriteRawTag(48); + output.WriteBool(Blockbottom); + } + if (Blockcolor != false) { + output.WriteRawTag(56); + output.WriteBool(Blockcolor); + } + if (Blockspecial != false) { + output.WriteRawTag(64); + output.WriteBool(Blockspecial); + } + if (Preventshade != false) { + output.WriteRawTag(72); + output.WriteBool(Preventshade); + } + if (Dmask != false) { + output.WriteRawTag(80); + output.WriteBool(Dmask); + } + if (Opacity != 0F) { + output.WriteRawTag(93); + output.WriteFloat(Opacity); + } + if (Dmarea != 0) { + output.WriteRawTag(96); + output.WriteInt32(Dmarea); + } + if (Speedplus != 0F) { + output.WriteRawTag(109); + output.WriteFloat(Speedplus); + } + if (Fontsize != 0F) { + output.WriteRawTag(117); + output.WriteFloat(Fontsize); + } + if (Screensync != false) { + output.WriteRawTag(120); + output.WriteBool(Screensync); + } + if (Speedsync != false) { + output.WriteRawTag(128, 1); + output.WriteBool(Speedsync); + } + if (Fontfamily.Length != 0) { + output.WriteRawTag(138, 1); + output.WriteString(Fontfamily); + } + if (Bold != false) { + output.WriteRawTag(144, 1); + output.WriteBool(Bold); + } + if (Fontborder != 0) { + output.WriteRawTag(152, 1); + output.WriteInt32(Fontborder); + } + if (DrawType.Length != 0) { + output.WriteRawTag(162, 1); + output.WriteString(DrawType); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (DmSwitch != false) { + size += 1 + 1; + } + if (AiSwitch != false) { + size += 1 + 1; + } + if (AiLevel != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(AiLevel); + } + if (Blocktop != false) { + size += 1 + 1; + } + if (Blockscroll != false) { + size += 1 + 1; + } + if (Blockbottom != false) { + size += 1 + 1; + } + if (Blockcolor != false) { + size += 1 + 1; + } + if (Blockspecial != false) { + size += 1 + 1; + } + if (Preventshade != false) { + size += 1 + 1; + } + if (Dmask != false) { + size += 1 + 1; + } + if (Opacity != 0F) { + size += 1 + 4; + } + if (Dmarea != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Dmarea); + } + if (Speedplus != 0F) { + size += 1 + 4; + } + if (Fontsize != 0F) { + size += 1 + 4; + } + if (Screensync != false) { + size += 1 + 1; + } + if (Speedsync != false) { + size += 2 + 1; + } + if (Fontfamily.Length != 0) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(Fontfamily); + } + if (Bold != false) { + size += 2 + 1; + } + if (Fontborder != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fontborder); + } + if (DrawType.Length != 0) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(DrawType); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmuWebPlayerConfig other) { + if (other == null) { + return; + } + if (other.DmSwitch != false) { + DmSwitch = other.DmSwitch; + } + if (other.AiSwitch != false) { + AiSwitch = other.AiSwitch; + } + if (other.AiLevel != 0) { + AiLevel = other.AiLevel; + } + if (other.Blocktop != false) { + Blocktop = other.Blocktop; + } + if (other.Blockscroll != false) { + Blockscroll = other.Blockscroll; + } + if (other.Blockbottom != false) { + Blockbottom = other.Blockbottom; + } + if (other.Blockcolor != false) { + Blockcolor = other.Blockcolor; + } + if (other.Blockspecial != false) { + Blockspecial = other.Blockspecial; + } + if (other.Preventshade != false) { + Preventshade = other.Preventshade; + } + if (other.Dmask != false) { + Dmask = other.Dmask; + } + if (other.Opacity != 0F) { + Opacity = other.Opacity; + } + if (other.Dmarea != 0) { + Dmarea = other.Dmarea; + } + if (other.Speedplus != 0F) { + Speedplus = other.Speedplus; + } + if (other.Fontsize != 0F) { + Fontsize = other.Fontsize; + } + if (other.Screensync != false) { + Screensync = other.Screensync; + } + if (other.Speedsync != false) { + Speedsync = other.Speedsync; + } + if (other.Fontfamily.Length != 0) { + Fontfamily = other.Fontfamily; + } + if (other.Bold != false) { + Bold = other.Bold; + } + if (other.Fontborder != 0) { + Fontborder = other.Fontborder; + } + if (other.DrawType.Length != 0) { + DrawType = other.DrawType; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + DmSwitch = input.ReadBool(); + break; + } + case 16: { + AiSwitch = input.ReadBool(); + break; + } + case 24: { + AiLevel = input.ReadInt32(); + break; + } + case 32: { + Blocktop = input.ReadBool(); + break; + } + case 40: { + Blockscroll = input.ReadBool(); + break; + } + case 48: { + Blockbottom = input.ReadBool(); + break; + } + case 56: { + Blockcolor = input.ReadBool(); + break; + } + case 64: { + Blockspecial = input.ReadBool(); + break; + } + case 72: { + Preventshade = input.ReadBool(); + break; + } + case 80: { + Dmask = input.ReadBool(); + break; + } + case 93: { + Opacity = input.ReadFloat(); + break; + } + case 96: { + Dmarea = input.ReadInt32(); + break; + } + case 109: { + Speedplus = input.ReadFloat(); + break; + } + case 117: { + Fontsize = input.ReadFloat(); + break; + } + case 120: { + Screensync = input.ReadBool(); + break; + } + case 128: { + Speedsync = input.ReadBool(); + break; + } + case 138: { + Fontfamily = input.ReadString(); + break; + } + case 144: { + Bold = input.ReadBool(); + break; + } + case 152: { + Fontborder = input.ReadInt32(); + break; + } + case 162: { + DrawType = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + DmSwitch = input.ReadBool(); + break; + } + case 16: { + AiSwitch = input.ReadBool(); + break; + } + case 24: { + AiLevel = input.ReadInt32(); + break; + } + case 32: { + Blocktop = input.ReadBool(); + break; + } + case 40: { + Blockscroll = input.ReadBool(); + break; + } + case 48: { + Blockbottom = input.ReadBool(); + break; + } + case 56: { + Blockcolor = input.ReadBool(); + break; + } + case 64: { + Blockspecial = input.ReadBool(); + break; + } + case 72: { + Preventshade = input.ReadBool(); + break; + } + case 80: { + Dmask = input.ReadBool(); + break; + } + case 93: { + Opacity = input.ReadFloat(); + break; + } + case 96: { + Dmarea = input.ReadInt32(); + break; + } + case 109: { + Speedplus = input.ReadFloat(); + break; + } + case 117: { + Fontsize = input.ReadFloat(); + break; + } + case 120: { + Screensync = input.ReadBool(); + break; + } + case 128: { + Speedsync = input.ReadBool(); + break; + } + case 138: { + Fontfamily = input.ReadString(); + break; + } + case 144: { + Bold = input.ReadBool(); + break; + } + case 152: { + Fontborder = input.ReadInt32(); + break; + } + case 162: { + DrawType = input.ReadString(); + break; + } + } + } + } + #endif + + } + + /// + /// 单个字幕信息 + /// + public sealed partial class SubtitleItem : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SubtitleItem()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[14]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public SubtitleItem() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public SubtitleItem(SubtitleItem other) : this() { + id_ = other.id_; + idStr_ = other.idStr_; + lan_ = other.lan_; + lanDoc_ = other.lanDoc_; + subtitleUrl_ = other.subtitleUrl_; + author_ = other.author_ != null ? other.author_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public SubtitleItem Clone() { + return new SubtitleItem(this); + } + + /// Field number for the "id" field. + public const int IdFieldNumber = 1; + private long id_; + /// + /// 字幕id + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Id { + get { return id_; } + set { + id_ = value; + } + } + + /// Field number for the "id_str" field. + public const int IdStrFieldNumber = 2; + private string idStr_ = ""; + /// + /// 字幕id str + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string IdStr { + get { return idStr_; } + set { + idStr_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "lan" field. + public const int LanFieldNumber = 3; + private string lan_ = ""; + /// + /// 字幕语言代码 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Lan { + get { return lan_; } + set { + lan_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "lan_doc" field. + public const int LanDocFieldNumber = 4; + private string lanDoc_ = ""; + /// + /// 字幕语言 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string LanDoc { + get { return lanDoc_; } + set { + lanDoc_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "subtitle_url" field. + public const int SubtitleUrlFieldNumber = 5; + private string subtitleUrl_ = ""; + /// + /// 字幕文件url + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string SubtitleUrl { + get { return subtitleUrl_; } + set { + subtitleUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "author" field. + public const int AuthorFieldNumber = 6; + private global::Bilibili.Community.Service.Dm.V1.UserInfo author_; + /// + /// 字幕作者信息 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.UserInfo Author { + get { return author_; } + set { + author_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as SubtitleItem); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(SubtitleItem other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Id != other.Id) return false; + if (IdStr != other.IdStr) return false; + if (Lan != other.Lan) return false; + if (LanDoc != other.LanDoc) return false; + if (SubtitleUrl != other.SubtitleUrl) return false; + if (!object.Equals(Author, other.Author)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Id != 0L) hash ^= Id.GetHashCode(); + if (IdStr.Length != 0) hash ^= IdStr.GetHashCode(); + if (Lan.Length != 0) hash ^= Lan.GetHashCode(); + if (LanDoc.Length != 0) hash ^= LanDoc.GetHashCode(); + if (SubtitleUrl.Length != 0) hash ^= SubtitleUrl.GetHashCode(); + if (author_ != null) hash ^= Author.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Id != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Id); + } + if (IdStr.Length != 0) { + output.WriteRawTag(18); + output.WriteString(IdStr); + } + if (Lan.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Lan); + } + if (LanDoc.Length != 0) { + output.WriteRawTag(34); + output.WriteString(LanDoc); + } + if (SubtitleUrl.Length != 0) { + output.WriteRawTag(42); + output.WriteString(SubtitleUrl); + } + if (author_ != null) { + output.WriteRawTag(50); + output.WriteMessage(Author); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Id != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Id); + } + if (IdStr.Length != 0) { + output.WriteRawTag(18); + output.WriteString(IdStr); + } + if (Lan.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Lan); + } + if (LanDoc.Length != 0) { + output.WriteRawTag(34); + output.WriteString(LanDoc); + } + if (SubtitleUrl.Length != 0) { + output.WriteRawTag(42); + output.WriteString(SubtitleUrl); + } + if (author_ != null) { + output.WriteRawTag(50); + output.WriteMessage(Author); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Id != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Id); + } + if (IdStr.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(IdStr); + } + if (Lan.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Lan); + } + if (LanDoc.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(LanDoc); + } + if (SubtitleUrl.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(SubtitleUrl); + } + if (author_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Author); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(SubtitleItem other) { + if (other == null) { + return; + } + if (other.Id != 0L) { + Id = other.Id; + } + if (other.IdStr.Length != 0) { + IdStr = other.IdStr; + } + if (other.Lan.Length != 0) { + Lan = other.Lan; + } + if (other.LanDoc.Length != 0) { + LanDoc = other.LanDoc; + } + if (other.SubtitleUrl.Length != 0) { + SubtitleUrl = other.SubtitleUrl; + } + if (other.author_ != null) { + if (author_ == null) { + Author = new global::Bilibili.Community.Service.Dm.V1.UserInfo(); + } + Author.MergeFrom(other.Author); + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Id = input.ReadInt64(); + break; + } + case 18: { + IdStr = input.ReadString(); + break; + } + case 26: { + Lan = input.ReadString(); + break; + } + case 34: { + LanDoc = input.ReadString(); + break; + } + case 42: { + SubtitleUrl = input.ReadString(); + break; + } + case 50: { + if (author_ == null) { + Author = new global::Bilibili.Community.Service.Dm.V1.UserInfo(); + } + input.ReadMessage(Author); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Id = input.ReadInt64(); + break; + } + case 18: { + IdStr = input.ReadString(); + break; + } + case 26: { + Lan = input.ReadString(); + break; + } + case 34: { + LanDoc = input.ReadString(); + break; + } + case 42: { + SubtitleUrl = input.ReadString(); + break; + } + case 50: { + if (author_ == null) { + Author = new global::Bilibili.Community.Service.Dm.V1.UserInfo(); + } + input.ReadMessage(Author); + break; + } + } + } + } + #endif + + } + + /// + /// 字幕作者信息 + /// + public sealed partial class UserInfo : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UserInfo()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[15]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public UserInfo() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public UserInfo(UserInfo other) : this() { + mid_ = other.mid_; + name_ = other.name_; + sex_ = other.sex_; + face_ = other.face_; + sign_ = other.sign_; + rank_ = other.rank_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public UserInfo Clone() { + return new UserInfo(this); + } + + /// Field number for the "mid" field. + public const int MidFieldNumber = 1; + private long mid_; + /// + /// 用户mid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Mid { + get { return mid_; } + set { + mid_ = value; + } + } + + /// Field number for the "name" field. + public const int NameFieldNumber = 2; + private string name_ = ""; + /// + /// 用户昵称 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Name { + get { return name_; } + set { + name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "sex" field. + public const int SexFieldNumber = 3; + private string sex_ = ""; + /// + /// 用户性别 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Sex { + get { return sex_; } + set { + sex_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "face" field. + public const int FaceFieldNumber = 4; + private string face_ = ""; + /// + /// 用户头像url + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Face { + get { return face_; } + set { + face_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "sign" field. + public const int SignFieldNumber = 5; + private string sign_ = ""; + /// + /// 用户签名 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Sign { + get { return sign_; } + set { + sign_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "rank" field. + public const int RankFieldNumber = 6; + private int rank_; + /// + /// 用户等级 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Rank { + get { return rank_; } + set { + rank_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as UserInfo); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(UserInfo other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Mid != other.Mid) return false; + if (Name != other.Name) return false; + if (Sex != other.Sex) return false; + if (Face != other.Face) return false; + if (Sign != other.Sign) return false; + if (Rank != other.Rank) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Mid != 0L) hash ^= Mid.GetHashCode(); + if (Name.Length != 0) hash ^= Name.GetHashCode(); + if (Sex.Length != 0) hash ^= Sex.GetHashCode(); + if (Face.Length != 0) hash ^= Face.GetHashCode(); + if (Sign.Length != 0) hash ^= Sign.GetHashCode(); + if (Rank != 0) hash ^= Rank.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Mid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Mid); + } + if (Name.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Name); + } + if (Sex.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Sex); + } + if (Face.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Face); + } + if (Sign.Length != 0) { + output.WriteRawTag(42); + output.WriteString(Sign); + } + if (Rank != 0) { + output.WriteRawTag(48); + output.WriteInt32(Rank); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Mid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Mid); + } + if (Name.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Name); + } + if (Sex.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Sex); + } + if (Face.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Face); + } + if (Sign.Length != 0) { + output.WriteRawTag(42); + output.WriteString(Sign); + } + if (Rank != 0) { + output.WriteRawTag(48); + output.WriteInt32(Rank); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Mid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Mid); + } + if (Name.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); + } + if (Sex.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Sex); + } + if (Face.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Face); + } + if (Sign.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Sign); + } + if (Rank != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Rank); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(UserInfo other) { + if (other == null) { + return; + } + if (other.Mid != 0L) { + Mid = other.Mid; + } + if (other.Name.Length != 0) { + Name = other.Name; + } + if (other.Sex.Length != 0) { + Sex = other.Sex; + } + if (other.Face.Length != 0) { + Face = other.Face; + } + if (other.Sign.Length != 0) { + Sign = other.Sign; + } + if (other.Rank != 0) { + Rank = other.Rank; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Mid = input.ReadInt64(); + break; + } + case 18: { + Name = input.ReadString(); + break; + } + case 26: { + Sex = input.ReadString(); + break; + } + case 34: { + Face = input.ReadString(); + break; + } + case 42: { + Sign = input.ReadString(); + break; + } + case 48: { + Rank = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Mid = input.ReadInt64(); + break; + } + case 18: { + Name = input.ReadString(); + break; + } + case 26: { + Sex = input.ReadString(); + break; + } + case 34: { + Face = input.ReadString(); + break; + } + case 42: { + Sign = input.ReadString(); + break; + } + case 48: { + Rank = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕条目 + /// + public sealed partial class DanmakuElem : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmakuElem()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[16]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuElem() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuElem(DanmakuElem other) : this() { + id_ = other.id_; + progress_ = other.progress_; + mode_ = other.mode_; + fontsize_ = other.fontsize_; + color_ = other.color_; + midHash_ = other.midHash_; + content_ = other.content_; + ctime_ = other.ctime_; + weight_ = other.weight_; + action_ = other.action_; + pool_ = other.pool_; + idStr_ = other.idStr_; + attr_ = other.attr_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuElem Clone() { + return new DanmakuElem(this); + } + + /// Field number for the "id" field. + public const int IdFieldNumber = 1; + private long id_; + /// + /// 弹幕dmid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Id { + get { return id_; } + set { + id_ = value; + } + } + + /// Field number for the "progress" field. + public const int ProgressFieldNumber = 2; + private int progress_; + /// + /// 弹幕出现位置(单位ms) + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Progress { + get { return progress_; } + set { + progress_ = value; + } + } + + /// Field number for the "mode" field. + public const int ModeFieldNumber = 3; + private int mode_; + /// + /// 弹幕类型 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Mode { + get { return mode_; } + set { + mode_ = value; + } + } + + /// Field number for the "fontsize" field. + public const int FontsizeFieldNumber = 4; + private int fontsize_; + /// + /// 弹幕字号 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Fontsize { + get { return fontsize_; } + set { + fontsize_ = value; + } + } + + /// Field number for the "color" field. + public const int ColorFieldNumber = 5; + private uint color_; + /// + /// 弹幕颜色 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public uint Color { + get { return color_; } + set { + color_ = value; + } + } + + /// Field number for the "midHash" field. + public const int MidHashFieldNumber = 6; + private string midHash_ = ""; + /// + /// 发送着mid hash + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string MidHash { + get { return midHash_; } + set { + midHash_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "content" field. + public const int ContentFieldNumber = 7; + private string content_ = ""; + /// + /// 弹幕正文 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Content { + get { return content_; } + set { + content_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "ctime" field. + public const int CtimeFieldNumber = 8; + private long ctime_; + /// + /// 发送时间 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Ctime { + get { return ctime_; } + set { + ctime_ = value; + } + } + + /// Field number for the "weight" field. + public const int WeightFieldNumber = 9; + private int weight_; + /// + /// 权重 区间:[1,10] + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Weight { + get { return weight_; } + set { + weight_ = value; + } + } + + /// Field number for the "action" field. + public const int ActionFieldNumber = 10; + private string action_ = ""; + /// + /// 动作 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Action { + get { return action_; } + set { + action_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "pool" field. + public const int PoolFieldNumber = 11; + private int pool_; + /// + /// 弹幕池 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Pool { + get { return pool_; } + set { + pool_ = value; + } + } + + /// Field number for the "idStr" field. + public const int IdStrFieldNumber = 12; + private string idStr_ = ""; + /// + /// 弹幕dmid str + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string IdStr { + get { return idStr_; } + set { + idStr_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "attr" field. + public const int AttrFieldNumber = 13; + private int attr_; + /// + /// 弹幕属性位(bin求AND) + /// bit0:保护 bit1:直播 bit2:高赞 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Attr { + get { return attr_; } + set { + attr_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmakuElem); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmakuElem other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Id != other.Id) return false; + if (Progress != other.Progress) return false; + if (Mode != other.Mode) return false; + if (Fontsize != other.Fontsize) return false; + if (Color != other.Color) return false; + if (MidHash != other.MidHash) return false; + if (Content != other.Content) return false; + if (Ctime != other.Ctime) return false; + if (Weight != other.Weight) return false; + if (Action != other.Action) return false; + if (Pool != other.Pool) return false; + if (IdStr != other.IdStr) return false; + if (Attr != other.Attr) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Id != 0L) hash ^= Id.GetHashCode(); + if (Progress != 0) hash ^= Progress.GetHashCode(); + if (Mode != 0) hash ^= Mode.GetHashCode(); + if (Fontsize != 0) hash ^= Fontsize.GetHashCode(); + if (Color != 0) hash ^= Color.GetHashCode(); + if (MidHash.Length != 0) hash ^= MidHash.GetHashCode(); + if (Content.Length != 0) hash ^= Content.GetHashCode(); + if (Ctime != 0L) hash ^= Ctime.GetHashCode(); + if (Weight != 0) hash ^= Weight.GetHashCode(); + if (Action.Length != 0) hash ^= Action.GetHashCode(); + if (Pool != 0) hash ^= Pool.GetHashCode(); + if (IdStr.Length != 0) hash ^= IdStr.GetHashCode(); + if (Attr != 0) hash ^= Attr.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Id != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Id); + } + if (Progress != 0) { + output.WriteRawTag(16); + output.WriteInt32(Progress); + } + if (Mode != 0) { + output.WriteRawTag(24); + output.WriteInt32(Mode); + } + if (Fontsize != 0) { + output.WriteRawTag(32); + output.WriteInt32(Fontsize); + } + if (Color != 0) { + output.WriteRawTag(40); + output.WriteUInt32(Color); + } + if (MidHash.Length != 0) { + output.WriteRawTag(50); + output.WriteString(MidHash); + } + if (Content.Length != 0) { + output.WriteRawTag(58); + output.WriteString(Content); + } + if (Ctime != 0L) { + output.WriteRawTag(64); + output.WriteInt64(Ctime); + } + if (Weight != 0) { + output.WriteRawTag(72); + output.WriteInt32(Weight); + } + if (Action.Length != 0) { + output.WriteRawTag(82); + output.WriteString(Action); + } + if (Pool != 0) { + output.WriteRawTag(88); + output.WriteInt32(Pool); + } + if (IdStr.Length != 0) { + output.WriteRawTag(98); + output.WriteString(IdStr); + } + if (Attr != 0) { + output.WriteRawTag(104); + output.WriteInt32(Attr); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Id != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Id); + } + if (Progress != 0) { + output.WriteRawTag(16); + output.WriteInt32(Progress); + } + if (Mode != 0) { + output.WriteRawTag(24); + output.WriteInt32(Mode); + } + if (Fontsize != 0) { + output.WriteRawTag(32); + output.WriteInt32(Fontsize); + } + if (Color != 0) { + output.WriteRawTag(40); + output.WriteUInt32(Color); + } + if (MidHash.Length != 0) { + output.WriteRawTag(50); + output.WriteString(MidHash); + } + if (Content.Length != 0) { + output.WriteRawTag(58); + output.WriteString(Content); + } + if (Ctime != 0L) { + output.WriteRawTag(64); + output.WriteInt64(Ctime); + } + if (Weight != 0) { + output.WriteRawTag(72); + output.WriteInt32(Weight); + } + if (Action.Length != 0) { + output.WriteRawTag(82); + output.WriteString(Action); + } + if (Pool != 0) { + output.WriteRawTag(88); + output.WriteInt32(Pool); + } + if (IdStr.Length != 0) { + output.WriteRawTag(98); + output.WriteString(IdStr); + } + if (Attr != 0) { + output.WriteRawTag(104); + output.WriteInt32(Attr); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Id != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Id); + } + if (Progress != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Progress); + } + if (Mode != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Mode); + } + if (Fontsize != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Fontsize); + } + if (Color != 0) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Color); + } + if (MidHash.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(MidHash); + } + if (Content.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Content); + } + if (Ctime != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Ctime); + } + if (Weight != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Weight); + } + if (Action.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Action); + } + if (Pool != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Pool); + } + if (IdStr.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(IdStr); + } + if (Attr != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Attr); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmakuElem other) { + if (other == null) { + return; + } + if (other.Id != 0L) { + Id = other.Id; + } + if (other.Progress != 0) { + Progress = other.Progress; + } + if (other.Mode != 0) { + Mode = other.Mode; + } + if (other.Fontsize != 0) { + Fontsize = other.Fontsize; + } + if (other.Color != 0) { + Color = other.Color; + } + if (other.MidHash.Length != 0) { + MidHash = other.MidHash; + } + if (other.Content.Length != 0) { + Content = other.Content; + } + if (other.Ctime != 0L) { + Ctime = other.Ctime; + } + if (other.Weight != 0) { + Weight = other.Weight; + } + if (other.Action.Length != 0) { + Action = other.Action; + } + if (other.Pool != 0) { + Pool = other.Pool; + } + if (other.IdStr.Length != 0) { + IdStr = other.IdStr; + } + if (other.Attr != 0) { + Attr = other.Attr; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Id = input.ReadInt64(); + break; + } + case 16: { + Progress = input.ReadInt32(); + break; + } + case 24: { + Mode = input.ReadInt32(); + break; + } + case 32: { + Fontsize = input.ReadInt32(); + break; + } + case 40: { + Color = input.ReadUInt32(); + break; + } + case 50: { + MidHash = input.ReadString(); + break; + } + case 58: { + Content = input.ReadString(); + break; + } + case 64: { + Ctime = input.ReadInt64(); + break; + } + case 72: { + Weight = input.ReadInt32(); + break; + } + case 82: { + Action = input.ReadString(); + break; + } + case 88: { + Pool = input.ReadInt32(); + break; + } + case 98: { + IdStr = input.ReadString(); + break; + } + case 104: { + Attr = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Id = input.ReadInt64(); + break; + } + case 16: { + Progress = input.ReadInt32(); + break; + } + case 24: { + Mode = input.ReadInt32(); + break; + } + case 32: { + Fontsize = input.ReadInt32(); + break; + } + case 40: { + Color = input.ReadUInt32(); + break; + } + case 50: { + MidHash = input.ReadString(); + break; + } + case 58: { + Content = input.ReadString(); + break; + } + case 64: { + Ctime = input.ReadInt64(); + break; + } + case 72: { + Weight = input.ReadInt32(); + break; + } + case 82: { + Action = input.ReadString(); + break; + } + case 88: { + Pool = input.ReadInt32(); + break; + } + case 98: { + IdStr = input.ReadString(); + break; + } + case 104: { + Attr = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 修改弹幕配置-请求 + /// + public sealed partial class DmPlayerConfigReq : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DmPlayerConfigReq()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[17]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmPlayerConfigReq() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmPlayerConfigReq(DmPlayerConfigReq other) : this() { + ts_ = other.ts_; + switch_ = other.switch_ != null ? other.switch_.Clone() : null; + switchSave_ = other.switchSave_ != null ? other.switchSave_.Clone() : null; + useDefaultConfig_ = other.useDefaultConfig_ != null ? other.useDefaultConfig_.Clone() : null; + aiRecommendedSwitch_ = other.aiRecommendedSwitch_ != null ? other.aiRecommendedSwitch_.Clone() : null; + aiRecommendedLevel_ = other.aiRecommendedLevel_ != null ? other.aiRecommendedLevel_.Clone() : null; + blocktop_ = other.blocktop_ != null ? other.blocktop_.Clone() : null; + blockscroll_ = other.blockscroll_ != null ? other.blockscroll_.Clone() : null; + blockbottom_ = other.blockbottom_ != null ? other.blockbottom_.Clone() : null; + blockcolorful_ = other.blockcolorful_ != null ? other.blockcolorful_.Clone() : null; + blockrepeat_ = other.blockrepeat_ != null ? other.blockrepeat_.Clone() : null; + blockspecial_ = other.blockspecial_ != null ? other.blockspecial_.Clone() : null; + opacity_ = other.opacity_ != null ? other.opacity_.Clone() : null; + scalingfactor_ = other.scalingfactor_ != null ? other.scalingfactor_.Clone() : null; + domain_ = other.domain_ != null ? other.domain_.Clone() : null; + speed_ = other.speed_ != null ? other.speed_.Clone() : null; + enableblocklist_ = other.enableblocklist_ != null ? other.enableblocklist_.Clone() : null; + inlinePlayerDanmakuSwitch_ = other.inlinePlayerDanmakuSwitch_ != null ? other.inlinePlayerDanmakuSwitch_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DmPlayerConfigReq Clone() { + return new DmPlayerConfigReq(this); + } + + /// Field number for the "ts" field. + public const int TsFieldNumber = 1; + private long ts_; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Ts { + get { return ts_; } + set { + ts_ = value; + } + } + + /// Field number for the "switch" field. + public const int SwitchFieldNumber = 2; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch switch_; + /// + /// 是否开启弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch Switch { + get { return switch_; } + set { + switch_ = value; + } + } + + /// Field number for the "switch_save" field. + public const int SwitchSaveFieldNumber = 3; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave switchSave_; + /// + /// 是否记录弹幕开关设置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave SwitchSave { + get { return switchSave_; } + set { + switchSave_ = value; + } + } + + /// Field number for the "use_default_config" field. + public const int UseDefaultConfigFieldNumber = 4; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig useDefaultConfig_; + /// + /// 是否使用推荐弹幕设置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig UseDefaultConfig { + get { return useDefaultConfig_; } + set { + useDefaultConfig_ = value; + } + } + + /// Field number for the "ai_recommended_switch" field. + public const int AiRecommendedSwitchFieldNumber = 5; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch aiRecommendedSwitch_; + /// + /// 是否开启智能云屏蔽 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch AiRecommendedSwitch { + get { return aiRecommendedSwitch_; } + set { + aiRecommendedSwitch_ = value; + } + } + + /// Field number for the "ai_recommended_level" field. + public const int AiRecommendedLevelFieldNumber = 6; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel aiRecommendedLevel_; + /// + /// 智能云屏蔽等级 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel AiRecommendedLevel { + get { return aiRecommendedLevel_; } + set { + aiRecommendedLevel_ = value; + } + } + + /// Field number for the "blocktop" field. + public const int BlocktopFieldNumber = 7; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop blocktop_; + /// + /// 是否屏蔽顶端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop Blocktop { + get { return blocktop_; } + set { + blocktop_ = value; + } + } + + /// Field number for the "blockscroll" field. + public const int BlockscrollFieldNumber = 8; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll blockscroll_; + /// + /// 是否屏蔽滚动弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll Blockscroll { + get { return blockscroll_; } + set { + blockscroll_ = value; + } + } + + /// Field number for the "blockbottom" field. + public const int BlockbottomFieldNumber = 9; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom blockbottom_; + /// + /// 是否屏蔽底端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom Blockbottom { + get { return blockbottom_; } + set { + blockbottom_ = value; + } + } + + /// Field number for the "blockcolorful" field. + public const int BlockcolorfulFieldNumber = 10; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful blockcolorful_; + /// + /// 是否屏蔽彩色弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful Blockcolorful { + get { return blockcolorful_; } + set { + blockcolorful_ = value; + } + } + + /// Field number for the "blockrepeat" field. + public const int BlockrepeatFieldNumber = 11; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat blockrepeat_; + /// + /// 是否屏蔽重复弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat Blockrepeat { + get { return blockrepeat_; } + set { + blockrepeat_ = value; + } + } + + /// Field number for the "blockspecial" field. + public const int BlockspecialFieldNumber = 12; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial blockspecial_; + /// + /// 是否屏蔽高级弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial Blockspecial { + get { return blockspecial_; } + set { + blockspecial_ = value; + } + } + + /// Field number for the "opacity" field. + public const int OpacityFieldNumber = 13; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity opacity_; + /// + /// 弹幕不透明度 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity Opacity { + get { return opacity_; } + set { + opacity_ = value; + } + } + + /// Field number for the "scalingfactor" field. + public const int ScalingfactorFieldNumber = 14; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor scalingfactor_; + /// + /// 弹幕缩放比例 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor Scalingfactor { + get { return scalingfactor_; } + set { + scalingfactor_ = value; + } + } + + /// Field number for the "domain" field. + public const int DomainFieldNumber = 15; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain domain_; + /// + /// 弹幕显示区域 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain Domain { + get { return domain_; } + set { + domain_ = value; + } + } + + /// Field number for the "speed" field. + public const int SpeedFieldNumber = 16; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed speed_; + /// + /// 弹幕速度 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed Speed { + get { return speed_; } + set { + speed_ = value; + } + } + + /// Field number for the "enableblocklist" field. + public const int EnableblocklistFieldNumber = 17; + private global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist enableblocklist_; + /// + /// 是否开启屏蔽列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist Enableblocklist { + get { return enableblocklist_; } + set { + enableblocklist_ = value; + } + } + + /// Field number for the "inlinePlayerDanmakuSwitch" field. + public const int InlinePlayerDanmakuSwitchFieldNumber = 18; + private global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch inlinePlayerDanmakuSwitch_; + /// + /// 是否开启弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch InlinePlayerDanmakuSwitch { + get { return inlinePlayerDanmakuSwitch_; } + set { + inlinePlayerDanmakuSwitch_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DmPlayerConfigReq); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DmPlayerConfigReq other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Ts != other.Ts) return false; + if (!object.Equals(Switch, other.Switch)) return false; + if (!object.Equals(SwitchSave, other.SwitchSave)) return false; + if (!object.Equals(UseDefaultConfig, other.UseDefaultConfig)) return false; + if (!object.Equals(AiRecommendedSwitch, other.AiRecommendedSwitch)) return false; + if (!object.Equals(AiRecommendedLevel, other.AiRecommendedLevel)) return false; + if (!object.Equals(Blocktop, other.Blocktop)) return false; + if (!object.Equals(Blockscroll, other.Blockscroll)) return false; + if (!object.Equals(Blockbottom, other.Blockbottom)) return false; + if (!object.Equals(Blockcolorful, other.Blockcolorful)) return false; + if (!object.Equals(Blockrepeat, other.Blockrepeat)) return false; + if (!object.Equals(Blockspecial, other.Blockspecial)) return false; + if (!object.Equals(Opacity, other.Opacity)) return false; + if (!object.Equals(Scalingfactor, other.Scalingfactor)) return false; + if (!object.Equals(Domain, other.Domain)) return false; + if (!object.Equals(Speed, other.Speed)) return false; + if (!object.Equals(Enableblocklist, other.Enableblocklist)) return false; + if (!object.Equals(InlinePlayerDanmakuSwitch, other.InlinePlayerDanmakuSwitch)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Ts != 0L) hash ^= Ts.GetHashCode(); + if (switch_ != null) hash ^= Switch.GetHashCode(); + if (switchSave_ != null) hash ^= SwitchSave.GetHashCode(); + if (useDefaultConfig_ != null) hash ^= UseDefaultConfig.GetHashCode(); + if (aiRecommendedSwitch_ != null) hash ^= AiRecommendedSwitch.GetHashCode(); + if (aiRecommendedLevel_ != null) hash ^= AiRecommendedLevel.GetHashCode(); + if (blocktop_ != null) hash ^= Blocktop.GetHashCode(); + if (blockscroll_ != null) hash ^= Blockscroll.GetHashCode(); + if (blockbottom_ != null) hash ^= Blockbottom.GetHashCode(); + if (blockcolorful_ != null) hash ^= Blockcolorful.GetHashCode(); + if (blockrepeat_ != null) hash ^= Blockrepeat.GetHashCode(); + if (blockspecial_ != null) hash ^= Blockspecial.GetHashCode(); + if (opacity_ != null) hash ^= Opacity.GetHashCode(); + if (scalingfactor_ != null) hash ^= Scalingfactor.GetHashCode(); + if (domain_ != null) hash ^= Domain.GetHashCode(); + if (speed_ != null) hash ^= Speed.GetHashCode(); + if (enableblocklist_ != null) hash ^= Enableblocklist.GetHashCode(); + if (inlinePlayerDanmakuSwitch_ != null) hash ^= InlinePlayerDanmakuSwitch.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Ts != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Ts); + } + if (switch_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Switch); + } + if (switchSave_ != null) { + output.WriteRawTag(26); + output.WriteMessage(SwitchSave); + } + if (useDefaultConfig_ != null) { + output.WriteRawTag(34); + output.WriteMessage(UseDefaultConfig); + } + if (aiRecommendedSwitch_ != null) { + output.WriteRawTag(42); + output.WriteMessage(AiRecommendedSwitch); + } + if (aiRecommendedLevel_ != null) { + output.WriteRawTag(50); + output.WriteMessage(AiRecommendedLevel); + } + if (blocktop_ != null) { + output.WriteRawTag(58); + output.WriteMessage(Blocktop); + } + if (blockscroll_ != null) { + output.WriteRawTag(66); + output.WriteMessage(Blockscroll); + } + if (blockbottom_ != null) { + output.WriteRawTag(74); + output.WriteMessage(Blockbottom); + } + if (blockcolorful_ != null) { + output.WriteRawTag(82); + output.WriteMessage(Blockcolorful); + } + if (blockrepeat_ != null) { + output.WriteRawTag(90); + output.WriteMessage(Blockrepeat); + } + if (blockspecial_ != null) { + output.WriteRawTag(98); + output.WriteMessage(Blockspecial); + } + if (opacity_ != null) { + output.WriteRawTag(106); + output.WriteMessage(Opacity); + } + if (scalingfactor_ != null) { + output.WriteRawTag(114); + output.WriteMessage(Scalingfactor); + } + if (domain_ != null) { + output.WriteRawTag(122); + output.WriteMessage(Domain); + } + if (speed_ != null) { + output.WriteRawTag(130, 1); + output.WriteMessage(Speed); + } + if (enableblocklist_ != null) { + output.WriteRawTag(138, 1); + output.WriteMessage(Enableblocklist); + } + if (inlinePlayerDanmakuSwitch_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(InlinePlayerDanmakuSwitch); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Ts != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Ts); + } + if (switch_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Switch); + } + if (switchSave_ != null) { + output.WriteRawTag(26); + output.WriteMessage(SwitchSave); + } + if (useDefaultConfig_ != null) { + output.WriteRawTag(34); + output.WriteMessage(UseDefaultConfig); + } + if (aiRecommendedSwitch_ != null) { + output.WriteRawTag(42); + output.WriteMessage(AiRecommendedSwitch); + } + if (aiRecommendedLevel_ != null) { + output.WriteRawTag(50); + output.WriteMessage(AiRecommendedLevel); + } + if (blocktop_ != null) { + output.WriteRawTag(58); + output.WriteMessage(Blocktop); + } + if (blockscroll_ != null) { + output.WriteRawTag(66); + output.WriteMessage(Blockscroll); + } + if (blockbottom_ != null) { + output.WriteRawTag(74); + output.WriteMessage(Blockbottom); + } + if (blockcolorful_ != null) { + output.WriteRawTag(82); + output.WriteMessage(Blockcolorful); + } + if (blockrepeat_ != null) { + output.WriteRawTag(90); + output.WriteMessage(Blockrepeat); + } + if (blockspecial_ != null) { + output.WriteRawTag(98); + output.WriteMessage(Blockspecial); + } + if (opacity_ != null) { + output.WriteRawTag(106); + output.WriteMessage(Opacity); + } + if (scalingfactor_ != null) { + output.WriteRawTag(114); + output.WriteMessage(Scalingfactor); + } + if (domain_ != null) { + output.WriteRawTag(122); + output.WriteMessage(Domain); + } + if (speed_ != null) { + output.WriteRawTag(130, 1); + output.WriteMessage(Speed); + } + if (enableblocklist_ != null) { + output.WriteRawTag(138, 1); + output.WriteMessage(Enableblocklist); + } + if (inlinePlayerDanmakuSwitch_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(InlinePlayerDanmakuSwitch); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Ts != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Ts); + } + if (switch_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Switch); + } + if (switchSave_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(SwitchSave); + } + if (useDefaultConfig_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(UseDefaultConfig); + } + if (aiRecommendedSwitch_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(AiRecommendedSwitch); + } + if (aiRecommendedLevel_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(AiRecommendedLevel); + } + if (blocktop_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Blocktop); + } + if (blockscroll_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Blockscroll); + } + if (blockbottom_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Blockbottom); + } + if (blockcolorful_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Blockcolorful); + } + if (blockrepeat_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Blockrepeat); + } + if (blockspecial_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Blockspecial); + } + if (opacity_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Opacity); + } + if (scalingfactor_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Scalingfactor); + } + if (domain_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Domain); + } + if (speed_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(Speed); + } + if (enableblocklist_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(Enableblocklist); + } + if (inlinePlayerDanmakuSwitch_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(InlinePlayerDanmakuSwitch); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DmPlayerConfigReq other) { + if (other == null) { + return; + } + if (other.Ts != 0L) { + Ts = other.Ts; + } + if (other.switch_ != null) { + if (switch_ == null) { + Switch = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch(); + } + Switch.MergeFrom(other.Switch); + } + if (other.switchSave_ != null) { + if (switchSave_ == null) { + SwitchSave = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave(); + } + SwitchSave.MergeFrom(other.SwitchSave); + } + if (other.useDefaultConfig_ != null) { + if (useDefaultConfig_ == null) { + UseDefaultConfig = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig(); + } + UseDefaultConfig.MergeFrom(other.UseDefaultConfig); + } + if (other.aiRecommendedSwitch_ != null) { + if (aiRecommendedSwitch_ == null) { + AiRecommendedSwitch = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch(); + } + AiRecommendedSwitch.MergeFrom(other.AiRecommendedSwitch); + } + if (other.aiRecommendedLevel_ != null) { + if (aiRecommendedLevel_ == null) { + AiRecommendedLevel = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel(); + } + AiRecommendedLevel.MergeFrom(other.AiRecommendedLevel); + } + if (other.blocktop_ != null) { + if (blocktop_ == null) { + Blocktop = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop(); + } + Blocktop.MergeFrom(other.Blocktop); + } + if (other.blockscroll_ != null) { + if (blockscroll_ == null) { + Blockscroll = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll(); + } + Blockscroll.MergeFrom(other.Blockscroll); + } + if (other.blockbottom_ != null) { + if (blockbottom_ == null) { + Blockbottom = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom(); + } + Blockbottom.MergeFrom(other.Blockbottom); + } + if (other.blockcolorful_ != null) { + if (blockcolorful_ == null) { + Blockcolorful = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful(); + } + Blockcolorful.MergeFrom(other.Blockcolorful); + } + if (other.blockrepeat_ != null) { + if (blockrepeat_ == null) { + Blockrepeat = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat(); + } + Blockrepeat.MergeFrom(other.Blockrepeat); + } + if (other.blockspecial_ != null) { + if (blockspecial_ == null) { + Blockspecial = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial(); + } + Blockspecial.MergeFrom(other.Blockspecial); + } + if (other.opacity_ != null) { + if (opacity_ == null) { + Opacity = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity(); + } + Opacity.MergeFrom(other.Opacity); + } + if (other.scalingfactor_ != null) { + if (scalingfactor_ == null) { + Scalingfactor = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor(); + } + Scalingfactor.MergeFrom(other.Scalingfactor); + } + if (other.domain_ != null) { + if (domain_ == null) { + Domain = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain(); + } + Domain.MergeFrom(other.Domain); + } + if (other.speed_ != null) { + if (speed_ == null) { + Speed = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed(); + } + Speed.MergeFrom(other.Speed); + } + if (other.enableblocklist_ != null) { + if (enableblocklist_ == null) { + Enableblocklist = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist(); + } + Enableblocklist.MergeFrom(other.Enableblocklist); + } + if (other.inlinePlayerDanmakuSwitch_ != null) { + if (inlinePlayerDanmakuSwitch_ == null) { + InlinePlayerDanmakuSwitch = new global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch(); + } + InlinePlayerDanmakuSwitch.MergeFrom(other.InlinePlayerDanmakuSwitch); + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Ts = input.ReadInt64(); + break; + } + case 18: { + if (switch_ == null) { + Switch = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch(); + } + input.ReadMessage(Switch); + break; + } + case 26: { + if (switchSave_ == null) { + SwitchSave = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave(); + } + input.ReadMessage(SwitchSave); + break; + } + case 34: { + if (useDefaultConfig_ == null) { + UseDefaultConfig = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig(); + } + input.ReadMessage(UseDefaultConfig); + break; + } + case 42: { + if (aiRecommendedSwitch_ == null) { + AiRecommendedSwitch = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch(); + } + input.ReadMessage(AiRecommendedSwitch); + break; + } + case 50: { + if (aiRecommendedLevel_ == null) { + AiRecommendedLevel = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel(); + } + input.ReadMessage(AiRecommendedLevel); + break; + } + case 58: { + if (blocktop_ == null) { + Blocktop = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop(); + } + input.ReadMessage(Blocktop); + break; + } + case 66: { + if (blockscroll_ == null) { + Blockscroll = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll(); + } + input.ReadMessage(Blockscroll); + break; + } + case 74: { + if (blockbottom_ == null) { + Blockbottom = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom(); + } + input.ReadMessage(Blockbottom); + break; + } + case 82: { + if (blockcolorful_ == null) { + Blockcolorful = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful(); + } + input.ReadMessage(Blockcolorful); + break; + } + case 90: { + if (blockrepeat_ == null) { + Blockrepeat = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat(); + } + input.ReadMessage(Blockrepeat); + break; + } + case 98: { + if (blockspecial_ == null) { + Blockspecial = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial(); + } + input.ReadMessage(Blockspecial); + break; + } + case 106: { + if (opacity_ == null) { + Opacity = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity(); + } + input.ReadMessage(Opacity); + break; + } + case 114: { + if (scalingfactor_ == null) { + Scalingfactor = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor(); + } + input.ReadMessage(Scalingfactor); + break; + } + case 122: { + if (domain_ == null) { + Domain = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain(); + } + input.ReadMessage(Domain); + break; + } + case 130: { + if (speed_ == null) { + Speed = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed(); + } + input.ReadMessage(Speed); + break; + } + case 138: { + if (enableblocklist_ == null) { + Enableblocklist = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist(); + } + input.ReadMessage(Enableblocklist); + break; + } + case 146: { + if (inlinePlayerDanmakuSwitch_ == null) { + InlinePlayerDanmakuSwitch = new global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch(); + } + input.ReadMessage(InlinePlayerDanmakuSwitch); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Ts = input.ReadInt64(); + break; + } + case 18: { + if (switch_ == null) { + Switch = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitch(); + } + input.ReadMessage(Switch); + break; + } + case 26: { + if (switchSave_ == null) { + SwitchSave = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSwitchSave(); + } + input.ReadMessage(SwitchSave); + break; + } + case 34: { + if (useDefaultConfig_ == null) { + UseDefaultConfig = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuUseDefaultConfig(); + } + input.ReadMessage(UseDefaultConfig); + break; + } + case 42: { + if (aiRecommendedSwitch_ == null) { + AiRecommendedSwitch = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedSwitch(); + } + input.ReadMessage(AiRecommendedSwitch); + break; + } + case 50: { + if (aiRecommendedLevel_ == null) { + AiRecommendedLevel = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuAiRecommendedLevel(); + } + input.ReadMessage(AiRecommendedLevel); + break; + } + case 58: { + if (blocktop_ == null) { + Blocktop = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlocktop(); + } + input.ReadMessage(Blocktop); + break; + } + case 66: { + if (blockscroll_ == null) { + Blockscroll = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockscroll(); + } + input.ReadMessage(Blockscroll); + break; + } + case 74: { + if (blockbottom_ == null) { + Blockbottom = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockbottom(); + } + input.ReadMessage(Blockbottom); + break; + } + case 82: { + if (blockcolorful_ == null) { + Blockcolorful = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockcolorful(); + } + input.ReadMessage(Blockcolorful); + break; + } + case 90: { + if (blockrepeat_ == null) { + Blockrepeat = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockrepeat(); + } + input.ReadMessage(Blockrepeat); + break; + } + case 98: { + if (blockspecial_ == null) { + Blockspecial = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuBlockspecial(); + } + input.ReadMessage(Blockspecial); + break; + } + case 106: { + if (opacity_ == null) { + Opacity = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuOpacity(); + } + input.ReadMessage(Opacity); + break; + } + case 114: { + if (scalingfactor_ == null) { + Scalingfactor = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuScalingfactor(); + } + input.ReadMessage(Scalingfactor); + break; + } + case 122: { + if (domain_ == null) { + Domain = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuDomain(); + } + input.ReadMessage(Domain); + break; + } + case 130: { + if (speed_ == null) { + Speed = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuSpeed(); + } + input.ReadMessage(Speed); + break; + } + case 138: { + if (enableblocklist_ == null) { + Enableblocklist = new global::Bilibili.Community.Service.Dm.V1.PlayerDanmakuEnableblocklist(); + } + input.ReadMessage(Enableblocklist); + break; + } + case 146: { + if (inlinePlayerDanmakuSwitch_ == null) { + InlinePlayerDanmakuSwitch = new global::Bilibili.Community.Service.Dm.V1.InlinePlayerDanmakuSwitch(); + } + input.ReadMessage(InlinePlayerDanmakuSwitch); + break; + } + } + } + } + #endif + + } + + /// + /// 修改弹幕配置-响应 + /// + public sealed partial class Response : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Response()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[18]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Response() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Response(Response other) : this() { + code_ = other.code_; + message_ = other.message_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Response Clone() { + return new Response(this); + } + + /// Field number for the "code" field. + public const int CodeFieldNumber = 1; + private int code_; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Code { + get { return code_; } + set { + code_ = value; + } + } + + /// Field number for the "message" field. + public const int MessageFieldNumber = 2; + private string message_ = ""; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Message { + get { return message_; } + set { + message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as Response); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(Response other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Code != other.Code) return false; + if (Message != other.Message) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Code != 0) hash ^= Code.GetHashCode(); + if (Message.Length != 0) hash ^= Message.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Code != 0) { + output.WriteRawTag(8); + output.WriteInt32(Code); + } + if (Message.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Message); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Code != 0) { + output.WriteRawTag(8); + output.WriteInt32(Code); + } + if (Message.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Message); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Code != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Code); + } + if (Message.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(Response other) { + if (other == null) { + return; + } + if (other.Code != 0) { + Code = other.Code; + } + if (other.Message.Length != 0) { + Message = other.Message; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Code = input.ReadInt32(); + break; + } + case 18: { + Message = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Code = input.ReadInt32(); + break; + } + case 18: { + Message = input.ReadString(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕ai云屏蔽条目 + /// + public sealed partial class DanmakuFlag : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmakuFlag()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[19]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuFlag() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuFlag(DanmakuFlag other) : this() { + dmid_ = other.dmid_; + flag_ = other.flag_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuFlag Clone() { + return new DanmakuFlag(this); + } + + /// Field number for the "dmid" field. + public const int DmidFieldNumber = 1; + private long dmid_; + /// + /// 弹幕dmid + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public long Dmid { + get { return dmid_; } + set { + dmid_ = value; + } + } + + /// Field number for the "flag" field. + public const int FlagFieldNumber = 2; + private uint flag_; + /// + /// 评分 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public uint Flag { + get { return flag_; } + set { + flag_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmakuFlag); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmakuFlag other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Dmid != other.Dmid) return false; + if (Flag != other.Flag) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Dmid != 0L) hash ^= Dmid.GetHashCode(); + if (Flag != 0) hash ^= Flag.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Dmid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Dmid); + } + if (Flag != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Flag); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Dmid != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Dmid); + } + if (Flag != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Flag); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Dmid != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Dmid); + } + if (Flag != 0) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Flag); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmakuFlag other) { + if (other == null) { + return; + } + if (other.Dmid != 0L) { + Dmid = other.Dmid; + } + if (other.Flag != 0) { + Flag = other.Flag; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Dmid = input.ReadInt64(); + break; + } + case 16: { + Flag = input.ReadUInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Dmid = input.ReadInt64(); + break; + } + case 16: { + Flag = input.ReadUInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 云屏蔽配置信息 + /// + public sealed partial class DanmakuFlagConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmakuFlagConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[20]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuFlagConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuFlagConfig(DanmakuFlagConfig other) : this() { + recFlag_ = other.recFlag_; + recText_ = other.recText_; + recSwitch_ = other.recSwitch_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuFlagConfig Clone() { + return new DanmakuFlagConfig(this); + } + + /// Field number for the "rec_flag" field. + public const int RecFlagFieldNumber = 1; + private int recFlag_; + /// + /// 云屏蔽等级 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int RecFlag { + get { return recFlag_; } + set { + recFlag_ = value; + } + } + + /// Field number for the "rec_text" field. + public const int RecTextFieldNumber = 2; + private string recText_ = ""; + /// + /// 云屏蔽文案 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string RecText { + get { return recText_; } + set { + recText_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "rec_switch" field. + public const int RecSwitchFieldNumber = 3; + private int recSwitch_; + /// + /// 云屏蔽开关 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int RecSwitch { + get { return recSwitch_; } + set { + recSwitch_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmakuFlagConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmakuFlagConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (RecFlag != other.RecFlag) return false; + if (RecText != other.RecText) return false; + if (RecSwitch != other.RecSwitch) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (RecFlag != 0) hash ^= RecFlag.GetHashCode(); + if (RecText.Length != 0) hash ^= RecText.GetHashCode(); + if (RecSwitch != 0) hash ^= RecSwitch.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (RecFlag != 0) { + output.WriteRawTag(8); + output.WriteInt32(RecFlag); + } + if (RecText.Length != 0) { + output.WriteRawTag(18); + output.WriteString(RecText); + } + if (RecSwitch != 0) { + output.WriteRawTag(24); + output.WriteInt32(RecSwitch); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (RecFlag != 0) { + output.WriteRawTag(8); + output.WriteInt32(RecFlag); + } + if (RecText.Length != 0) { + output.WriteRawTag(18); + output.WriteString(RecText); + } + if (RecSwitch != 0) { + output.WriteRawTag(24); + output.WriteInt32(RecSwitch); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (RecFlag != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(RecFlag); + } + if (RecText.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(RecText); + } + if (RecSwitch != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(RecSwitch); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmakuFlagConfig other) { + if (other == null) { + return; + } + if (other.RecFlag != 0) { + RecFlag = other.RecFlag; + } + if (other.RecText.Length != 0) { + RecText = other.RecText; + } + if (other.RecSwitch != 0) { + RecSwitch = other.RecSwitch; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + RecFlag = input.ReadInt32(); + break; + } + case 18: { + RecText = input.ReadString(); + break; + } + case 24: { + RecSwitch = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + RecFlag = input.ReadInt32(); + break; + } + case 18: { + RecText = input.ReadString(); + break; + } + case 24: { + RecSwitch = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕ai云屏蔽列表 + /// + public sealed partial class DanmakuAIFlag : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmakuAIFlag()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[21]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuAIFlag() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuAIFlag(DanmakuAIFlag other) : this() { + dmFlags_ = other.dmFlags_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmakuAIFlag Clone() { + return new DanmakuAIFlag(this); + } + + /// Field number for the "dm_flags" field. + public const int DmFlagsFieldNumber = 1; + private static readonly pb::FieldCodec _repeated_dmFlags_codec + = pb::FieldCodec.ForMessage(10, global::Bilibili.Community.Service.Dm.V1.DanmakuFlag.Parser); + private readonly pbc::RepeatedField dmFlags_ = new pbc::RepeatedField(); + /// + /// 弹幕ai云屏蔽条目 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField DmFlags { + get { return dmFlags_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmakuAIFlag); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmakuAIFlag other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if(!dmFlags_.Equals(other.dmFlags_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + hash ^= dmFlags_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + dmFlags_.WriteTo(output, _repeated_dmFlags_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + dmFlags_.WriteTo(ref output, _repeated_dmFlags_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + size += dmFlags_.CalculateSize(_repeated_dmFlags_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmakuAIFlag other) { + if (other == null) { + return; + } + dmFlags_.Add(other.dmFlags_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + dmFlags_.AddEntriesFrom(input, _repeated_dmFlags_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + dmFlags_.AddEntriesFrom(ref input, _repeated_dmFlags_codec); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕配置信息 + /// + public sealed partial class DanmuPlayerViewConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmuPlayerViewConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[22]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerViewConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerViewConfig(DanmuPlayerViewConfig other) : this() { + danmukuDefaultPlayerConfig_ = other.danmukuDefaultPlayerConfig_ != null ? other.danmukuDefaultPlayerConfig_.Clone() : null; + danmukuPlayerConfig_ = other.danmukuPlayerConfig_ != null ? other.danmukuPlayerConfig_.Clone() : null; + danmukuPlayerDynamicConfig_ = other.danmukuPlayerDynamicConfig_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerViewConfig Clone() { + return new DanmuPlayerViewConfig(this); + } + + /// Field number for the "danmuku_default_player_config" field. + public const int DanmukuDefaultPlayerConfigFieldNumber = 1; + private global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig danmukuDefaultPlayerConfig_; + /// + /// 弹幕默认配置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig DanmukuDefaultPlayerConfig { + get { return danmukuDefaultPlayerConfig_; } + set { + danmukuDefaultPlayerConfig_ = value; + } + } + + /// Field number for the "danmuku_player_config" field. + public const int DanmukuPlayerConfigFieldNumber = 2; + private global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig danmukuPlayerConfig_; + /// + /// 弹幕用户配置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig DanmukuPlayerConfig { + get { return danmukuPlayerConfig_; } + set { + danmukuPlayerConfig_ = value; + } + } + + /// Field number for the "danmuku_player_dynamic_config" field. + public const int DanmukuPlayerDynamicConfigFieldNumber = 3; + private static readonly pb::FieldCodec _repeated_danmukuPlayerDynamicConfig_codec + = pb::FieldCodec.ForMessage(26, global::Bilibili.Community.Service.Dm.V1.DanmuPlayerDynamicConfig.Parser); + private readonly pbc::RepeatedField danmukuPlayerDynamicConfig_ = new pbc::RepeatedField(); + /// + /// 弹幕显示区域自动配置列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField DanmukuPlayerDynamicConfig { + get { return danmukuPlayerDynamicConfig_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmuPlayerViewConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmuPlayerViewConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!object.Equals(DanmukuDefaultPlayerConfig, other.DanmukuDefaultPlayerConfig)) return false; + if (!object.Equals(DanmukuPlayerConfig, other.DanmukuPlayerConfig)) return false; + if(!danmukuPlayerDynamicConfig_.Equals(other.danmukuPlayerDynamicConfig_)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (danmukuDefaultPlayerConfig_ != null) hash ^= DanmukuDefaultPlayerConfig.GetHashCode(); + if (danmukuPlayerConfig_ != null) hash ^= DanmukuPlayerConfig.GetHashCode(); + hash ^= danmukuPlayerDynamicConfig_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (danmukuDefaultPlayerConfig_ != null) { + output.WriteRawTag(10); + output.WriteMessage(DanmukuDefaultPlayerConfig); + } + if (danmukuPlayerConfig_ != null) { + output.WriteRawTag(18); + output.WriteMessage(DanmukuPlayerConfig); + } + danmukuPlayerDynamicConfig_.WriteTo(output, _repeated_danmukuPlayerDynamicConfig_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (danmukuDefaultPlayerConfig_ != null) { + output.WriteRawTag(10); + output.WriteMessage(DanmukuDefaultPlayerConfig); + } + if (danmukuPlayerConfig_ != null) { + output.WriteRawTag(18); + output.WriteMessage(DanmukuPlayerConfig); + } + danmukuPlayerDynamicConfig_.WriteTo(ref output, _repeated_danmukuPlayerDynamicConfig_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (danmukuDefaultPlayerConfig_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(DanmukuDefaultPlayerConfig); + } + if (danmukuPlayerConfig_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(DanmukuPlayerConfig); + } + size += danmukuPlayerDynamicConfig_.CalculateSize(_repeated_danmukuPlayerDynamicConfig_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmuPlayerViewConfig other) { + if (other == null) { + return; + } + if (other.danmukuDefaultPlayerConfig_ != null) { + if (danmukuDefaultPlayerConfig_ == null) { + DanmukuDefaultPlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig(); + } + DanmukuDefaultPlayerConfig.MergeFrom(other.DanmukuDefaultPlayerConfig); + } + if (other.danmukuPlayerConfig_ != null) { + if (danmukuPlayerConfig_ == null) { + DanmukuPlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig(); + } + DanmukuPlayerConfig.MergeFrom(other.DanmukuPlayerConfig); + } + danmukuPlayerDynamicConfig_.Add(other.danmukuPlayerDynamicConfig_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + if (danmukuDefaultPlayerConfig_ == null) { + DanmukuDefaultPlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig(); + } + input.ReadMessage(DanmukuDefaultPlayerConfig); + break; + } + case 18: { + if (danmukuPlayerConfig_ == null) { + DanmukuPlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig(); + } + input.ReadMessage(DanmukuPlayerConfig); + break; + } + case 26: { + danmukuPlayerDynamicConfig_.AddEntriesFrom(input, _repeated_danmukuPlayerDynamicConfig_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (danmukuDefaultPlayerConfig_ == null) { + DanmukuDefaultPlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuDefaultPlayerConfig(); + } + input.ReadMessage(DanmukuDefaultPlayerConfig); + break; + } + case 18: { + if (danmukuPlayerConfig_ == null) { + DanmukuPlayerConfig = new global::Bilibili.Community.Service.Dm.V1.DanmuPlayerConfig(); + } + input.ReadMessage(DanmukuPlayerConfig); + break; + } + case 26: { + danmukuPlayerDynamicConfig_.AddEntriesFrom(ref input, _repeated_danmukuPlayerDynamicConfig_codec); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕默认配置 + /// + public sealed partial class DanmuDefaultPlayerConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmuDefaultPlayerConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[23]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuDefaultPlayerConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuDefaultPlayerConfig(DanmuDefaultPlayerConfig other) : this() { + playerDanmakuUseDefaultConfig_ = other.playerDanmakuUseDefaultConfig_; + playerDanmakuAiRecommendedSwitch_ = other.playerDanmakuAiRecommendedSwitch_; + playerDanmakuAiRecommendedLevel_ = other.playerDanmakuAiRecommendedLevel_; + playerDanmakuBlocktop_ = other.playerDanmakuBlocktop_; + playerDanmakuBlockscroll_ = other.playerDanmakuBlockscroll_; + playerDanmakuBlockbottom_ = other.playerDanmakuBlockbottom_; + playerDanmakuBlockcolorful_ = other.playerDanmakuBlockcolorful_; + playerDanmakuBlockrepeat_ = other.playerDanmakuBlockrepeat_; + playerDanmakuBlockspecial_ = other.playerDanmakuBlockspecial_; + playerDanmakuOpacity_ = other.playerDanmakuOpacity_; + playerDanmakuScalingfactor_ = other.playerDanmakuScalingfactor_; + playerDanmakuDomain_ = other.playerDanmakuDomain_; + playerDanmakuSpeed_ = other.playerDanmakuSpeed_; + inlinePlayerDanmakuSwitch_ = other.inlinePlayerDanmakuSwitch_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuDefaultPlayerConfig Clone() { + return new DanmuDefaultPlayerConfig(this); + } + + /// Field number for the "player_danmaku_use_default_config" field. + public const int PlayerDanmakuUseDefaultConfigFieldNumber = 1; + private bool playerDanmakuUseDefaultConfig_; + /// + /// 是否使用推荐弹幕设置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuUseDefaultConfig { + get { return playerDanmakuUseDefaultConfig_; } + set { + playerDanmakuUseDefaultConfig_ = value; + } + } + + /// Field number for the "player_danmaku_ai_recommended_switch" field. + public const int PlayerDanmakuAiRecommendedSwitchFieldNumber = 4; + private bool playerDanmakuAiRecommendedSwitch_; + /// + /// 是否开启智能云屏蔽 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuAiRecommendedSwitch { + get { return playerDanmakuAiRecommendedSwitch_; } + set { + playerDanmakuAiRecommendedSwitch_ = value; + } + } + + /// Field number for the "player_danmaku_ai_recommended_level" field. + public const int PlayerDanmakuAiRecommendedLevelFieldNumber = 5; + private int playerDanmakuAiRecommendedLevel_; + /// + /// 智能云屏蔽等级 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int PlayerDanmakuAiRecommendedLevel { + get { return playerDanmakuAiRecommendedLevel_; } + set { + playerDanmakuAiRecommendedLevel_ = value; + } + } + + /// Field number for the "player_danmaku_blocktop" field. + public const int PlayerDanmakuBlocktopFieldNumber = 6; + private bool playerDanmakuBlocktop_; + /// + /// 是否屏蔽顶端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlocktop { + get { return playerDanmakuBlocktop_; } + set { + playerDanmakuBlocktop_ = value; + } + } + + /// Field number for the "player_danmaku_blockscroll" field. + public const int PlayerDanmakuBlockscrollFieldNumber = 7; + private bool playerDanmakuBlockscroll_; + /// + /// 是否屏蔽滚动弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockscroll { + get { return playerDanmakuBlockscroll_; } + set { + playerDanmakuBlockscroll_ = value; + } + } + + /// Field number for the "player_danmaku_blockbottom" field. + public const int PlayerDanmakuBlockbottomFieldNumber = 8; + private bool playerDanmakuBlockbottom_; + /// + /// 是否屏蔽底端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockbottom { + get { return playerDanmakuBlockbottom_; } + set { + playerDanmakuBlockbottom_ = value; + } + } + + /// Field number for the "player_danmaku_blockcolorful" field. + public const int PlayerDanmakuBlockcolorfulFieldNumber = 9; + private bool playerDanmakuBlockcolorful_; + /// + /// 是否屏蔽彩色弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockcolorful { + get { return playerDanmakuBlockcolorful_; } + set { + playerDanmakuBlockcolorful_ = value; + } + } + + /// Field number for the "player_danmaku_blockrepeat" field. + public const int PlayerDanmakuBlockrepeatFieldNumber = 10; + private bool playerDanmakuBlockrepeat_; + /// + /// 是否屏蔽重复弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockrepeat { + get { return playerDanmakuBlockrepeat_; } + set { + playerDanmakuBlockrepeat_ = value; + } + } + + /// Field number for the "player_danmaku_blockspecial" field. + public const int PlayerDanmakuBlockspecialFieldNumber = 11; + private bool playerDanmakuBlockspecial_; + /// + /// 是否屏蔽高级弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockspecial { + get { return playerDanmakuBlockspecial_; } + set { + playerDanmakuBlockspecial_ = value; + } + } + + /// Field number for the "player_danmaku_opacity" field. + public const int PlayerDanmakuOpacityFieldNumber = 12; + private float playerDanmakuOpacity_; + /// + /// 弹幕不透明度 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuOpacity { + get { return playerDanmakuOpacity_; } + set { + playerDanmakuOpacity_ = value; + } + } + + /// Field number for the "player_danmaku_scalingfactor" field. + public const int PlayerDanmakuScalingfactorFieldNumber = 13; + private float playerDanmakuScalingfactor_; + /// + /// 弹幕缩放比例 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuScalingfactor { + get { return playerDanmakuScalingfactor_; } + set { + playerDanmakuScalingfactor_ = value; + } + } + + /// Field number for the "player_danmaku_domain" field. + public const int PlayerDanmakuDomainFieldNumber = 14; + private float playerDanmakuDomain_; + /// + /// 弹幕显示区域 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuDomain { + get { return playerDanmakuDomain_; } + set { + playerDanmakuDomain_ = value; + } + } + + /// Field number for the "player_danmaku_speed" field. + public const int PlayerDanmakuSpeedFieldNumber = 15; + private int playerDanmakuSpeed_; + /// + /// 弹幕速度 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int PlayerDanmakuSpeed { + get { return playerDanmakuSpeed_; } + set { + playerDanmakuSpeed_ = value; + } + } + + /// Field number for the "inline_player_danmaku_switch" field. + public const int InlinePlayerDanmakuSwitchFieldNumber = 16; + private bool inlinePlayerDanmakuSwitch_; + /// + /// 是否开启弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool InlinePlayerDanmakuSwitch { + get { return inlinePlayerDanmakuSwitch_; } + set { + inlinePlayerDanmakuSwitch_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmuDefaultPlayerConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmuDefaultPlayerConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (PlayerDanmakuUseDefaultConfig != other.PlayerDanmakuUseDefaultConfig) return false; + if (PlayerDanmakuAiRecommendedSwitch != other.PlayerDanmakuAiRecommendedSwitch) return false; + if (PlayerDanmakuAiRecommendedLevel != other.PlayerDanmakuAiRecommendedLevel) return false; + if (PlayerDanmakuBlocktop != other.PlayerDanmakuBlocktop) return false; + if (PlayerDanmakuBlockscroll != other.PlayerDanmakuBlockscroll) return false; + if (PlayerDanmakuBlockbottom != other.PlayerDanmakuBlockbottom) return false; + if (PlayerDanmakuBlockcolorful != other.PlayerDanmakuBlockcolorful) return false; + if (PlayerDanmakuBlockrepeat != other.PlayerDanmakuBlockrepeat) return false; + if (PlayerDanmakuBlockspecial != other.PlayerDanmakuBlockspecial) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuOpacity, other.PlayerDanmakuOpacity)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuScalingfactor, other.PlayerDanmakuScalingfactor)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuDomain, other.PlayerDanmakuDomain)) return false; + if (PlayerDanmakuSpeed != other.PlayerDanmakuSpeed) return false; + if (InlinePlayerDanmakuSwitch != other.InlinePlayerDanmakuSwitch) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (PlayerDanmakuUseDefaultConfig != false) hash ^= PlayerDanmakuUseDefaultConfig.GetHashCode(); + if (PlayerDanmakuAiRecommendedSwitch != false) hash ^= PlayerDanmakuAiRecommendedSwitch.GetHashCode(); + if (PlayerDanmakuAiRecommendedLevel != 0) hash ^= PlayerDanmakuAiRecommendedLevel.GetHashCode(); + if (PlayerDanmakuBlocktop != false) hash ^= PlayerDanmakuBlocktop.GetHashCode(); + if (PlayerDanmakuBlockscroll != false) hash ^= PlayerDanmakuBlockscroll.GetHashCode(); + if (PlayerDanmakuBlockbottom != false) hash ^= PlayerDanmakuBlockbottom.GetHashCode(); + if (PlayerDanmakuBlockcolorful != false) hash ^= PlayerDanmakuBlockcolorful.GetHashCode(); + if (PlayerDanmakuBlockrepeat != false) hash ^= PlayerDanmakuBlockrepeat.GetHashCode(); + if (PlayerDanmakuBlockspecial != false) hash ^= PlayerDanmakuBlockspecial.GetHashCode(); + if (PlayerDanmakuOpacity != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuOpacity); + if (PlayerDanmakuScalingfactor != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuScalingfactor); + if (PlayerDanmakuDomain != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuDomain); + if (PlayerDanmakuSpeed != 0) hash ^= PlayerDanmakuSpeed.GetHashCode(); + if (InlinePlayerDanmakuSwitch != false) hash ^= InlinePlayerDanmakuSwitch.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (PlayerDanmakuUseDefaultConfig != false) { + output.WriteRawTag(8); + output.WriteBool(PlayerDanmakuUseDefaultConfig); + } + if (PlayerDanmakuAiRecommendedSwitch != false) { + output.WriteRawTag(32); + output.WriteBool(PlayerDanmakuAiRecommendedSwitch); + } + if (PlayerDanmakuAiRecommendedLevel != 0) { + output.WriteRawTag(40); + output.WriteInt32(PlayerDanmakuAiRecommendedLevel); + } + if (PlayerDanmakuBlocktop != false) { + output.WriteRawTag(48); + output.WriteBool(PlayerDanmakuBlocktop); + } + if (PlayerDanmakuBlockscroll != false) { + output.WriteRawTag(56); + output.WriteBool(PlayerDanmakuBlockscroll); + } + if (PlayerDanmakuBlockbottom != false) { + output.WriteRawTag(64); + output.WriteBool(PlayerDanmakuBlockbottom); + } + if (PlayerDanmakuBlockcolorful != false) { + output.WriteRawTag(72); + output.WriteBool(PlayerDanmakuBlockcolorful); + } + if (PlayerDanmakuBlockrepeat != false) { + output.WriteRawTag(80); + output.WriteBool(PlayerDanmakuBlockrepeat); + } + if (PlayerDanmakuBlockspecial != false) { + output.WriteRawTag(88); + output.WriteBool(PlayerDanmakuBlockspecial); + } + if (PlayerDanmakuOpacity != 0F) { + output.WriteRawTag(101); + output.WriteFloat(PlayerDanmakuOpacity); + } + if (PlayerDanmakuScalingfactor != 0F) { + output.WriteRawTag(109); + output.WriteFloat(PlayerDanmakuScalingfactor); + } + if (PlayerDanmakuDomain != 0F) { + output.WriteRawTag(117); + output.WriteFloat(PlayerDanmakuDomain); + } + if (PlayerDanmakuSpeed != 0) { + output.WriteRawTag(120); + output.WriteInt32(PlayerDanmakuSpeed); + } + if (InlinePlayerDanmakuSwitch != false) { + output.WriteRawTag(128, 1); + output.WriteBool(InlinePlayerDanmakuSwitch); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (PlayerDanmakuUseDefaultConfig != false) { + output.WriteRawTag(8); + output.WriteBool(PlayerDanmakuUseDefaultConfig); + } + if (PlayerDanmakuAiRecommendedSwitch != false) { + output.WriteRawTag(32); + output.WriteBool(PlayerDanmakuAiRecommendedSwitch); + } + if (PlayerDanmakuAiRecommendedLevel != 0) { + output.WriteRawTag(40); + output.WriteInt32(PlayerDanmakuAiRecommendedLevel); + } + if (PlayerDanmakuBlocktop != false) { + output.WriteRawTag(48); + output.WriteBool(PlayerDanmakuBlocktop); + } + if (PlayerDanmakuBlockscroll != false) { + output.WriteRawTag(56); + output.WriteBool(PlayerDanmakuBlockscroll); + } + if (PlayerDanmakuBlockbottom != false) { + output.WriteRawTag(64); + output.WriteBool(PlayerDanmakuBlockbottom); + } + if (PlayerDanmakuBlockcolorful != false) { + output.WriteRawTag(72); + output.WriteBool(PlayerDanmakuBlockcolorful); + } + if (PlayerDanmakuBlockrepeat != false) { + output.WriteRawTag(80); + output.WriteBool(PlayerDanmakuBlockrepeat); + } + if (PlayerDanmakuBlockspecial != false) { + output.WriteRawTag(88); + output.WriteBool(PlayerDanmakuBlockspecial); + } + if (PlayerDanmakuOpacity != 0F) { + output.WriteRawTag(101); + output.WriteFloat(PlayerDanmakuOpacity); + } + if (PlayerDanmakuScalingfactor != 0F) { + output.WriteRawTag(109); + output.WriteFloat(PlayerDanmakuScalingfactor); + } + if (PlayerDanmakuDomain != 0F) { + output.WriteRawTag(117); + output.WriteFloat(PlayerDanmakuDomain); + } + if (PlayerDanmakuSpeed != 0) { + output.WriteRawTag(120); + output.WriteInt32(PlayerDanmakuSpeed); + } + if (InlinePlayerDanmakuSwitch != false) { + output.WriteRawTag(128, 1); + output.WriteBool(InlinePlayerDanmakuSwitch); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (PlayerDanmakuUseDefaultConfig != false) { + size += 1 + 1; + } + if (PlayerDanmakuAiRecommendedSwitch != false) { + size += 1 + 1; + } + if (PlayerDanmakuAiRecommendedLevel != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(PlayerDanmakuAiRecommendedLevel); + } + if (PlayerDanmakuBlocktop != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockscroll != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockbottom != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockcolorful != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockrepeat != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockspecial != false) { + size += 1 + 1; + } + if (PlayerDanmakuOpacity != 0F) { + size += 1 + 4; + } + if (PlayerDanmakuScalingfactor != 0F) { + size += 1 + 4; + } + if (PlayerDanmakuDomain != 0F) { + size += 1 + 4; + } + if (PlayerDanmakuSpeed != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(PlayerDanmakuSpeed); + } + if (InlinePlayerDanmakuSwitch != false) { + size += 2 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmuDefaultPlayerConfig other) { + if (other == null) { + return; + } + if (other.PlayerDanmakuUseDefaultConfig != false) { + PlayerDanmakuUseDefaultConfig = other.PlayerDanmakuUseDefaultConfig; + } + if (other.PlayerDanmakuAiRecommendedSwitch != false) { + PlayerDanmakuAiRecommendedSwitch = other.PlayerDanmakuAiRecommendedSwitch; + } + if (other.PlayerDanmakuAiRecommendedLevel != 0) { + PlayerDanmakuAiRecommendedLevel = other.PlayerDanmakuAiRecommendedLevel; + } + if (other.PlayerDanmakuBlocktop != false) { + PlayerDanmakuBlocktop = other.PlayerDanmakuBlocktop; + } + if (other.PlayerDanmakuBlockscroll != false) { + PlayerDanmakuBlockscroll = other.PlayerDanmakuBlockscroll; + } + if (other.PlayerDanmakuBlockbottom != false) { + PlayerDanmakuBlockbottom = other.PlayerDanmakuBlockbottom; + } + if (other.PlayerDanmakuBlockcolorful != false) { + PlayerDanmakuBlockcolorful = other.PlayerDanmakuBlockcolorful; + } + if (other.PlayerDanmakuBlockrepeat != false) { + PlayerDanmakuBlockrepeat = other.PlayerDanmakuBlockrepeat; + } + if (other.PlayerDanmakuBlockspecial != false) { + PlayerDanmakuBlockspecial = other.PlayerDanmakuBlockspecial; + } + if (other.PlayerDanmakuOpacity != 0F) { + PlayerDanmakuOpacity = other.PlayerDanmakuOpacity; + } + if (other.PlayerDanmakuScalingfactor != 0F) { + PlayerDanmakuScalingfactor = other.PlayerDanmakuScalingfactor; + } + if (other.PlayerDanmakuDomain != 0F) { + PlayerDanmakuDomain = other.PlayerDanmakuDomain; + } + if (other.PlayerDanmakuSpeed != 0) { + PlayerDanmakuSpeed = other.PlayerDanmakuSpeed; + } + if (other.InlinePlayerDanmakuSwitch != false) { + InlinePlayerDanmakuSwitch = other.InlinePlayerDanmakuSwitch; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + PlayerDanmakuUseDefaultConfig = input.ReadBool(); + break; + } + case 32: { + PlayerDanmakuAiRecommendedSwitch = input.ReadBool(); + break; + } + case 40: { + PlayerDanmakuAiRecommendedLevel = input.ReadInt32(); + break; + } + case 48: { + PlayerDanmakuBlocktop = input.ReadBool(); + break; + } + case 56: { + PlayerDanmakuBlockscroll = input.ReadBool(); + break; + } + case 64: { + PlayerDanmakuBlockbottom = input.ReadBool(); + break; + } + case 72: { + PlayerDanmakuBlockcolorful = input.ReadBool(); + break; + } + case 80: { + PlayerDanmakuBlockrepeat = input.ReadBool(); + break; + } + case 88: { + PlayerDanmakuBlockspecial = input.ReadBool(); + break; + } + case 101: { + PlayerDanmakuOpacity = input.ReadFloat(); + break; + } + case 109: { + PlayerDanmakuScalingfactor = input.ReadFloat(); + break; + } + case 117: { + PlayerDanmakuDomain = input.ReadFloat(); + break; + } + case 120: { + PlayerDanmakuSpeed = input.ReadInt32(); + break; + } + case 128: { + InlinePlayerDanmakuSwitch = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + PlayerDanmakuUseDefaultConfig = input.ReadBool(); + break; + } + case 32: { + PlayerDanmakuAiRecommendedSwitch = input.ReadBool(); + break; + } + case 40: { + PlayerDanmakuAiRecommendedLevel = input.ReadInt32(); + break; + } + case 48: { + PlayerDanmakuBlocktop = input.ReadBool(); + break; + } + case 56: { + PlayerDanmakuBlockscroll = input.ReadBool(); + break; + } + case 64: { + PlayerDanmakuBlockbottom = input.ReadBool(); + break; + } + case 72: { + PlayerDanmakuBlockcolorful = input.ReadBool(); + break; + } + case 80: { + PlayerDanmakuBlockrepeat = input.ReadBool(); + break; + } + case 88: { + PlayerDanmakuBlockspecial = input.ReadBool(); + break; + } + case 101: { + PlayerDanmakuOpacity = input.ReadFloat(); + break; + } + case 109: { + PlayerDanmakuScalingfactor = input.ReadFloat(); + break; + } + case 117: { + PlayerDanmakuDomain = input.ReadFloat(); + break; + } + case 120: { + PlayerDanmakuSpeed = input.ReadInt32(); + break; + } + case 128: { + InlinePlayerDanmakuSwitch = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕配置 + /// + public sealed partial class DanmuPlayerConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmuPlayerConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[24]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerConfig(DanmuPlayerConfig other) : this() { + playerDanmakuSwitch_ = other.playerDanmakuSwitch_; + playerDanmakuSwitchSave_ = other.playerDanmakuSwitchSave_; + playerDanmakuUseDefaultConfig_ = other.playerDanmakuUseDefaultConfig_; + playerDanmakuAiRecommendedSwitch_ = other.playerDanmakuAiRecommendedSwitch_; + playerDanmakuAiRecommendedLevel_ = other.playerDanmakuAiRecommendedLevel_; + playerDanmakuBlocktop_ = other.playerDanmakuBlocktop_; + playerDanmakuBlockscroll_ = other.playerDanmakuBlockscroll_; + playerDanmakuBlockbottom_ = other.playerDanmakuBlockbottom_; + playerDanmakuBlockcolorful_ = other.playerDanmakuBlockcolorful_; + playerDanmakuBlockrepeat_ = other.playerDanmakuBlockrepeat_; + playerDanmakuBlockspecial_ = other.playerDanmakuBlockspecial_; + playerDanmakuOpacity_ = other.playerDanmakuOpacity_; + playerDanmakuScalingfactor_ = other.playerDanmakuScalingfactor_; + playerDanmakuDomain_ = other.playerDanmakuDomain_; + playerDanmakuSpeed_ = other.playerDanmakuSpeed_; + playerDanmakuEnableblocklist_ = other.playerDanmakuEnableblocklist_; + inlinePlayerDanmakuSwitch_ = other.inlinePlayerDanmakuSwitch_; + inlinePlayerDanmakuConfig_ = other.inlinePlayerDanmakuConfig_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerConfig Clone() { + return new DanmuPlayerConfig(this); + } + + /// Field number for the "player_danmaku_switch" field. + public const int PlayerDanmakuSwitchFieldNumber = 1; + private bool playerDanmakuSwitch_; + /// + /// 是否开启弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuSwitch { + get { return playerDanmakuSwitch_; } + set { + playerDanmakuSwitch_ = value; + } + } + + /// Field number for the "player_danmaku_switch_save" field. + public const int PlayerDanmakuSwitchSaveFieldNumber = 2; + private bool playerDanmakuSwitchSave_; + /// + /// 是否记录弹幕开关设置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuSwitchSave { + get { return playerDanmakuSwitchSave_; } + set { + playerDanmakuSwitchSave_ = value; + } + } + + /// Field number for the "player_danmaku_use_default_config" field. + public const int PlayerDanmakuUseDefaultConfigFieldNumber = 3; + private bool playerDanmakuUseDefaultConfig_; + /// + /// 是否使用推荐弹幕设置 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuUseDefaultConfig { + get { return playerDanmakuUseDefaultConfig_; } + set { + playerDanmakuUseDefaultConfig_ = value; + } + } + + /// Field number for the "player_danmaku_ai_recommended_switch" field. + public const int PlayerDanmakuAiRecommendedSwitchFieldNumber = 4; + private bool playerDanmakuAiRecommendedSwitch_; + /// + /// 是否开启智能云屏蔽 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuAiRecommendedSwitch { + get { return playerDanmakuAiRecommendedSwitch_; } + set { + playerDanmakuAiRecommendedSwitch_ = value; + } + } + + /// Field number for the "player_danmaku_ai_recommended_level" field. + public const int PlayerDanmakuAiRecommendedLevelFieldNumber = 5; + private int playerDanmakuAiRecommendedLevel_; + /// + /// 智能云屏蔽等级 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int PlayerDanmakuAiRecommendedLevel { + get { return playerDanmakuAiRecommendedLevel_; } + set { + playerDanmakuAiRecommendedLevel_ = value; + } + } + + /// Field number for the "player_danmaku_blocktop" field. + public const int PlayerDanmakuBlocktopFieldNumber = 6; + private bool playerDanmakuBlocktop_; + /// + /// 是否屏蔽顶端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlocktop { + get { return playerDanmakuBlocktop_; } + set { + playerDanmakuBlocktop_ = value; + } + } + + /// Field number for the "player_danmaku_blockscroll" field. + public const int PlayerDanmakuBlockscrollFieldNumber = 7; + private bool playerDanmakuBlockscroll_; + /// + /// 是否屏蔽滚动弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockscroll { + get { return playerDanmakuBlockscroll_; } + set { + playerDanmakuBlockscroll_ = value; + } + } + + /// Field number for the "player_danmaku_blockbottom" field. + public const int PlayerDanmakuBlockbottomFieldNumber = 8; + private bool playerDanmakuBlockbottom_; + /// + /// 是否屏蔽底端弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockbottom { + get { return playerDanmakuBlockbottom_; } + set { + playerDanmakuBlockbottom_ = value; + } + } + + /// Field number for the "player_danmaku_blockcolorful" field. + public const int PlayerDanmakuBlockcolorfulFieldNumber = 9; + private bool playerDanmakuBlockcolorful_; + /// + /// 是否屏蔽彩色弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockcolorful { + get { return playerDanmakuBlockcolorful_; } + set { + playerDanmakuBlockcolorful_ = value; + } + } + + /// Field number for the "player_danmaku_blockrepeat" field. + public const int PlayerDanmakuBlockrepeatFieldNumber = 10; + private bool playerDanmakuBlockrepeat_; + /// + /// 是否屏蔽重复弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockrepeat { + get { return playerDanmakuBlockrepeat_; } + set { + playerDanmakuBlockrepeat_ = value; + } + } + + /// Field number for the "player_danmaku_blockspecial" field. + public const int PlayerDanmakuBlockspecialFieldNumber = 11; + private bool playerDanmakuBlockspecial_; + /// + /// 是否屏蔽高级弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuBlockspecial { + get { return playerDanmakuBlockspecial_; } + set { + playerDanmakuBlockspecial_ = value; + } + } + + /// Field number for the "player_danmaku_opacity" field. + public const int PlayerDanmakuOpacityFieldNumber = 12; + private float playerDanmakuOpacity_; + /// + /// 弹幕不透明度 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuOpacity { + get { return playerDanmakuOpacity_; } + set { + playerDanmakuOpacity_ = value; + } + } + + /// Field number for the "player_danmaku_scalingfactor" field. + public const int PlayerDanmakuScalingfactorFieldNumber = 13; + private float playerDanmakuScalingfactor_; + /// + /// 弹幕缩放比例 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuScalingfactor { + get { return playerDanmakuScalingfactor_; } + set { + playerDanmakuScalingfactor_ = value; + } + } + + /// Field number for the "player_danmaku_domain" field. + public const int PlayerDanmakuDomainFieldNumber = 14; + private float playerDanmakuDomain_; + /// + /// 弹幕显示区域 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuDomain { + get { return playerDanmakuDomain_; } + set { + playerDanmakuDomain_ = value; + } + } + + /// Field number for the "player_danmaku_speed" field. + public const int PlayerDanmakuSpeedFieldNumber = 15; + private int playerDanmakuSpeed_; + /// + /// 弹幕速度 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int PlayerDanmakuSpeed { + get { return playerDanmakuSpeed_; } + set { + playerDanmakuSpeed_ = value; + } + } + + /// Field number for the "player_danmaku_enableblocklist" field. + public const int PlayerDanmakuEnableblocklistFieldNumber = 16; + private bool playerDanmakuEnableblocklist_; + /// + /// 是否开启屏蔽列表 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool PlayerDanmakuEnableblocklist { + get { return playerDanmakuEnableblocklist_; } + set { + playerDanmakuEnableblocklist_ = value; + } + } + + /// Field number for the "inline_player_danmaku_switch" field. + public const int InlinePlayerDanmakuSwitchFieldNumber = 17; + private bool inlinePlayerDanmakuSwitch_; + /// + /// 是否开启弹幕 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool InlinePlayerDanmakuSwitch { + get { return inlinePlayerDanmakuSwitch_; } + set { + inlinePlayerDanmakuSwitch_ = value; + } + } + + /// Field number for the "inline_player_danmaku_config" field. + public const int InlinePlayerDanmakuConfigFieldNumber = 18; + private int inlinePlayerDanmakuConfig_; + /// + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int InlinePlayerDanmakuConfig { + get { return inlinePlayerDanmakuConfig_; } + set { + inlinePlayerDanmakuConfig_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmuPlayerConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmuPlayerConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (PlayerDanmakuSwitch != other.PlayerDanmakuSwitch) return false; + if (PlayerDanmakuSwitchSave != other.PlayerDanmakuSwitchSave) return false; + if (PlayerDanmakuUseDefaultConfig != other.PlayerDanmakuUseDefaultConfig) return false; + if (PlayerDanmakuAiRecommendedSwitch != other.PlayerDanmakuAiRecommendedSwitch) return false; + if (PlayerDanmakuAiRecommendedLevel != other.PlayerDanmakuAiRecommendedLevel) return false; + if (PlayerDanmakuBlocktop != other.PlayerDanmakuBlocktop) return false; + if (PlayerDanmakuBlockscroll != other.PlayerDanmakuBlockscroll) return false; + if (PlayerDanmakuBlockbottom != other.PlayerDanmakuBlockbottom) return false; + if (PlayerDanmakuBlockcolorful != other.PlayerDanmakuBlockcolorful) return false; + if (PlayerDanmakuBlockrepeat != other.PlayerDanmakuBlockrepeat) return false; + if (PlayerDanmakuBlockspecial != other.PlayerDanmakuBlockspecial) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuOpacity, other.PlayerDanmakuOpacity)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuScalingfactor, other.PlayerDanmakuScalingfactor)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuDomain, other.PlayerDanmakuDomain)) return false; + if (PlayerDanmakuSpeed != other.PlayerDanmakuSpeed) return false; + if (PlayerDanmakuEnableblocklist != other.PlayerDanmakuEnableblocklist) return false; + if (InlinePlayerDanmakuSwitch != other.InlinePlayerDanmakuSwitch) return false; + if (InlinePlayerDanmakuConfig != other.InlinePlayerDanmakuConfig) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (PlayerDanmakuSwitch != false) hash ^= PlayerDanmakuSwitch.GetHashCode(); + if (PlayerDanmakuSwitchSave != false) hash ^= PlayerDanmakuSwitchSave.GetHashCode(); + if (PlayerDanmakuUseDefaultConfig != false) hash ^= PlayerDanmakuUseDefaultConfig.GetHashCode(); + if (PlayerDanmakuAiRecommendedSwitch != false) hash ^= PlayerDanmakuAiRecommendedSwitch.GetHashCode(); + if (PlayerDanmakuAiRecommendedLevel != 0) hash ^= PlayerDanmakuAiRecommendedLevel.GetHashCode(); + if (PlayerDanmakuBlocktop != false) hash ^= PlayerDanmakuBlocktop.GetHashCode(); + if (PlayerDanmakuBlockscroll != false) hash ^= PlayerDanmakuBlockscroll.GetHashCode(); + if (PlayerDanmakuBlockbottom != false) hash ^= PlayerDanmakuBlockbottom.GetHashCode(); + if (PlayerDanmakuBlockcolorful != false) hash ^= PlayerDanmakuBlockcolorful.GetHashCode(); + if (PlayerDanmakuBlockrepeat != false) hash ^= PlayerDanmakuBlockrepeat.GetHashCode(); + if (PlayerDanmakuBlockspecial != false) hash ^= PlayerDanmakuBlockspecial.GetHashCode(); + if (PlayerDanmakuOpacity != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuOpacity); + if (PlayerDanmakuScalingfactor != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuScalingfactor); + if (PlayerDanmakuDomain != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuDomain); + if (PlayerDanmakuSpeed != 0) hash ^= PlayerDanmakuSpeed.GetHashCode(); + if (PlayerDanmakuEnableblocklist != false) hash ^= PlayerDanmakuEnableblocklist.GetHashCode(); + if (InlinePlayerDanmakuSwitch != false) hash ^= InlinePlayerDanmakuSwitch.GetHashCode(); + if (InlinePlayerDanmakuConfig != 0) hash ^= InlinePlayerDanmakuConfig.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (PlayerDanmakuSwitch != false) { + output.WriteRawTag(8); + output.WriteBool(PlayerDanmakuSwitch); + } + if (PlayerDanmakuSwitchSave != false) { + output.WriteRawTag(16); + output.WriteBool(PlayerDanmakuSwitchSave); + } + if (PlayerDanmakuUseDefaultConfig != false) { + output.WriteRawTag(24); + output.WriteBool(PlayerDanmakuUseDefaultConfig); + } + if (PlayerDanmakuAiRecommendedSwitch != false) { + output.WriteRawTag(32); + output.WriteBool(PlayerDanmakuAiRecommendedSwitch); + } + if (PlayerDanmakuAiRecommendedLevel != 0) { + output.WriteRawTag(40); + output.WriteInt32(PlayerDanmakuAiRecommendedLevel); + } + if (PlayerDanmakuBlocktop != false) { + output.WriteRawTag(48); + output.WriteBool(PlayerDanmakuBlocktop); + } + if (PlayerDanmakuBlockscroll != false) { + output.WriteRawTag(56); + output.WriteBool(PlayerDanmakuBlockscroll); + } + if (PlayerDanmakuBlockbottom != false) { + output.WriteRawTag(64); + output.WriteBool(PlayerDanmakuBlockbottom); + } + if (PlayerDanmakuBlockcolorful != false) { + output.WriteRawTag(72); + output.WriteBool(PlayerDanmakuBlockcolorful); + } + if (PlayerDanmakuBlockrepeat != false) { + output.WriteRawTag(80); + output.WriteBool(PlayerDanmakuBlockrepeat); + } + if (PlayerDanmakuBlockspecial != false) { + output.WriteRawTag(88); + output.WriteBool(PlayerDanmakuBlockspecial); + } + if (PlayerDanmakuOpacity != 0F) { + output.WriteRawTag(101); + output.WriteFloat(PlayerDanmakuOpacity); + } + if (PlayerDanmakuScalingfactor != 0F) { + output.WriteRawTag(109); + output.WriteFloat(PlayerDanmakuScalingfactor); + } + if (PlayerDanmakuDomain != 0F) { + output.WriteRawTag(117); + output.WriteFloat(PlayerDanmakuDomain); + } + if (PlayerDanmakuSpeed != 0) { + output.WriteRawTag(120); + output.WriteInt32(PlayerDanmakuSpeed); + } + if (PlayerDanmakuEnableblocklist != false) { + output.WriteRawTag(128, 1); + output.WriteBool(PlayerDanmakuEnableblocklist); + } + if (InlinePlayerDanmakuSwitch != false) { + output.WriteRawTag(136, 1); + output.WriteBool(InlinePlayerDanmakuSwitch); + } + if (InlinePlayerDanmakuConfig != 0) { + output.WriteRawTag(144, 1); + output.WriteInt32(InlinePlayerDanmakuConfig); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (PlayerDanmakuSwitch != false) { + output.WriteRawTag(8); + output.WriteBool(PlayerDanmakuSwitch); + } + if (PlayerDanmakuSwitchSave != false) { + output.WriteRawTag(16); + output.WriteBool(PlayerDanmakuSwitchSave); + } + if (PlayerDanmakuUseDefaultConfig != false) { + output.WriteRawTag(24); + output.WriteBool(PlayerDanmakuUseDefaultConfig); + } + if (PlayerDanmakuAiRecommendedSwitch != false) { + output.WriteRawTag(32); + output.WriteBool(PlayerDanmakuAiRecommendedSwitch); + } + if (PlayerDanmakuAiRecommendedLevel != 0) { + output.WriteRawTag(40); + output.WriteInt32(PlayerDanmakuAiRecommendedLevel); + } + if (PlayerDanmakuBlocktop != false) { + output.WriteRawTag(48); + output.WriteBool(PlayerDanmakuBlocktop); + } + if (PlayerDanmakuBlockscroll != false) { + output.WriteRawTag(56); + output.WriteBool(PlayerDanmakuBlockscroll); + } + if (PlayerDanmakuBlockbottom != false) { + output.WriteRawTag(64); + output.WriteBool(PlayerDanmakuBlockbottom); + } + if (PlayerDanmakuBlockcolorful != false) { + output.WriteRawTag(72); + output.WriteBool(PlayerDanmakuBlockcolorful); + } + if (PlayerDanmakuBlockrepeat != false) { + output.WriteRawTag(80); + output.WriteBool(PlayerDanmakuBlockrepeat); + } + if (PlayerDanmakuBlockspecial != false) { + output.WriteRawTag(88); + output.WriteBool(PlayerDanmakuBlockspecial); + } + if (PlayerDanmakuOpacity != 0F) { + output.WriteRawTag(101); + output.WriteFloat(PlayerDanmakuOpacity); + } + if (PlayerDanmakuScalingfactor != 0F) { + output.WriteRawTag(109); + output.WriteFloat(PlayerDanmakuScalingfactor); + } + if (PlayerDanmakuDomain != 0F) { + output.WriteRawTag(117); + output.WriteFloat(PlayerDanmakuDomain); + } + if (PlayerDanmakuSpeed != 0) { + output.WriteRawTag(120); + output.WriteInt32(PlayerDanmakuSpeed); + } + if (PlayerDanmakuEnableblocklist != false) { + output.WriteRawTag(128, 1); + output.WriteBool(PlayerDanmakuEnableblocklist); + } + if (InlinePlayerDanmakuSwitch != false) { + output.WriteRawTag(136, 1); + output.WriteBool(InlinePlayerDanmakuSwitch); + } + if (InlinePlayerDanmakuConfig != 0) { + output.WriteRawTag(144, 1); + output.WriteInt32(InlinePlayerDanmakuConfig); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (PlayerDanmakuSwitch != false) { + size += 1 + 1; + } + if (PlayerDanmakuSwitchSave != false) { + size += 1 + 1; + } + if (PlayerDanmakuUseDefaultConfig != false) { + size += 1 + 1; + } + if (PlayerDanmakuAiRecommendedSwitch != false) { + size += 1 + 1; + } + if (PlayerDanmakuAiRecommendedLevel != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(PlayerDanmakuAiRecommendedLevel); + } + if (PlayerDanmakuBlocktop != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockscroll != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockbottom != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockcolorful != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockrepeat != false) { + size += 1 + 1; + } + if (PlayerDanmakuBlockspecial != false) { + size += 1 + 1; + } + if (PlayerDanmakuOpacity != 0F) { + size += 1 + 4; + } + if (PlayerDanmakuScalingfactor != 0F) { + size += 1 + 4; + } + if (PlayerDanmakuDomain != 0F) { + size += 1 + 4; + } + if (PlayerDanmakuSpeed != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(PlayerDanmakuSpeed); + } + if (PlayerDanmakuEnableblocklist != false) { + size += 2 + 1; + } + if (InlinePlayerDanmakuSwitch != false) { + size += 2 + 1; + } + if (InlinePlayerDanmakuConfig != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(InlinePlayerDanmakuConfig); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmuPlayerConfig other) { + if (other == null) { + return; + } + if (other.PlayerDanmakuSwitch != false) { + PlayerDanmakuSwitch = other.PlayerDanmakuSwitch; + } + if (other.PlayerDanmakuSwitchSave != false) { + PlayerDanmakuSwitchSave = other.PlayerDanmakuSwitchSave; + } + if (other.PlayerDanmakuUseDefaultConfig != false) { + PlayerDanmakuUseDefaultConfig = other.PlayerDanmakuUseDefaultConfig; + } + if (other.PlayerDanmakuAiRecommendedSwitch != false) { + PlayerDanmakuAiRecommendedSwitch = other.PlayerDanmakuAiRecommendedSwitch; + } + if (other.PlayerDanmakuAiRecommendedLevel != 0) { + PlayerDanmakuAiRecommendedLevel = other.PlayerDanmakuAiRecommendedLevel; + } + if (other.PlayerDanmakuBlocktop != false) { + PlayerDanmakuBlocktop = other.PlayerDanmakuBlocktop; + } + if (other.PlayerDanmakuBlockscroll != false) { + PlayerDanmakuBlockscroll = other.PlayerDanmakuBlockscroll; + } + if (other.PlayerDanmakuBlockbottom != false) { + PlayerDanmakuBlockbottom = other.PlayerDanmakuBlockbottom; + } + if (other.PlayerDanmakuBlockcolorful != false) { + PlayerDanmakuBlockcolorful = other.PlayerDanmakuBlockcolorful; + } + if (other.PlayerDanmakuBlockrepeat != false) { + PlayerDanmakuBlockrepeat = other.PlayerDanmakuBlockrepeat; + } + if (other.PlayerDanmakuBlockspecial != false) { + PlayerDanmakuBlockspecial = other.PlayerDanmakuBlockspecial; + } + if (other.PlayerDanmakuOpacity != 0F) { + PlayerDanmakuOpacity = other.PlayerDanmakuOpacity; + } + if (other.PlayerDanmakuScalingfactor != 0F) { + PlayerDanmakuScalingfactor = other.PlayerDanmakuScalingfactor; + } + if (other.PlayerDanmakuDomain != 0F) { + PlayerDanmakuDomain = other.PlayerDanmakuDomain; + } + if (other.PlayerDanmakuSpeed != 0) { + PlayerDanmakuSpeed = other.PlayerDanmakuSpeed; + } + if (other.PlayerDanmakuEnableblocklist != false) { + PlayerDanmakuEnableblocklist = other.PlayerDanmakuEnableblocklist; + } + if (other.InlinePlayerDanmakuSwitch != false) { + InlinePlayerDanmakuSwitch = other.InlinePlayerDanmakuSwitch; + } + if (other.InlinePlayerDanmakuConfig != 0) { + InlinePlayerDanmakuConfig = other.InlinePlayerDanmakuConfig; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + PlayerDanmakuSwitch = input.ReadBool(); + break; + } + case 16: { + PlayerDanmakuSwitchSave = input.ReadBool(); + break; + } + case 24: { + PlayerDanmakuUseDefaultConfig = input.ReadBool(); + break; + } + case 32: { + PlayerDanmakuAiRecommendedSwitch = input.ReadBool(); + break; + } + case 40: { + PlayerDanmakuAiRecommendedLevel = input.ReadInt32(); + break; + } + case 48: { + PlayerDanmakuBlocktop = input.ReadBool(); + break; + } + case 56: { + PlayerDanmakuBlockscroll = input.ReadBool(); + break; + } + case 64: { + PlayerDanmakuBlockbottom = input.ReadBool(); + break; + } + case 72: { + PlayerDanmakuBlockcolorful = input.ReadBool(); + break; + } + case 80: { + PlayerDanmakuBlockrepeat = input.ReadBool(); + break; + } + case 88: { + PlayerDanmakuBlockspecial = input.ReadBool(); + break; + } + case 101: { + PlayerDanmakuOpacity = input.ReadFloat(); + break; + } + case 109: { + PlayerDanmakuScalingfactor = input.ReadFloat(); + break; + } + case 117: { + PlayerDanmakuDomain = input.ReadFloat(); + break; + } + case 120: { + PlayerDanmakuSpeed = input.ReadInt32(); + break; + } + case 128: { + PlayerDanmakuEnableblocklist = input.ReadBool(); + break; + } + case 136: { + InlinePlayerDanmakuSwitch = input.ReadBool(); + break; + } + case 144: { + InlinePlayerDanmakuConfig = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + PlayerDanmakuSwitch = input.ReadBool(); + break; + } + case 16: { + PlayerDanmakuSwitchSave = input.ReadBool(); + break; + } + case 24: { + PlayerDanmakuUseDefaultConfig = input.ReadBool(); + break; + } + case 32: { + PlayerDanmakuAiRecommendedSwitch = input.ReadBool(); + break; + } + case 40: { + PlayerDanmakuAiRecommendedLevel = input.ReadInt32(); + break; + } + case 48: { + PlayerDanmakuBlocktop = input.ReadBool(); + break; + } + case 56: { + PlayerDanmakuBlockscroll = input.ReadBool(); + break; + } + case 64: { + PlayerDanmakuBlockbottom = input.ReadBool(); + break; + } + case 72: { + PlayerDanmakuBlockcolorful = input.ReadBool(); + break; + } + case 80: { + PlayerDanmakuBlockrepeat = input.ReadBool(); + break; + } + case 88: { + PlayerDanmakuBlockspecial = input.ReadBool(); + break; + } + case 101: { + PlayerDanmakuOpacity = input.ReadFloat(); + break; + } + case 109: { + PlayerDanmakuScalingfactor = input.ReadFloat(); + break; + } + case 117: { + PlayerDanmakuDomain = input.ReadFloat(); + break; + } + case 120: { + PlayerDanmakuSpeed = input.ReadInt32(); + break; + } + case 128: { + PlayerDanmakuEnableblocklist = input.ReadBool(); + break; + } + case 136: { + InlinePlayerDanmakuSwitch = input.ReadBool(); + break; + } + case 144: { + InlinePlayerDanmakuConfig = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕显示区域自动配置 + /// + public sealed partial class DanmuPlayerDynamicConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DanmuPlayerDynamicConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[25]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerDynamicConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerDynamicConfig(DanmuPlayerDynamicConfig other) : this() { + progress_ = other.progress_; + playerDanmakuDomain_ = other.playerDanmakuDomain_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public DanmuPlayerDynamicConfig Clone() { + return new DanmuPlayerDynamicConfig(this); + } + + /// Field number for the "progress" field. + public const int ProgressFieldNumber = 1; + private int progress_; + /// + /// 时间 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Progress { + get { return progress_; } + set { + progress_ = value; + } + } + + /// Field number for the "player_danmaku_domain" field. + public const int PlayerDanmakuDomainFieldNumber = 2; + private float playerDanmakuDomain_; + /// + /// 弹幕显示区域 + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float PlayerDanmakuDomain { + get { return playerDanmakuDomain_; } + set { + playerDanmakuDomain_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as DanmuPlayerDynamicConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(DanmuPlayerDynamicConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Progress != other.Progress) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(PlayerDanmakuDomain, other.PlayerDanmakuDomain)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Progress != 0) hash ^= Progress.GetHashCode(); + if (PlayerDanmakuDomain != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(PlayerDanmakuDomain); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Progress != 0) { + output.WriteRawTag(8); + output.WriteInt32(Progress); + } + if (PlayerDanmakuDomain != 0F) { + output.WriteRawTag(21); + output.WriteFloat(PlayerDanmakuDomain); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Progress != 0) { + output.WriteRawTag(8); + output.WriteInt32(Progress); + } + if (PlayerDanmakuDomain != 0F) { + output.WriteRawTag(21); + output.WriteFloat(PlayerDanmakuDomain); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Progress != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Progress); + } + if (PlayerDanmakuDomain != 0F) { + size += 1 + 4; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(DanmuPlayerDynamicConfig other) { + if (other == null) { + return; + } + if (other.Progress != 0) { + Progress = other.Progress; + } + if (other.PlayerDanmakuDomain != 0F) { + PlayerDanmakuDomain = other.PlayerDanmakuDomain; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Progress = input.ReadInt32(); + break; + } + case 21: { + PlayerDanmakuDomain = input.ReadFloat(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Progress = input.ReadInt32(); + break; + } + case 21: { + PlayerDanmakuDomain = input.ReadFloat(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否开启弹幕 + /// + public sealed partial class PlayerDanmakuSwitch : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuSwitch()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[26]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSwitch() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSwitch(PlayerDanmakuSwitch other) : this() { + value_ = other.value_; + canIgnore_ = other.canIgnore_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSwitch Clone() { + return new PlayerDanmakuSwitch(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + /// Field number for the "canIgnore" field. + public const int CanIgnoreFieldNumber = 2; + private bool canIgnore_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool CanIgnore { + get { return canIgnore_; } + set { + canIgnore_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuSwitch); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuSwitch other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + if (CanIgnore != other.CanIgnore) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (CanIgnore != false) hash ^= CanIgnore.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (CanIgnore != false) { + output.WriteRawTag(16); + output.WriteBool(CanIgnore); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (CanIgnore != false) { + output.WriteRawTag(16); + output.WriteBool(CanIgnore); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (CanIgnore != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuSwitch other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + if (other.CanIgnore != false) { + CanIgnore = other.CanIgnore; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + case 16: { + CanIgnore = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + case 16: { + CanIgnore = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否记录弹幕开关设置 + /// + public sealed partial class PlayerDanmakuSwitchSave : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuSwitchSave()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[27]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSwitchSave() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSwitchSave(PlayerDanmakuSwitchSave other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSwitchSave Clone() { + return new PlayerDanmakuSwitchSave(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuSwitchSave); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuSwitchSave other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuSwitchSave other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否使用推荐弹幕设置 + /// + public sealed partial class PlayerDanmakuUseDefaultConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuUseDefaultConfig()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[28]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuUseDefaultConfig() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuUseDefaultConfig(PlayerDanmakuUseDefaultConfig other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuUseDefaultConfig Clone() { + return new PlayerDanmakuUseDefaultConfig(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuUseDefaultConfig); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuUseDefaultConfig other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuUseDefaultConfig other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否开启智能云屏蔽 + /// + public sealed partial class PlayerDanmakuAiRecommendedSwitch : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuAiRecommendedSwitch()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[29]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuAiRecommendedSwitch() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuAiRecommendedSwitch(PlayerDanmakuAiRecommendedSwitch other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuAiRecommendedSwitch Clone() { + return new PlayerDanmakuAiRecommendedSwitch(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuAiRecommendedSwitch); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuAiRecommendedSwitch other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuAiRecommendedSwitch other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 智能云屏蔽等级 + /// + public sealed partial class PlayerDanmakuAiRecommendedLevel : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuAiRecommendedLevel()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[30]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuAiRecommendedLevel() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuAiRecommendedLevel(PlayerDanmakuAiRecommendedLevel other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuAiRecommendedLevel Clone() { + return new PlayerDanmakuAiRecommendedLevel(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuAiRecommendedLevel); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuAiRecommendedLevel other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuAiRecommendedLevel other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否屏蔽顶端弹幕 + /// + public sealed partial class PlayerDanmakuBlocktop : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuBlocktop()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[31]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlocktop() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlocktop(PlayerDanmakuBlocktop other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlocktop Clone() { + return new PlayerDanmakuBlocktop(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuBlocktop); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuBlocktop other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuBlocktop other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否屏蔽滚动弹幕 + /// + public sealed partial class PlayerDanmakuBlockscroll : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuBlockscroll()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[32]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockscroll() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockscroll(PlayerDanmakuBlockscroll other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockscroll Clone() { + return new PlayerDanmakuBlockscroll(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuBlockscroll); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuBlockscroll other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuBlockscroll other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否屏蔽底端弹幕 + /// + public sealed partial class PlayerDanmakuBlockbottom : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuBlockbottom()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[33]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockbottom() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockbottom(PlayerDanmakuBlockbottom other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockbottom Clone() { + return new PlayerDanmakuBlockbottom(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuBlockbottom); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuBlockbottom other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuBlockbottom other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否屏蔽彩色弹幕 + /// + public sealed partial class PlayerDanmakuBlockcolorful : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuBlockcolorful()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[34]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockcolorful() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockcolorful(PlayerDanmakuBlockcolorful other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockcolorful Clone() { + return new PlayerDanmakuBlockcolorful(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuBlockcolorful); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuBlockcolorful other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuBlockcolorful other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否屏蔽重复弹幕 + /// + public sealed partial class PlayerDanmakuBlockrepeat : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuBlockrepeat()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[35]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockrepeat() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockrepeat(PlayerDanmakuBlockrepeat other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockrepeat Clone() { + return new PlayerDanmakuBlockrepeat(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuBlockrepeat); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuBlockrepeat other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuBlockrepeat other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否屏蔽高级弹幕 + /// + public sealed partial class PlayerDanmakuBlockspecial : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuBlockspecial()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[36]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockspecial() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockspecial(PlayerDanmakuBlockspecial other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuBlockspecial Clone() { + return new PlayerDanmakuBlockspecial(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuBlockspecial); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuBlockspecial other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuBlockspecial other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕不透明度 + /// + public sealed partial class PlayerDanmakuOpacity : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuOpacity()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[37]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuOpacity() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuOpacity(PlayerDanmakuOpacity other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuOpacity Clone() { + return new PlayerDanmakuOpacity(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private float value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuOpacity); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuOpacity other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Value, other.Value)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Value); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != 0F) { + size += 1 + 4; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuOpacity other) { + if (other == null) { + return; + } + if (other.Value != 0F) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕缩放比例 + /// + public sealed partial class PlayerDanmakuScalingfactor : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuScalingfactor()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[38]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuScalingfactor() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuScalingfactor(PlayerDanmakuScalingfactor other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuScalingfactor Clone() { + return new PlayerDanmakuScalingfactor(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private float value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuScalingfactor); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuScalingfactor other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Value, other.Value)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Value); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != 0F) { + size += 1 + 4; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuScalingfactor other) { + if (other == null) { + return; + } + if (other.Value != 0F) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕显示区域 + /// + public sealed partial class PlayerDanmakuDomain : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuDomain()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[39]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuDomain() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuDomain(PlayerDanmakuDomain other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuDomain Clone() { + return new PlayerDanmakuDomain(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private float value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public float Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuDomain); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuDomain other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Value, other.Value)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != 0F) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Value); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != 0F) { + size += 1 + 4; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuDomain other) { + if (other == null) { + return; + } + if (other.Value != 0F) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } + } + #endif + + } + + /// + /// 弹幕速度 + /// + public sealed partial class PlayerDanmakuSpeed : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuSpeed()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[40]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSpeed() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSpeed(PlayerDanmakuSpeed other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuSpeed Clone() { + return new PlayerDanmakuSpeed(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private int value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuSpeed); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuSpeed other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != 0) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != 0) { + output.WriteRawTag(8); + output.WriteInt32(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0) { + output.WriteRawTag(8); + output.WriteInt32(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Value); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuSpeed other) { + if (other == null) { + return; + } + if (other.Value != 0) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否开启屏蔽列表 + /// + public sealed partial class PlayerDanmakuEnableblocklist : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PlayerDanmakuEnableblocklist()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[41]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuEnableblocklist() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuEnableblocklist(PlayerDanmakuEnableblocklist other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public PlayerDanmakuEnableblocklist Clone() { + return new PlayerDanmakuEnableblocklist(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as PlayerDanmakuEnableblocklist); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(PlayerDanmakuEnableblocklist other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(PlayerDanmakuEnableblocklist other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + /// + /// 是否开启弹幕 + /// + public sealed partial class InlinePlayerDanmakuSwitch : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new InlinePlayerDanmakuSwitch()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Bilibili.Community.Service.Dm.V1.DmReflection.Descriptor.MessageTypes[42]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public InlinePlayerDanmakuSwitch() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public InlinePlayerDanmakuSwitch(InlinePlayerDanmakuSwitch other) : this() { + value_ = other.value_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public InlinePlayerDanmakuSwitch Clone() { + return new InlinePlayerDanmakuSwitch(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as InlinePlayerDanmakuSwitch); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(InlinePlayerDanmakuSwitch other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(InlinePlayerDanmakuSwitch other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/DownKyi.Core/Danmaku2Ass/Bilibili.cs b/DownKyi.Core/Danmaku2Ass/Bilibili.cs new file mode 100644 index 0000000..5a8e812 --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Bilibili.cs @@ -0,0 +1,169 @@ +using DownKyi.Core.BiliApi.Danmaku; +using System.Collections.Generic; + +namespace DownKyi.Core.Danmaku2Ass +{ + public class Bilibili + { + private static Bilibili instance; + + private readonly Dictionary config = new Dictionary + { + { "top_filter", false }, + { "bottom_filter", false }, + { "scroll_filter", false } + }; + + private readonly Dictionary mapping = new Dictionary + { + { 0, "none" }, // 保留项 + { 1, "scroll" }, + { 2, "scroll" }, + { 3, "scroll" }, + { 4, "bottom" }, + { 5, "top" }, + { 6, "scroll" }, // 逆向滚动弹幕,还是当滚动处理 + { 7, "none" }, // 高级弹幕,暂时不要考虑 + { 8, "none" }, // 代码弹幕,暂时不要考虑 + { 9, "none" }, // BAS弹幕,暂时不要考虑 + { 10, "none" }, // 未知,暂时不要考虑 + { 11, "none" }, // 保留项 + { 12, "none" }, // 保留项 + { 13, "none" }, // 保留项 + { 14, "none" }, // 保留项 + { 15, "none" }, // 保留项 + }; + + // 弹幕标准字体大小 + private readonly int normalFontSize = 25; + + /// + /// 获取Bilibili实例 + /// + /// + public static Bilibili GetInstance() + { + if (instance == null) + { + instance = new Bilibili(); + } + + return instance; + } + + /// + /// 隐藏Bilibili()方法,必须使用单例模式 + /// + private Bilibili() { } + + /// + /// 是否屏蔽顶部弹幕 + /// + /// + /// + public Bilibili SetTopFilter(bool isFilter) + { + config["top_filter"] = isFilter; + return this; + } + + /// + /// 是否屏蔽底部弹幕 + /// + /// + /// + public Bilibili SetBottomFilter(bool isFilter) + { + config["bottom_filter"] = isFilter; + return this; + } + + /// + /// 是否屏蔽滚动弹幕 + /// + /// + /// + public Bilibili SetScrollFilter(bool isFilter) + { + config["scroll_filter"] = isFilter; + return this; + } + + public void Create(long avid, long cid, Config subtitleConfig, string assFile) + { + // 弹幕转换 + var biliDanmakus = DanmakuProtobuf.GetAllDanmakuProto(avid, cid); + + // 按弹幕出现顺序排序 + biliDanmakus.Sort((x, y) => { return x.Progress.CompareTo(y.Progress); }); + + var danmakus = new List(); + foreach (var biliDanmaku in biliDanmakus) + { + var danmaku = new Danmaku + { + // biliDanmaku.Progress单位是毫秒,所以除以1000,单位变为秒 + Start = biliDanmaku.Progress / 1000.0f, + Style = mapping[biliDanmaku.Mode], + Color = (int)biliDanmaku.Color, + Commenter = biliDanmaku.MidHash, + Content = biliDanmaku.Content, + SizeRatio = 1.0f * biliDanmaku.Fontsize / normalFontSize + }; + + danmakus.Add(danmaku); + } + + // 弹幕预处理 + Producer producer = new Producer(config, danmakus); + producer.StartHandle(); + + // 字幕生成 + var keepedDanmakus = producer.KeepedDanmakus; + var studio = new Studio(subtitleConfig, keepedDanmakus); + studio.StartHandle(); + studio.CreateAssFile(assFile); + } + + public Dictionary GetResolution(int quality) + { + var resolution = new Dictionary + { + { "width", 0 }, + { "height", 0 } + }; + + switch (quality) + { + // 240P 极速(仅mp4方式) + case 6: + break; + // 360P 流畅 + case 16: + break; + // 480P 清晰 + case 32: + break; + // 720P 高清(登录) + case 64: + break; + // 720P60 高清(大会员) + case 74: + break; + // 1080P 高清(登录) + case 80: + break; + // 1080P+ 高清(大会员) + case 112: + break; + // 1080P60 高清(大会员) + case 116: + break; + // 4K 超清(大会员)(需要fourk=1) + case 120: + break; + } + return resolution; + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Collision.cs b/DownKyi.Core/Danmaku2Ass/Collision.cs new file mode 100644 index 0000000..518b997 --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Collision.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.Core.Danmaku2Ass +{ + /// + /// 碰撞处理 + /// + public class Collision + { + private readonly int lineCount; + private readonly List leaves; + + public Collision(int lineCount) + { + this.lineCount = lineCount; + leaves = Leaves(); + } + + private List Leaves() + { + var ret = new List(lineCount); + for (int i = 0; i < lineCount; i++) ret.Add(0); + return ret; + } + + /// + /// 碰撞检测 + /// 返回行号和时间偏移 + /// + /// + /// + public Tuple Detect(Display display) + { + List beyonds = new List(); + for (int i = 0; i < leaves.Count; i++) + { + float beyond = display.Danmaku.Start - leaves[i]; + // 某一行有足够空间,直接返回行号和 0 偏移 + if (beyond >= 0) + { + return Tuple.Create(i, 0f); + } + beyonds.Add(beyond); + } + + // 所有行都没有空间了,那么找出哪一行能在最短时间内让出空间 + float soon = beyonds.Max(); + int lineIndex = beyonds.IndexOf(soon); + float offset = -soon; + return Tuple.Create(lineIndex, offset); + } + + public void Update(float leave, int lineIndex, float offset) + { + leaves[lineIndex] = Utils.IntCeiling(leave + offset); + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Config.cs b/DownKyi.Core/Danmaku2Ass/Config.cs new file mode 100644 index 0000000..79b4aad --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Config.cs @@ -0,0 +1,57 @@ +using System; + +namespace DownKyi.Core.Danmaku2Ass +{ + public class Config + { + public string Title = "Downkyi"; + public int ScreenWidth = 1920; + public int ScreenHeight = 1080; + public string FontName = "黑体"; + public int BaseFontSize; // 字体大小,像素 + + // 限制行数 + private int lineCount; + public int LineCount + { + get { return lineCount; } + set + { + if (value == 0) + { + lineCount = (int)Math.Floor(ScreenHeight / BaseFontSize * 1.0); + } + else + { + lineCount = value; + } + } + } + + public string LayoutAlgorithm; // 布局算法,async/sync + public int TuneDuration; // 微调时长 + public int DropOffset; // 丢弃偏移 + public int BottomMargin; // 底部边距 + public int CustomOffset; // 自定义偏移 + public string HeaderTemplate = @"[Script Info] +; Script generated by Downkyi Danmaku Converter +; https://github.com/FlySelfLog/downkyi +Title: {title} +ScriptType: v4.00+ +Collisions: Normal +PlayResX: {width} +PlayResY: {height} +Timer: 10.0000 +WrapStyle: 2 +ScaledBorderAndShadow: no + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,{fontname},54,&H00FFFFFF,&H00FFFFFF,&H00000000,&H00000000,0,0,0,0,100,100,0.00,0.00,1,2.00,0.00,2,30,30,120,0 +Style: Alternate,{fontname},36,&H00FFFFFF,&H00FFFFFF,&H00000000,&H00000000,0,0,0,0,100,100,0.00,0.00,1,2.00,0.00,2,30,30,84,0 +Style: Danmaku,{fontname},{fontsize},&H00FFFFFF,&H00FFFFFF,&H00000000,&H00000000,0,0,0,0,100,100,0.00,0.00,1,1.00,0.00,2,30,30,30,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"; + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Creater.cs b/DownKyi.Core/Danmaku2Ass/Creater.cs new file mode 100644 index 0000000..c5d8090 --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Creater.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.Danmaku2Ass +{ + /// + /// 创建器 + /// + public class Creater + { + public Config Config; + public List Danmakus; + public List Subtitles; + public string Text; + + public Creater(Config config, List danmakus) + { + Config = config; + Danmakus = danmakus; + Subtitles = SetSubtitles(); + Text = SetText(); + } + + protected List SetSubtitles() + { + var scroll = new Collision(Config.LineCount); + var stayed = new Collision(Config.LineCount); + Dictionary collisions = new Dictionary + { + { "scroll", scroll }, + { "top", stayed }, + { "bottom", stayed } + }; + + List subtitles = new List(); + foreach (var danmaku in Danmakus) + { + // 丢弃不支持的 + if (danmaku.Style == "none") + { + continue; + } + + // 创建显示方式对象 + var display = Display.Factory(Config, danmaku); + var collision = collisions[danmaku.Style]; + var detect = collision.Detect(display); + int lineIndex = detect.Item1; + float waitingOffset = detect.Item2; + + // 超过容忍的偏移量,丢弃掉此条弹幕 + if (waitingOffset > Config.DropOffset) + { + continue; + } + + // 接受偏移,更新碰撞信息 + display.Relayout(lineIndex); + collision.Update(display.Leave, lineIndex, waitingOffset); + + // 再加上自定义偏移 + float offset = waitingOffset + Config.CustomOffset; + Subtitle subtitle = new Subtitle(danmaku, display, offset); + + subtitles.Add(subtitle); + } + return subtitles; + } + + protected string SetText() + { + string header = Config.HeaderTemplate + .Replace("{title}", Config.Title) + .Replace("{width}", Config.ScreenWidth.ToString()) + .Replace("{height}", Config.ScreenHeight.ToString()) + .Replace("{fontname}", Config.FontName) + .Replace("{fontsize}", Config.BaseFontSize.ToString()); + + string events = string.Empty; + foreach (var subtitle in Subtitles) + { + events += "\n" + subtitle.Text; + } + + return header + events; + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Danmaku.cs b/DownKyi.Core/Danmaku2Ass/Danmaku.cs new file mode 100644 index 0000000..f12afce --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Danmaku.cs @@ -0,0 +1,12 @@ +namespace DownKyi.Core.Danmaku2Ass +{ + public class Danmaku + { + public float Start { get; set; } + public string Style { get; set; } + public int Color { get; set; } + public string Commenter { get; set; } + public string Content { get; set; } + public float SizeRatio { get; set; } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Display.cs b/DownKyi.Core/Danmaku2Ass/Display.cs new file mode 100644 index 0000000..e83f48f --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Display.cs @@ -0,0 +1,406 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace DownKyi.Core.Danmaku2Ass +{ + /// + /// 显示方式 + /// + public class Display + { + public Config Config; + public Danmaku Danmaku; + public int LineIndex; + + public int FontSize; + public bool IsScaled; + public int MaxLength; + public int Width; + public int Height; + + public Tuple Horizontal; + public Tuple Vertical; + + public int Duration; + public int Leave; + + protected Display() { } + + public Display(Config config, Danmaku danmaku) + { + Config = config; + Danmaku = danmaku; + LineIndex = 0; + + IsScaled = SetIsScaled(); + FontSize = SetFontSize(); + MaxLength = SetMaxLength(); + Width = SetWidth(); + Height = SetHeight(); + + Horizontal = SetHorizontal(); + Vertical = SetVertical(); + + Duration = SetDuration(); + Leave = SetLeave(); + } + + /// + /// 根据弹幕样式自动创建对应的 Display 类 + /// + /// + public static Display Factory(Config config, Danmaku danmaku) + { + Dictionary dict = new Dictionary + { + { "scroll", new ScrollDisplay(config, danmaku) }, + { "top", new TopDisplay(config, danmaku) }, + { "bottom", new BottomDisplay(config, danmaku) } + }; + return dict[danmaku.Style]; + } + + /// + /// 字体大小 + /// 按用户自定义的字体大小来缩放 + /// + /// + protected int SetFontSize() + { + if (IsScaled) + { + Console.WriteLine($"{Danmaku.SizeRatio}"); + } + return Utils.IntCeiling(Config.BaseFontSize * Danmaku.SizeRatio); + } + + /// + /// 字体是否被缩放过 + /// + /// + protected bool SetIsScaled() + { + return !Math.Round(Danmaku.SizeRatio, 2).Equals(1.0); + //return Danmaku.SizeRatio.Equals(1.0f); + } + + /// + /// 最长的行字符数 + /// + /// + protected int SetMaxLength() + { + string[] lines = Danmaku.Content.Split('\n'); + int maxLength = 0; + foreach (string line in lines) + { + int length = Utils.DisplayLength(line); + if (maxLength < length) + { + maxLength = length; + } + } + return maxLength; + } + + /// + /// 整条字幕宽度 + /// + /// + protected int SetWidth() + { + float charCount = MaxLength;// / 2; + return Utils.IntCeiling(FontSize * charCount); + } + + /// + /// 整条字幕高度 + /// + /// + protected int SetHeight() + { + int lineCount = Danmaku.Content.Split('\n').Length; + return lineCount * FontSize; + } + + /// + /// 出现和消失的水平坐标位置 + /// 默认在屏幕中间 + /// + /// + protected virtual Tuple SetHorizontal() + { + int x = (int)Math.Floor(Config.ScreenWidth / 2.0); + return Tuple.Create(x, x); + } + + /// + /// 出现和消失的垂直坐标位置 + /// 默认在屏幕中间 + /// + /// + protected virtual Tuple SetVertical() + { + int y = (int)Math.Floor(Config.ScreenHeight / 2.0); + return Tuple.Create(y, y); + } + + /// + /// 整条字幕的显示时间 + /// + /// + protected virtual int SetDuration() + { + int baseDuration = 3 + Config.TuneDuration; + if (baseDuration <= 0) + { + baseDuration = 0; + } + float charCount = MaxLength / 2; + + int value; + if (charCount < 6) + { + value = baseDuration + 1; + } + else if (charCount < 12) + { + value = baseDuration + 2; + } + else + { + value = baseDuration + 3; + } + return value; + } + + /// + /// 离开碰撞时间 + /// + /// + protected virtual int SetLeave() + { + return (int)(Danmaku.Start + Duration); + } + + /// + /// 按照新的行号重新布局 + /// + /// + public void Relayout(int lineIndex) + { + LineIndex = lineIndex; + Horizontal = SetHorizontal(); + Vertical = SetVertical(); + } + } + + + /// + /// 顶部 + /// + public class TopDisplay : Display + { + public TopDisplay(Config config, Danmaku danmaku) : base(config, danmaku) + { + Console.WriteLine("TopDisplay constructor."); + } + + /// + /// + /// + /// + protected override Tuple SetVertical() + { + // 这里 y 坐标为 0 就是最顶行了 + int y = LineIndex * Config.BaseFontSize; + return Tuple.Create(y, y); + } + } + + /// + /// 底部 + /// + public class BottomDisplay : Display + { + public BottomDisplay(Config config, Danmaku danmaku) : base(config, danmaku) + { + Console.WriteLine("BottomDisplay constructor."); + } + + /// + /// + /// + /// + protected override Tuple SetVertical() + { + // 要让字幕不超出底部,减去高度 + int y = Config.ScreenHeight - (LineIndex * Config.BaseFontSize) - Height; + // 再减去自定义的底部边距 + y -= Config.BottomMargin; + return Tuple.Create(y, y); + } + } + + /// + /// 滚动 + /// + public class ScrollDisplay : Display + { + public int Distance; + public int Speed; + + public ScrollDisplay(Config config, Danmaku danmaku) : base() + { + Console.WriteLine("ScrollDisplay constructor."); + + Config = config; + Danmaku = danmaku; + LineIndex = 0; + + IsScaled = SetIsScaled(); + FontSize = SetFontSize(); + MaxLength = SetMaxLength(); + Width = SetWidth(); + Height = SetHeight(); + + Horizontal = SetHorizontal(); + Vertical = SetVertical(); + + Distance = SetDistance(); + Speed = SetSpeed(); + + Duration = SetDuration(); + Leave = SetLeave(); + } + + /// + /// ASS 的水平位置参考点是整条字幕文本的中点 + /// + /// + protected override Tuple SetHorizontal() + { + int x1 = Config.ScreenWidth + (int)Math.Floor(Width / 2.0); + int x2 = 0 - (int)Math.Floor(Width / 2.0); + return Tuple.Create(x1, x2); + } + + protected override Tuple SetVertical() + { + int baseFontSize = Config.BaseFontSize; + + // 垂直位置,按基准字体大小算每一行的高度 + int y = (LineIndex + 1) * baseFontSize; + + // 个别弹幕可能字体比基准要大,所以最上的一行还要避免挤出顶部屏幕 + // 坐标不能小于字体大小 + if (y < FontSize) + { + y = FontSize; + } + return Tuple.Create(y, y); + } + + /// + /// 字幕坐标点的移动距离 + /// + /// + protected int SetDistance() + { + Tuple x = Horizontal; + return x.Item1 - x.Item2; + } + + /// + /// 字幕每个字的移动的速度 + /// + /// + protected int SetSpeed() + { + // 基准时间,就是每个字的移动时间 + // 12 秒加上用户自定义的微调 + int baseDuration = 12 + Config.TuneDuration; + if (baseDuration <= 0) + { + baseDuration = 1; + } + return Utils.IntCeiling(Config.ScreenWidth / baseDuration); + } + + /// + /// 计算每条弹幕的显示时长,同步方式 + /// 每个弹幕的滚动速度都一样,辨认度好,适合观看剧集类视频。 + /// + /// + public int SyncDuration() + { + return Distance / Speed; + } + + /// + /// 计算每条弹幕的显示时长,异步方式 + /// 每个弹幕的滚动速度都不一样,动态调整,辨认度低,适合观看 MTV 类视频。 + /// + /// + public int AsyncDuration() + { + int baseDuration = 6 + Config.TuneDuration; + if (baseDuration <= 0) + { + baseDuration = 0; + } + float charCount = MaxLength / 2; + + int value; + if (charCount < 6) + { + value = (int)(baseDuration + charCount); + } + else if (charCount < 12) + { + value = baseDuration + (int)(charCount / 2); + } + else if (charCount < 24) + { + value = baseDuration + (int)(charCount / 3); + } + else + { + value = baseDuration + 10; + } + return value; + } + + /// + /// 整条字幕的移动时间 + /// + /// + protected override int SetDuration() + { + string methodName = Config.LayoutAlgorithm.Substring(0, 1).ToUpper() + Config.LayoutAlgorithm.Substring(1); + methodName += "Duration"; + MethodInfo method = typeof(ScrollDisplay).GetMethod(methodName); + if (method != null) + { + return (int)method.Invoke(this, null); + } + return 0; + } + + /// + /// 离开碰撞时间 + /// + /// + protected override int SetLeave() + { + // 对于滚动样式弹幕来说,就是最后一个字符离开最右边缘的时间 + // 坐标是字幕中点,在屏幕外和内各有半个字幕宽度 + // 也就是跑过一个字幕宽度的路程 + float duration = Width / Speed; + return (int)(Danmaku.Start + duration); + } + + } + +} diff --git a/DownKyi.Core/Danmaku2Ass/Filter.cs b/DownKyi.Core/Danmaku2Ass/Filter.cs new file mode 100644 index 0000000..625405f --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Filter.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.Danmaku2Ass +{ + /// + /// 过滤器基类 + /// + public class Filter + { + public virtual List DoFilter(List danmakus) + { + throw new NotImplementedException("使用了过滤器的未实现的方法。"); + } + } + + /// + /// 顶部样式过滤器 + /// + public class TopFilter : Filter + { + public override List DoFilter(List danmakus) + { + List keep = new List(); + foreach (var danmaku in danmakus) + { + if (danmaku.Style == "top") + { + continue; + } + keep.Add(danmaku); + } + return keep; + } + } + + /// + /// 底部样式过滤器 + /// + public class BottomFilter : Filter + { + public override List DoFilter(List danmakus) + { + List keep = new List(); + foreach (var danmaku in danmakus) + { + if (danmaku.Style == "bottom") + { + continue; + } + keep.Add(danmaku); + } + return keep; + } + } + + /// + /// 滚动样式过滤器 + /// + public class ScrollFilter : Filter + { + public override List DoFilter(List danmakus) + { + List keep = new List(); + foreach (var danmaku in danmakus) + { + if (danmaku.Style == "scroll") + { + continue; + } + keep.Add(danmaku); + } + return keep; + } + } + + /// + /// 自定义过滤器 + /// + public class CustomFilter : Filter + { + public override List DoFilter(List danmakus) + { + // TODO + return base.DoFilter(danmakus); + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Producer.cs b/DownKyi.Core/Danmaku2Ass/Producer.cs new file mode 100644 index 0000000..42e0ae3 --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Producer.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.Core.Danmaku2Ass +{ + public class Producer + { + public Dictionary Config; + public Dictionary Filters; + public List Danmakus; + public List KeepedDanmakus; + public Dictionary FilterDetail; + + public Producer(Dictionary config, List danmakus) + { + Config = config; + Danmakus = danmakus; + } + + public void StartHandle() + { + LoadFilter(); + ApplyFilter(); + } + + public void LoadFilter() + { + Filters = new Dictionary(); + if (Config["top_filter"]) + { + Filters.Add("top_filter", new TopFilter()); + } + if (Config["bottom_filter"]) + { + Filters.Add("bottom_filter", new BottomFilter()); + } + if (Config["scroll_filter"]) + { + Filters.Add("scroll_filter", new ScrollFilter()); + } + //if (Config["custom_filter"]) + //{ + // Filters.Add("custom_filter", new CustomFilter()); + //} + + } + + public void ApplyFilter() + { + Dictionary filterDetail = new Dictionary() { + { "top_filter",0}, + { "bottom_filter",0}, + { "scroll_filter",0}, + //{ "custom_filter",0} + }; + + List danmakus = Danmakus; + //string[] orders = { "top_filter", "bottom_filter", "scroll_filter", "custom_filter" }; + string[] orders = { "top_filter", "bottom_filter", "scroll_filter" }; + foreach (var name in orders) + { + Filter filter; + try + { + filter = Filters[name]; + } + catch (Exception e) + { + Console.WriteLine("ApplyFilter()发生异常: {0}", e); + continue; + } + + int count = danmakus.Count; + danmakus = filter.DoFilter(danmakus); + filterDetail[name] = count - danmakus.Count; + } + + KeepedDanmakus = danmakus; + FilterDetail = filterDetail; + } + + public Dictionary Report() + { + int blockedCount = 0; + foreach (int count in FilterDetail.Values) + { + blockedCount += count; + } + + int passedCount = KeepedDanmakus.Count; + int totalCount = blockedCount + passedCount; + + Dictionary ret = new Dictionary + { + { "blocked", blockedCount }, + { "passed", passedCount }, + { "total", totalCount } + }; + + return (Dictionary)ret.Concat(FilterDetail); + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Studio.cs b/DownKyi.Core/Danmaku2Ass/Studio.cs new file mode 100644 index 0000000..97acc48 --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Studio.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace DownKyi.Core.Danmaku2Ass +{ + /// + /// 字幕工程类 + /// + public class Studio + { + public Config Config; + public List Danmakus; + + public Creater Creater; + public int KeepedCount; + public int DropedCount; + + public Studio(Config config, List danmakus) + { + Config = config; + Danmakus = danmakus; + } + + public void StartHandle() + { + Creater = SetCreater(); + KeepedCount = SetKeepedCount(); + DropedCount = SetDropedCount(); + } + + /// + /// ass 创建器 + /// + /// + protected Creater SetCreater() + { + return new Creater(Config, Danmakus); + } + + /// + /// 保留条数 + /// + /// + protected int SetKeepedCount() + { + return Creater.Subtitles.Count(); + } + + /// + /// 丢弃条数 + /// + /// + protected int SetDropedCount() + { + return Danmakus.Count - KeepedCount; + } + + /// + /// 创建 ass 字幕 + /// + /// + public void CreateAssFile(string fileName) + { + CreateFile(fileName, Creater.Text); + } + + public void CreateFile(string fileName, string text) + { + File.WriteAllText(fileName, text); + } + + public Dictionary Report() + { + return new Dictionary() + { + {"total", Danmakus.Count}, + {"droped", DropedCount}, + {"keeped", KeepedCount}, + }; + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Subtitle.cs b/DownKyi.Core/Danmaku2Ass/Subtitle.cs new file mode 100644 index 0000000..d785065 --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Subtitle.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.Danmaku2Ass +{ + /// + /// 字幕 + /// + public class Subtitle + { + public Danmaku Danmaku; + public Display Display; + public float Offset; + + public float Start; + public float End; + public string Color; + public Dictionary Position; + public string StartMarkup; + public string EndMarkup; + public string ColorMarkup; + public string BorderMarkup; + public string FontSizeMarkup; + public string StyleMarkup; + public string LayerMarkup; + public string ContentMarkup; + public string Text; + + public Subtitle(Danmaku danmaku, Display display, float offset = 0) + { + Danmaku = danmaku; + Display = display; + Offset = offset; + + Start = SetStart(); + End = SetEnd(); + Color = SetColor(); + Position = SetPosition(); + StartMarkup = SetStartMarkup(); + EndMarkup = SetEndMarkup(); + ColorMarkup = SetColorMarkup(); + BorderMarkup = SetBorderMarkup(); + FontSizeMarkup = SetFontSizeMarkup(); + StyleMarkup = SetStyleMarkup(); + LayerMarkup = SetLayerMarkup(); + ContentMarkup = SetContentMarkup(); + Text = SetText(); + } + + protected float SetStart() + { + return Danmaku.Start + Offset; + } + + protected float SetEnd() + { + return Start + Display.Duration; + } + + protected string SetColor() + { + return Utils.Int2bgr(Danmaku.Color); + } + + protected Dictionary SetPosition() + { + Tuple x = Display.Horizontal; + Tuple y = Display.Vertical; + + Dictionary value = new Dictionary + { + { "x1", x.Item1 }, + { "x2", x.Item2 }, + { "y1", y.Item1 }, + { "y2", y.Item2 } + }; + return value; + } + + protected string SetStartMarkup() + { + return Utils.Second2hms(Start); + } + + protected string SetEndMarkup() + { + return Utils.Second2hms(End); + } + + protected string SetColorMarkup() + { + // 白色不需要加特别标记 + if (Color == "FFFFFF") + { + return ""; + } + return "\\c&H" + Color; + } + + protected string SetBorderMarkup() + { + // 暗色加个亮色边框,方便阅读 + if (Utils.IsDark(Danmaku.Color)) + { + //return "\\3c&HFFFFFF"; + return "\\3c&H000000"; + } + else + { + return "\\3c&H000000"; + } + //return ""; + } + + protected string SetFontSizeMarkup() + { + if (Display.IsScaled) + { + return $"\\fs{Display.FontSize}"; + } + return ""; + } + + protected string SetStyleMarkup() + { + if (Danmaku.Style == "scroll") + { + return $"\\move({Position["x1"]}, {Position["y1"]}, {Position["x2"]}, {Position["y2"]})"; + } + return $"\\a6\\pos({Position["x1"]}, {Position["y1"]})"; + } + + protected string SetLayerMarkup() + { + if (Danmaku.Style != "scroll") + { + return "-2"; + } + return "-1"; + } + + protected string SetContentMarkup() + { + string markup = StyleMarkup + ColorMarkup + BorderMarkup + FontSizeMarkup; + string content = Utils.CorrectTypos(Danmaku.Content); + return $"{{{markup}}}{content}"; + } + + protected string SetText() + { + return $"Dialogue: {LayerMarkup},{StartMarkup},{EndMarkup},Danmaku,,0000,0000,0000,,{ContentMarkup}"; + } + } +} diff --git a/DownKyi.Core/Danmaku2Ass/Utils.cs b/DownKyi.Core/Danmaku2Ass/Utils.cs new file mode 100644 index 0000000..2d874cc --- /dev/null +++ b/DownKyi.Core/Danmaku2Ass/Utils.cs @@ -0,0 +1,227 @@ +using System; +using System.Linq; +using System.Text; + +namespace DownKyi.Core.Danmaku2Ass +{ + internal static class Utils + { + /// + /// 向上取整,返回int类型 + /// + /// + /// + public static int IntCeiling(float number) + { + return (int)Math.Ceiling(number); + } + + /// + /// 字符长度,1个汉字当2个英文 + /// + /// + /// + public static int DisplayLength(string text) + { + return Encoding.Default.GetBytes(text).Length; + } + + /// + /// 修正一些评论者的拼写错误 + /// + /// + /// + public static string CorrectTypos(string text) + { + text = text.Replace("/n", "\\N"); + text = text.Replace(">", ">"); + text = text.Replace("<", "<"); + return text; + } + + /// + /// 秒数转 时:分:秒 格式 + /// + /// + /// + public static string Second2hms(float seconds) + { + if (seconds < 0) + { + return "0:00:00.00"; + } + + int i = (int)Math.Floor(seconds / 1.0); + int dec = (int)(Math.Round(seconds % 1.0f, 2) * 100); + if (dec >= 100) + { + dec = 99; + } + + int min = (int)Math.Floor(i / 60.0); + int second = (int)(i % 60.0f); + + int hour = (int)Math.Floor(min / 60.0); + + return $"{hour:D}:{min:D2}:{second:D2}.{dec:D2}"; + } + + /// + /// 时:分:秒 格式转 秒数 + /// + /// + /// + public static float Hms2second(string hms) + { + string[] numbers = hms.Split(':'); + float seconds = 0; + + for (int i = 0; i < numbers.Length; i++) + { + seconds += (float)(float.Parse(numbers[numbers.Length - i - 1]) * Math.Pow(60, i)); + } + return seconds; + } + + /// + /// 同Hms2second(string hms),不过可以用 +/- 符号来连接多个 + /// 即 3:00-2:30 相当于 30 秒 + /// + /// + /// + public static float Xhms2second(string xhms) + { + string[] args = xhms.Replace("+", " +").Replace("-", " -").Split(' '); + float result = 0; + foreach (string hms in args) + { + result += Hms2second(hms); + } + return result; + } + + /// + /// 颜色值,整型转 RGB + /// + /// + /// + public static string Int2rgb(int integer) + { + return integer.ToString("X").PadLeft(6, '0'); ; + } + + /// + /// 颜色值,整型转 BGR + /// + /// + /// + public static string Int2bgr(int integer) + { + string rgb = Int2rgb(integer); + string bgr = rgb.Substring(4, 2) + rgb.Substring(2, 2) + rgb.Substring(0, 2); + return bgr; + } + + /// + /// 颜色值,整型转 HLS + /// + /// + /// + public static float[] Int2hls(int integer) + { + string rgb = Int2rgb(integer); + int[] rgb_decimals = { 0, 0, 0 }; + rgb_decimals[0] = int.Parse(rgb.Substring(0, 2), System.Globalization.NumberStyles.HexNumber); + rgb_decimals[1] = int.Parse(rgb.Substring(2, 2), System.Globalization.NumberStyles.HexNumber); + rgb_decimals[2] = int.Parse(rgb.Substring(4, 2), System.Globalization.NumberStyles.HexNumber); + + int[] rgb_coordinates = { 0, 0, 0 }; + rgb_coordinates[0] = (int)Math.Floor(rgb_decimals[0] / 255.0); + rgb_coordinates[1] = (int)Math.Floor(rgb_decimals[1] / 255.0); + rgb_coordinates[2] = (int)Math.Floor(rgb_decimals[2] / 255.0); + float[] hls_corrdinates = Rgb2hls(rgb_coordinates); + + float[] hls = { 0, 0, 0 }; + hls[0] = hls_corrdinates[0] * 360; + hls[1] = hls_corrdinates[1] * 100; + hls[2] = hls_corrdinates[2] * 100; + return hls; + } + + /// + /// HLS: Hue, Luminance, Saturation + /// H: position in the spectrum + /// L: color lightness + /// S: color saturation + /// + /// + /// + private static float[] Rgb2hls(int[] rgb) + { + float[] hls = { 0, 0, 0 }; + int maxc = rgb.Max(); + int minc = rgb.Min(); + hls[1] = (minc + maxc) / 2.0f; + if (minc == maxc) + { + return hls; + } + + if (hls[1] <= 0.5) + { + hls[2] = (maxc - minc) / (maxc + minc); + } + else + { + hls[2] = (maxc - minc) / (2.0f - maxc - minc); + } + float rc = (maxc - rgb[0]) / (maxc - minc); + float gc = (maxc - rgb[1]) / (maxc - minc); + float bc = (maxc - rgb[2]) / (maxc - minc); + if (rgb[0] == maxc) + { + hls[0] = bc - gc; + } + else if (rgb[1] == maxc) + { + hls[0] = 2.0f + rc - bc; + } + else + { + hls[0] = 4.0f + gc - rc; + } + hls[0] = (hls[0] / 6.0f) % 1.0f; + return hls; + } + + /// + /// 是否属于暗色 + /// + /// + /// + public static bool IsDark(int integer) + { + if (integer == 0) + { + return true; + } + + float[] hls = Int2hls(integer); + float hue = hls[0]; + float lightness = hls[1]; + + // HSL 色轮见 + // http://zh.wikipedia.org/zh-cn/HSL和HSV色彩空间 + // 以下的数值都是我的主观判断认为是暗色 + if ((hue > 30 && hue < 210) && lightness < 33) + { + return true; + } + if ((hue < 30 || hue > 210) && lightness < 66) + { + return true; + } + return false; + } + } +} diff --git a/DownKyi.Core/DownKyi.Core.csproj b/DownKyi.Core/DownKyi.Core.csproj new file mode 100644 index 0000000..4a0a896 --- /dev/null +++ b/DownKyi.Core/DownKyi.Core.csproj @@ -0,0 +1,261 @@ + + + + + Debug + AnyCPU + {4FDE0364-F65B-4812-BFE8-34E886624FBD} + Library + Properties + DownKyi.Core + DownKyi.Core + v4.7.2 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Brotli.NET.2.1.1\lib\net45\Brotli.Core.dll + + + ..\packages\Google.Protobuf.3.18.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + + + ..\packages\QRCoder.1.4.1\lib\net40\QRCoder.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + ..\packages\System.Data.SQLite.Core.1.0.112.2\lib\net40\System.Data.SQLite.dll + + + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + True + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + + + \ No newline at end of file diff --git a/DownKyi.Core/Downloader/MultiThreadDownloader.cs b/DownKyi.Core/Downloader/MultiThreadDownloader.cs new file mode 100644 index 0000000..c4d8a0b --- /dev/null +++ b/DownKyi.Core/Downloader/MultiThreadDownloader.cs @@ -0,0 +1,423 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; + +namespace DownKyi.Core.Downloader +{ + /// + /// 文件合并改变事件 + /// + /// + /// + public delegate void FileMergeProgressChangedEventHandler(object sender, int e); + + /// + /// 多线程下载器 + /// + public class MultiThreadDownloader + { + #region 属性 + + private string _url; + private bool _rangeAllowed; + private readonly HttpWebRequest _request; + private Action _requestConfigure = req => req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"; + #endregion + + #region 公共属性 + + /// + /// RangeAllowed + /// + public bool RangeAllowed + { + get => _rangeAllowed; + set => _rangeAllowed = value; + } + + /// + /// 临时文件夹 + /// + public string TempFileDirectory { get; set; } + + /// + /// url地址 + /// + public string Url + { + get => _url; + set => _url = value; + } + + /// + /// 第几部分 + /// + public int NumberOfParts { get; set; } + + /// + /// 已接收字节数 + /// + public long TotalBytesReceived + { + get + { + try + { + return PartialDownloaderList.Where(t => t != null).Sum(t => t.TotalBytesRead); + } + catch (Exception e) + { + Logging.LogManager.Error(e); + return 0; + } + } + } + + /// + /// 总进度 + /// + public float TotalProgress { get; private set; } + + /// + /// 文件大小 + /// + public long Size { get; private set; } + + /// + /// 下载速度 + /// + public float TotalSpeedInBytes => PartialDownloaderList.Sum(t => t.SpeedInBytes); + + /// + /// 下载块 + /// + public List PartialDownloaderList { get; } + + /// + /// 文件路径 + /// + public string FilePath { get; set; } + + #endregion + + #region 变量 + + /// + /// 总下载进度更新事件 + /// + public event EventHandler TotalProgressChanged; + + /// + /// 文件合并完成事件 + /// + public event EventHandler FileMergedComplete; + + /// + /// 文件合并事件 + /// + public event FileMergeProgressChangedEventHandler FileMergeProgressChanged; + + private readonly AsyncOperation _aop; + + #endregion + + #region 下载管理器 + + /// + /// 多线程下载管理器 + /// + /// + /// + /// + /// + public MultiThreadDownloader(string sourceUrl, string tempDir, string savePath, int numOfParts) + { + _url = sourceUrl; + NumberOfParts = numOfParts; + TempFileDirectory = tempDir; + PartialDownloaderList = new List(); + _aop = AsyncOperationManager.CreateOperation(null); + FilePath = savePath; + _request = WebRequest.Create(sourceUrl) as HttpWebRequest; + } + + /// + /// 多线程下载管理器 + /// + /// + /// + /// + public MultiThreadDownloader(string sourceUrl, string savePath, int numOfParts) : this(sourceUrl, null, savePath, numOfParts) + { + TempFileDirectory = Environment.GetEnvironmentVariable("temp"); + } + + /// + /// 多线程下载管理器 + /// + /// + /// + public MultiThreadDownloader(string sourceUrl, int numOfParts) : this(sourceUrl, null, numOfParts) + { + } + + #endregion + + #region 事件 + + private void temp_DownloadPartCompleted(object sender, EventArgs e) + { + WaitOrResumeAll(PartialDownloaderList, true); + + if (TotalBytesReceived == Size) + { + UpdateProgress(); + MergeParts(); + return; + } + + PartialDownloaderList.Sort((x, y) => y.RemainingBytes - x.RemainingBytes); + int rem = PartialDownloaderList[0].RemainingBytes; + if (rem < 50 * 1024) + { + WaitOrResumeAll(PartialDownloaderList, false); + return; + } + + int from = PartialDownloaderList[0].CurrentPosition + rem / 2; + int to = PartialDownloaderList[0].To; + if (from > to) + { + WaitOrResumeAll(PartialDownloaderList, false); + return; + } + + PartialDownloaderList[0].To = from - 1; + WaitOrResumeAll(PartialDownloaderList, false); + var temp = new PartialDownloader(_url, TempFileDirectory, Guid.NewGuid().ToString(), from, to, true); + temp.DownloadPartCompleted += temp_DownloadPartCompleted; + temp.DownloadPartProgressChanged += temp_DownloadPartProgressChanged; + PartialDownloaderList.Add(temp); + temp.Start(_requestConfigure); + } + + void temp_DownloadPartProgressChanged(object sender, EventArgs e) + { + UpdateProgress(); + } + + void UpdateProgress() + { + int pr = (int)(TotalBytesReceived * 1d / Size * 100); + if (TotalProgress != pr) + { + TotalProgress = pr; + if (TotalProgressChanged != null) + { + _aop.Post(state => TotalProgressChanged(this, EventArgs.Empty), null); + } + } + } + + #endregion + + #region 方法 + + void CreateFirstPartitions() + { + Size = GetContentLength(ref _rangeAllowed, ref _url); + int maximumPart = (int)(Size / (25 * 1024)); + maximumPart = maximumPart == 0 ? 1 : maximumPart; + if (!_rangeAllowed) + { + NumberOfParts = 1; + } + else if (NumberOfParts > maximumPart) + { + NumberOfParts = maximumPart; + } + + for (int i = 0; i < NumberOfParts; i++) + { + var temp = CreateNew(i, NumberOfParts, Size); + temp.DownloadPartProgressChanged += temp_DownloadPartProgressChanged; + temp.DownloadPartCompleted += temp_DownloadPartCompleted; + PartialDownloaderList.Add(temp); + temp.Start(_requestConfigure); + } + } + + void MergeParts() + { + var mergeOrderedList = PartialDownloaderList.OrderBy(x => x.From); + var dir = new FileInfo(FilePath).DirectoryName; + Directory.CreateDirectory(dir); + + using (var fs = File.OpenWrite(FilePath)) + { + long totalBytesWrite = 0; + int mergeProgress = 0; + foreach (var item in mergeOrderedList) + { + using (var pdi = File.OpenRead(item.FullPath)) + { + byte[] buffer = new byte[4096]; + int read; + while ((read = pdi.Read(buffer, 0, buffer.Length)) > 0) + { + fs.Write(buffer, 0, read); + totalBytesWrite += read; + int temp = (int)(totalBytesWrite * 1d / Size * 100); + if (temp != mergeProgress && FileMergeProgressChanged != null) + { + mergeProgress = temp; + _aop.Post(state => FileMergeProgressChanged(this, temp), null); + } + } + } + + try + { + File.Delete(item.FullPath); + } + catch + { + // ignored + } + } + } + + if (FileMergedComplete != null) + { + _aop.Post(state => FileMergedComplete(state, EventArgs.Empty), this); + } + } + + PartialDownloader CreateNew(int order, int parts, long contentLength) + { + int division = (int)contentLength / parts; + int remaining = (int)contentLength % parts; + int start = division * order; + int end = start + division - 1; + end += order == parts - 1 ? remaining : 0; + return new PartialDownloader(_url, TempFileDirectory, Guid.NewGuid().ToString("N"), start, end, true); + } + + /// + /// 暂停或继续 + /// + /// + /// + public static void WaitOrResumeAll(List list, bool wait) + { + foreach (var item in list) + { + if (wait) + { + item.Wait(); + } + else + { + item.ResumeAfterWait(); + } + } + } + + /// + /// 配置请求头 + /// + /// + public void Configure(Action config) + { + _requestConfigure = config; + } + + /// + /// 获取内容长度 + /// + /// + /// + /// + public long GetContentLength(ref bool rangeAllowed, ref string redirectedUrl) + { + _request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"; + _request.ServicePoint.ConnectionLimit = 4; + _requestConfigure(_request); + + long ctl; + using (var resp = _request.GetResponse() as HttpWebResponse) + { + redirectedUrl = resp.ResponseUri.OriginalString; + ctl = resp.ContentLength; + rangeAllowed = resp.Headers.AllKeys.Select((v, i) => new + { + HeaderName = v, + HeaderValue = resp.Headers[i] + }).Any(k => k.HeaderName.ToLower().Contains("range") && k.HeaderValue.ToLower().Contains("byte")); + _request.Abort(); + } + + return ctl; + } + + #endregion + + #region 公共方法 + + /// + /// 暂停下载 + /// + public void Pause() + { + foreach (var t in PartialDownloaderList.Where(t => !t.Completed)) + { + t.Stop(); + } + + Thread.Sleep(200); + } + + /// + /// 开始下载 + /// + public void Start() + { + Task th = new Task(CreateFirstPartitions); + th.Start(); + } + + /// + /// 唤醒下载 + /// + public void Resume() + { + int count = PartialDownloaderList.Count; + for (int i = 0; i < count; i++) + { + if (PartialDownloaderList[i].Stopped) + { + int from = PartialDownloaderList[i].CurrentPosition + 1; + int to = PartialDownloaderList[i].To; + if (from > to) + { + continue; + } + + var temp = new PartialDownloader(_url, TempFileDirectory, Guid.NewGuid().ToString(), from, to, _rangeAllowed); + temp.DownloadPartProgressChanged += temp_DownloadPartProgressChanged; + temp.DownloadPartCompleted += temp_DownloadPartCompleted; + PartialDownloaderList.Add(temp); + PartialDownloaderList[i].To = PartialDownloaderList[i].CurrentPosition; + temp.Start(_requestConfigure); + } + } + } + + #endregion + } +} diff --git a/DownKyi.Core/Downloader/PartialDownloader.cs b/DownKyi.Core/Downloader/PartialDownloader.cs new file mode 100644 index 0000000..de94973 --- /dev/null +++ b/DownKyi.Core/Downloader/PartialDownloader.cs @@ -0,0 +1,268 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; + +namespace DownKyi.Core.Downloader +{ + /// + /// 部分下载器 + /// + public class PartialDownloader + { + /// + /// 这部分完成事件 + /// + public event EventHandler DownloadPartCompleted; + + /// + /// 部分下载进度改变事件 + /// + public event EventHandler DownloadPartProgressChanged; + + /// + /// 部分下载停止事件 + /// + public event EventHandler DownloadPartStopped; + + private readonly AsyncOperation _aop = AsyncOperationManager.CreateOperation(null); + readonly int[] _lastSpeeds; + int _counter; + private bool _wait; + private int _to; + private int _totalBytesRead; + + /// + /// 下载已停止 + /// + public bool Stopped { get; private set; } + + /// + /// 下载已完成 + /// + public bool Completed { get; private set; } + + /// + /// 下载进度 + /// + public int Progress { get; private set; } + + /// + /// 下载目录 + /// + public string Directory { get; } + + /// + /// 文件名 + /// + public string FileName { get; } + + /// + /// 已读字节数 + /// + public long TotalBytesRead => _totalBytesRead; + + /// + /// 内容长度 + /// + public long ContentLength { get; private set; } + + /// + /// RangeAllowed + /// + public bool RangeAllowed { get; } + + /// + /// url + /// + public string Url { get; } + + /// + /// to + /// + public int To + { + get => _to; + set + { + _to = value; + ContentLength = _to - From + 1; + } + } + + /// + /// from + /// + public int From { get; } + + /// + /// 当前位置 + /// + public int CurrentPosition => From + _totalBytesRead - 1; + + /// + /// 剩余字节数 + /// + public int RemainingBytes => (int)(ContentLength - _totalBytesRead); + + /// + /// 完整路径 + /// + public string FullPath => Path.Combine(Directory, FileName); + + /// + /// 下载速度 + /// + public int SpeedInBytes + { + get + { + if (Completed) + { + return 0; + } + + int totalSpeeds = _lastSpeeds.Sum(); + return totalSpeeds / 10; + } + } + + /// + /// 部分块下载 + /// + /// + /// + /// + /// + /// + /// + public PartialDownloader(string url, string dir, string fileGuid, int from, int to, bool rangeAllowed) + { + From = from; + _to = to; + Url = url; + RangeAllowed = rangeAllowed; + FileName = fileGuid; + Directory = dir; + _lastSpeeds = new int[10]; + } + + void DownloadProcedure(Action config) + { + using (var file = new FileStream(FullPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Delete)) + { + var sw = new Stopwatch(); + if (WebRequest.Create(Url) is HttpWebRequest req) + { + req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"; + req.AllowAutoRedirect = true; + req.MaximumAutomaticRedirections = 5; + req.ServicePoint.ConnectionLimit += 1; + req.ServicePoint.Expect100Continue = true; + req.ProtocolVersion = HttpVersion.Version11; + config(req); + if (RangeAllowed) + { + req.AddRange(From, _to); + } + + if (req.GetResponse() is HttpWebResponse resp) + { + ContentLength = resp.ContentLength; + if (ContentLength <= 0 || (RangeAllowed && ContentLength != _to - From + 1)) + { + throw new Exception("Invalid response content"); + } + + using (var tempStream = resp.GetResponseStream()) + { + int bytesRead; + byte[] buffer = new byte[4096]; + sw.Start(); + while ((bytesRead = tempStream.Read(buffer, 0, buffer.Length)) > 0) + { + if (_totalBytesRead + bytesRead > ContentLength) + { + bytesRead = (int)(ContentLength - _totalBytesRead); + } + + file.Write(buffer, 0, bytesRead); + _totalBytesRead += bytesRead; + _lastSpeeds[_counter] = (int)(_totalBytesRead / Math.Ceiling(sw.Elapsed.TotalSeconds)); + _counter = (_counter >= 9) ? 0 : _counter + 1; + int tempProgress = (int)(_totalBytesRead * 100 / ContentLength); + if (Progress != tempProgress) + { + Progress = tempProgress; + _aop.Post(state => + { + DownloadPartProgressChanged?.Invoke(this, EventArgs.Empty); + }, null); + } + + if (Stopped || (RangeAllowed && _totalBytesRead == ContentLength)) + { + break; + } + } + } + } + + req.Abort(); + } + + sw.Stop(); + if (!Stopped && DownloadPartCompleted != null) + { + _aop.Post(state => + { + Completed = true; + DownloadPartCompleted(this, EventArgs.Empty); + }, null); + } + + if (Stopped && DownloadPartStopped != null) + { + _aop.Post(state => DownloadPartStopped(this, EventArgs.Empty), null); + } + } + } + + /// + /// 启动下载 + /// + public void Start(Action config) + { + Stopped = false; + var procThread = new Thread(_ => DownloadProcedure(config)); + procThread.Start(); + } + + /// + /// 下载停止 + /// + public void Stop() + { + Stopped = true; + } + + /// + /// 暂停等待下载 + /// + public void Wait() + { + _wait = true; + } + + /// + /// 稍后唤醒 + /// + public void ResumeAfterWait() + { + _wait = false; + } + } +} diff --git a/DownKyi.Core/FFmpeg/FFmpegHelper.cs b/DownKyi.Core/FFmpeg/FFmpegHelper.cs new file mode 100644 index 0000000..b77bf99 --- /dev/null +++ b/DownKyi.Core/FFmpeg/FFmpegHelper.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; + +namespace DownKyi.Core.FFmpeg +{ + public static class FFmpegHelper + { + private const string Tag = "PageToolboxDelogo"; + + /// + /// 合并音频和视频 + /// + /// + /// + /// + public static bool MergeVideo(string video1, string video2, string destVideo) + { + string param = $"-i \"{video1}\" -i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\""; + if (video1 == null || !File.Exists(video1)) + { + param = $"-i \"{video2}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\""; + } + if (video2 == null || !File.Exists(video2)) + { + param = $"-i \"{video1}\" -acodec copy -vcodec copy -f mp4 \"{destVideo}\""; + } + if (!File.Exists(video1) && !File.Exists(video2)) { return false; } + + // 如果存在 + try { File.Delete(destVideo); } + catch (IOException e) + { + Console.WriteLine("MergeVideo()发生IO异常: {0}", e); + Logging.LogManager.Error(Tag, e); + return false; + } + + ExcuteProcess("ffmpeg.exe", param, null, (s, e) => Console.WriteLine(e.Data)); + + try + { + if (video1 != null) { File.Delete(video1); } + if (video2 != null) { File.Delete(video2); } + } + catch (IOException e) + { + Console.WriteLine("MergeVideo()发生IO异常: {0}", e); + Logging.LogManager.Error(Tag, e); + } + + return true; + } + + /// + /// 拼接多个视频 + /// + /// + /// + /// + /// + public static bool ConcatVideo(string workingDirectory, List flvFiles, string destVideo) + { + // contact的文件名,不包含路径 + string concatFileName = Guid.NewGuid().ToString("N") + "_concat.txt"; + try + { + string contact = ""; + foreach (string flv in flvFiles) + { + contact += $"file '{flv}'\n"; + } + + FileStream fileStream = new FileStream(workingDirectory + "/" + concatFileName, FileMode.Create); + StreamWriter streamWriter = new StreamWriter(fileStream); + //开始写入 + streamWriter.Write(contact); + //清空缓冲区 + streamWriter.Flush(); + //关闭流 + streamWriter.Close(); + fileStream.Close(); + } + catch (Exception e) + { + Console.WriteLine("ConcatVideo()发生异常: {0}", e); + Logging.LogManager.Error(Tag, e); + return false; + } + + // ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mkv + // 加上-y,表示如果有同名文件,则默认覆盖 + string param = $"-f concat -safe 0 -i {concatFileName} -c copy \"{destVideo}\" -y"; + ExcuteProcess("ffmpeg.exe", param, workingDirectory, (s, e) => Console.WriteLine(e.Data)); + + // 删除临时文件 + try + { + // 删除concat文件 + File.Delete(workingDirectory + "/" + concatFileName); + + foreach (string flv in flvFiles) + { + File.Delete(flv); + } + } + catch (Exception e) + { + Console.WriteLine("ConcatVideo()发生异常: {0}", e); + Logging.LogManager.Error(Tag, e); + } + + return true; + } + + /// + /// 去水印,非常消耗cpu资源 + /// + /// + /// + /// + /// + /// + /// + /// + public static void Delogo(string video, string destVideo, int x, int y, int width, int height, Action action) + { + // ffmpeg -i "video.mp4" -vf delogo=x=1670:y=50:w=180:h=70:show=1 "delogo.mp4" + string param = $"-i \"{video}\" -vf delogo=x={x}:y={y}:w={width}:h={height}:show=0 \"{destVideo}\" -hide_banner -y"; + ExcuteProcess("ffmpeg.exe", param, null, (s, e) => + { + Console.WriteLine(e.Data); + action.Invoke(e.Data); + }); + } + + /// + /// 从一个视频中仅提取音频 + /// + /// 源视频 + /// 目标音频 + /// 输出信息 + public static void ExtractAudio(string video, string audio, Action action) + { + // 抽取音频命令 + // ffmpeg -i 3.mp4 -vn -y -acodec copy 3.aac + // ffmpeg -i 3.mp4 -vn -y -acodec copy 3.m4a + string param = $"-i \"{video}\" -vn -y -acodec copy \"{audio}\" -hide_banner"; + ExcuteProcess("ffmpeg.exe", param, + null, (s, e) => + { + Console.WriteLine(e.Data); + action.Invoke(e.Data); + }); + } + + /// + /// 从一个视频中仅提取视频 + /// + /// 源视频 + /// 目标视频 + /// 输出信息 + public static void ExtractVideo(string video, string destVideo, Action action) + { + // 提取视频 (Extract Video) + // ffmpeg -i Life.of.Pi.has.subtitles.mkv -vcodec copy –an videoNoAudioSubtitle.mp4 + string param = $"-i \"{video}\" -y -vcodec copy -an \"{destVideo}\" -hide_banner"; + ExcuteProcess("ffmpeg.exe", param, + null, (s, e) => + { + Console.WriteLine(e.Data); + action.Invoke(e.Data); + }); + } + + /// + /// 提取视频的帧,输出为图片 + /// + /// + /// + /// + public static void ExtractFrame(string video, string image, uint number) + { + // 提取帧 + // ffmpeg -i caiyilin.wmv -vframes 1 wm.bmp + string param = $"-i \"{video}\" -y -vframes {number} \"{image}\""; + ExcuteProcess("ffmpeg.exe", param, null, (s, e) => Console.WriteLine(e.Data)); + } + + + /// + /// 执行一个控制台程序 + /// + /// 程序名称 + /// 参数 + /// 工作路径 + /// 输出重定向 + private static void ExcuteProcess(string exe, string arg, string workingDirectory, DataReceivedEventHandler output) + { + using (var p = new Process()) + { + p.StartInfo.FileName = exe; + p.StartInfo.Arguments = arg; + + // 工作目录 + if (workingDirectory != null) + { + p.StartInfo.WorkingDirectory = workingDirectory; + } + + p.StartInfo.UseShellExecute = false; //输出信息重定向 + p.StartInfo.CreateNoWindow = true; + p.StartInfo.RedirectStandardError = true; + p.StartInfo.RedirectStandardOutput = true; + + // 将 StandardErrorEncoding 改为 UTF-8 才不会出现中文乱码 + p.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8; + p.StartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8; + + p.OutputDataReceived += output; + p.ErrorDataReceived += output; + + p.Start(); //启动线程 + p.BeginOutputReadLine(); + p.BeginErrorReadLine(); + p.WaitForExit(); //等待进程结束 + } + } + + } +} diff --git a/DownKyi.Core/Logging/LogInfo.cs b/DownKyi.Core/Logging/LogInfo.cs new file mode 100644 index 0000000..192afe7 --- /dev/null +++ b/DownKyi.Core/Logging/LogInfo.cs @@ -0,0 +1,55 @@ +using System; + +namespace DownKyi.Core.Logging +{ + /// + /// 日志信息 + /// + public class LogInfo + { + /// + /// 时间 + /// + public DateTime Time { get; set; } + + /// + /// 线程id + /// + public int ThreadId { get; set; } + + /// + /// 日志级别 + /// + public LogLevel LogLevel { get; set; } + + /// + /// 异常源 + /// + public string Source { get; set; } + + /// + /// 异常信息 + /// + public string Message { get; set; } + + /// + /// 异常对象 + /// + public Exception Exception { get; set; } + + /// + /// 日志类型 + /// + public string ExceptionType { get; set; } + + /// + /// 请求路径 + /// + public string RequestUrl { get; set; } + + /// + /// 客户端代理 + /// + public string UserAgent { get; set; } + } +} \ No newline at end of file diff --git a/DownKyi.Core/Logging/LogLevel.cs b/DownKyi.Core/Logging/LogLevel.cs new file mode 100644 index 0000000..bf7108e --- /dev/null +++ b/DownKyi.Core/Logging/LogLevel.cs @@ -0,0 +1,28 @@ +namespace DownKyi.Core.Logging +{ + /// + /// 日志级别 + /// + public enum LogLevel + { + /// + /// 信息级别 + /// + Info, + + /// + /// debug级别 + /// + Debug, + + /// + /// 错误级别 + /// + Error, + + /// + /// 致命级别 + /// + Fatal + } +} \ No newline at end of file diff --git a/DownKyi.Core/Logging/LogManager.cs b/DownKyi.Core/Logging/LogManager.cs new file mode 100644 index 0000000..f91abc5 --- /dev/null +++ b/DownKyi.Core/Logging/LogManager.cs @@ -0,0 +1,450 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using static System.DateTime; + +namespace DownKyi.Core.Logging +{ + /// + /// 日志组件 + /// + public class LogManager + { + static readonly ConcurrentQueue> LogQueue = new ConcurrentQueue>(); + + /// + /// 自定义事件 + /// + public static event Action Event; + + static LogManager() + { + var writeTask = new Task(obj => + { + while (true) + { + Pause.WaitOne(1000, true); + List temp = new List(); + foreach (var logItem in LogQueue) + { + string logPath = logItem.Item1; + string logMergeContent = string.Concat(logItem.Item2, Environment.NewLine, "----------------------------------------------------------------------------------------------------------------------", Environment.NewLine); + string[] logArr = temp.FirstOrDefault(d => d[0].Equals(logPath)); + if (logArr != null) + { + logArr[1] = string.Concat(logArr[1], logMergeContent); + } + else + { + logArr = new[] + { + logPath, + logMergeContent + }; + temp.Add(logArr); + } + + LogQueue.TryDequeue(out Tuple _); + } + + foreach (var item in temp) + { + WriteText(item[0], item[1]); + } + } + }, null, TaskCreationOptions.LongRunning); + writeTask.Start(); + } + + private static AutoResetEvent Pause => new AutoResetEvent(false); + + /// + /// 日志存放目录,默认日志放在当前应用程序运行目录下的logs文件夹中 + /// + public static string LogDirectory + { + get => Storage.Constant.Logs; // Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs"); + set + { + } + } + + /// + /// 写入Info级别的日志 + /// + /// + public static void Info(string info) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(info).ToUpper()} {info}")); + var log = new LogInfo() + { + LogLevel = LogLevel.Info, + Message = info, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId + }; + Event?.Invoke(log); + } + + /// + /// 写入Info级别的日志 + /// + /// + /// + public static void Info(string source, string info) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(info).ToUpper()} {source} {info}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Info, + Message = info, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source + }; + Event?.Invoke(log); + } + + /// + /// 写入Info级别的日志 + /// + /// + /// + public static void Info(Type source, string info) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(info).ToUpper()} {source.FullName} {info}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Info, + Message = info, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source.FullName + }; + Event?.Invoke(log); + } + + /// + /// 写入debug级别日志 + /// + /// 异常对象 + public static void Debug(string debug) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(debug).ToUpper()} {debug}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Debug, + Message = debug, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId + }; + Event?.Invoke(log); + } + + /// + /// 写入debug级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Debug(string source, string debug) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(debug).ToUpper()} {source} {debug}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Debug, + Message = debug, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source + }; + Event?.Invoke(log); + } + + /// + /// 写入debug级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Debug(Type source, string debug) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(debug).ToUpper()} {source.FullName} {debug}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Debug, + Message = debug, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source.FullName + }; + Event?.Invoke(log); + } + + /// + /// 写入error级别日志 + /// + /// 异常对象 + public static void Error(Exception error) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(error).ToUpper()} {error.Source} {error.Message}{Environment.NewLine}{error.StackTrace}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Error, + Message = error.Message, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = error.Source, + Exception = error, + ExceptionType = error.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入error级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Error(Type source, Exception error) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(error).ToUpper()} {source.FullName} {error.Message}{Environment.NewLine}{error.StackTrace}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Error, + Message = error.Message, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source.FullName, + Exception = error, + ExceptionType = error.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入error级别日志 + /// + /// 异常源的类型 + /// 异常信息 + public static void Error(Type source, string error) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(error).ToUpper()} {source.FullName} {error}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Error, + Message = error, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source.FullName, + //Exception = error, + ExceptionType = error.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入error级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Error(string source, Exception error) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(error).ToUpper()} {source} {error.Message}{Environment.NewLine}{error.StackTrace}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Error, + Message = error.Message, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source, + Exception = error, + ExceptionType = error.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入error级别日志 + /// + /// 异常源的类型 + /// 异常信息 + public static void Error(string source, string error) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(error).ToUpper()} {source} {error}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Error, + Message = error, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source, + //Exception = error, + ExceptionType = error.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入fatal级别日志 + /// + /// 异常对象 + public static void Fatal(Exception fatal) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(fatal).ToUpper()} {fatal.Source} {fatal.Message}{Environment.NewLine}{fatal.StackTrace}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Fatal, + Message = fatal.Message, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = fatal.Source, + Exception = fatal, + ExceptionType = fatal.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入fatal级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Fatal(Type source, Exception fatal) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(fatal).ToUpper()} {source.FullName} {fatal.Message}{Environment.NewLine}{fatal.StackTrace}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Fatal, + Message = fatal.Message, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source.FullName, + Exception = fatal, + ExceptionType = fatal.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入fatal级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Fatal(Type source, string fatal) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(fatal).ToUpper()} {source.FullName} {fatal}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Fatal, + Message = fatal, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source.FullName, + //Exception = fatal, + ExceptionType = fatal.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入fatal级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Fatal(string source, Exception fatal) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(fatal).ToUpper()} {source} {fatal.Message}{Environment.NewLine}{fatal.StackTrace}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Fatal, + Message = fatal.Message, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source, + Exception = fatal, + ExceptionType = fatal.GetType().Name + }; + Event?.Invoke(log); + } + + /// + /// 写入fatal级别日志 + /// + /// 异常源的类型 + /// 异常对象 + public static void Fatal(string source, string fatal) + { + LogQueue.Enqueue(new Tuple(GetLogPath(), $"{Now} [{Thread.CurrentThread.ManagedThreadId}] {nameof(fatal).ToUpper()} {source} {fatal}")); + LogInfo log = new LogInfo() + { + LogLevel = LogLevel.Fatal, + Message = fatal, + Time = Now, + ThreadId = Thread.CurrentThread.ManagedThreadId, + Source = source, + ExceptionType = fatal.GetType().Name + }; + Event?.Invoke(log); + } + + private static string GetLogPath() + { + string newFilePath; + var logDir = string.IsNullOrEmpty(LogDirectory) ? Path.Combine(Environment.CurrentDirectory, "logs") : LogDirectory; + Directory.CreateDirectory(logDir); + string extension = ".log"; + string fileNameNotExt = Now.ToString("yyyyMMdd"); + string fileNamePattern = string.Concat(fileNameNotExt, "(*)", extension); + List filePaths = Directory.GetFiles(logDir, fileNamePattern, SearchOption.TopDirectoryOnly).ToList(); + + if (filePaths.Count > 0) + { + int fileMaxLen = filePaths.Max(d => d.Length); + string lastFilePath = filePaths.Where(d => d.Length == fileMaxLen).OrderByDescending(d => d).FirstOrDefault(); + if (new FileInfo(lastFilePath).Length > 1 * 1024 * 1024) + { + var no = new Regex(@"(?is)(?<=\()(.*)(?=\))").Match(Path.GetFileName(lastFilePath)).Value; + var parse = int.TryParse(no, out int tempno); + var formatno = $"({(parse ? (tempno + 1) : tempno)})"; + var newFileName = String.Concat(fileNameNotExt, formatno, extension); + newFilePath = Path.Combine(logDir, newFileName); + } + else + { + newFilePath = lastFilePath; + } + } + else + { + var newFileName = string.Concat(fileNameNotExt, $"({0})", extension); + newFilePath = Path.Combine(logDir, newFileName); + } + + return newFilePath; + } + + private static void WriteText(string logPath, string logContent) + { + try + { + if (!File.Exists(logPath)) + { + File.CreateText(logPath).Close(); + } + + using (var sw = File.AppendText(logPath)) + { + sw.Write(logContent); + } + } + catch (Exception) + { + // ignored + } + } + } +} \ No newline at end of file diff --git a/DownKyi.Core/Properties/AssemblyInfo.cs b/DownKyi.Core/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e3405cb --- /dev/null +++ b/DownKyi.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("DownKyi.Core")] +[assembly: AssemblyDescription("DownKyi.Core")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("DownKyi")] +[assembly: AssemblyProduct("DownKyi.Core")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("4fde0364-f65b-4812-bfe8-34e886624fbd")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] diff --git a/DownKyi.Core/Settings/AfterDownloadOperation.cs b/DownKyi.Core/Settings/AfterDownloadOperation.cs new file mode 100644 index 0000000..99ac8a1 --- /dev/null +++ b/DownKyi.Core/Settings/AfterDownloadOperation.cs @@ -0,0 +1,10 @@ +namespace DownKyi.Core.Settings +{ + public enum AfterDownloadOperation + { + NONE = 1, + OPEN_FOLDER, + CLOSE_APP, + CLOSE_SYSTEM + } +} diff --git a/DownKyi.Core/Settings/AllowStatus.cs b/DownKyi.Core/Settings/AllowStatus.cs new file mode 100644 index 0000000..9473713 --- /dev/null +++ b/DownKyi.Core/Settings/AllowStatus.cs @@ -0,0 +1,9 @@ +namespace DownKyi.Core.Settings +{ + public enum AllowStatus + { + NONE = 0, + NO, + YES + } +} diff --git a/DownKyi.Core/Settings/DanmakuLayoutAlgorithm.cs b/DownKyi.Core/Settings/DanmakuLayoutAlgorithm.cs new file mode 100644 index 0000000..ed188f6 --- /dev/null +++ b/DownKyi.Core/Settings/DanmakuLayoutAlgorithm.cs @@ -0,0 +1,9 @@ +namespace DownKyi.Core.Settings +{ + public enum DanmakuLayoutAlgorithm + { + NONE = 0, + ASYNC, + SYNC + } +} diff --git a/DownKyi.Core/Settings/DownloadFinishedSort.cs b/DownKyi.Core/Settings/DownloadFinishedSort.cs new file mode 100644 index 0000000..6676737 --- /dev/null +++ b/DownKyi.Core/Settings/DownloadFinishedSort.cs @@ -0,0 +1,8 @@ +namespace DownKyi.Core.Settings +{ + public enum DownloadFinishedSort + { + DOWNLOAD = 0, + NUMBER + } +} diff --git a/DownKyi.Core/Settings/Models/AboutSettings.cs b/DownKyi.Core/Settings/Models/AboutSettings.cs new file mode 100644 index 0000000..7b6a1db --- /dev/null +++ b/DownKyi.Core/Settings/Models/AboutSettings.cs @@ -0,0 +1,11 @@ +namespace DownKyi.Core.Settings.Models +{ + /// + /// 关于 + /// + public class AboutSettings + { + public AllowStatus IsReceiveBetaVersion { get; set; } + public AllowStatus AutoUpdateWhenLaunch { get; set; } + } +} diff --git a/DownKyi.Core/Settings/Models/AppSettings.cs b/DownKyi.Core/Settings/Models/AppSettings.cs new file mode 100644 index 0000000..6285a91 --- /dev/null +++ b/DownKyi.Core/Settings/Models/AppSettings.cs @@ -0,0 +1,12 @@ +namespace DownKyi.Core.Settings.Models +{ + public class AppSettings + { + public BasicSettings Basic { get; set; } = new BasicSettings(); + public NetworkSettings Network { get; set; } = new NetworkSettings(); + public VideoSettings Video { get; set; } = new VideoSettings(); + public DanmakuSettings Danmaku { get; set; } = new DanmakuSettings(); + public AboutSettings About { get; set; } = new AboutSettings(); + public UserInfoSettings UserInfo { get; set; } + } +} diff --git a/DownKyi.Core/Settings/Models/BasicSettings.cs b/DownKyi.Core/Settings/Models/BasicSettings.cs new file mode 100644 index 0000000..46a53e0 --- /dev/null +++ b/DownKyi.Core/Settings/Models/BasicSettings.cs @@ -0,0 +1,14 @@ +namespace DownKyi.Core.Settings.Models +{ + /// + /// 基本 + /// + public class BasicSettings + { + public AfterDownloadOperation AfterDownload { get; set; } + public AllowStatus IsListenClipboard { get; set; } + public AllowStatus IsAutoParseVideo { get; set; } + public ParseScope ParseScope { get; set; } + public DownloadFinishedSort DownloadFinishedSort { get; set; } + } +} diff --git a/DownKyi.Core/Settings/Models/DanmakuSettings.cs b/DownKyi.Core/Settings/Models/DanmakuSettings.cs new file mode 100644 index 0000000..64bc828 --- /dev/null +++ b/DownKyi.Core/Settings/Models/DanmakuSettings.cs @@ -0,0 +1,19 @@ +namespace DownKyi.Core.Settings.Models +{ + /// + /// 弹幕 + /// + public class DanmakuSettings + { + public AllowStatus DanmakuTopFilter { get; set; } + public AllowStatus DanmakuBottomFilter { get; set; } + public AllowStatus DanmakuScrollFilter { get; set; } + public AllowStatus IsCustomDanmakuResolution { get; set; } + public int DanmakuScreenWidth { get; set; } + public int DanmakuScreenHeight { get; set; } + public string DanmakuFontName { get; set; } + public int DanmakuFontSize { get; set; } + public int DanmakuLineCount { get; set; } + public DanmakuLayoutAlgorithm DanmakuLayoutAlgorithm { get; set; } + } +} diff --git a/DownKyi.Core/Settings/Models/NetworkSettings.cs b/DownKyi.Core/Settings/Models/NetworkSettings.cs new file mode 100644 index 0000000..cdfcb5f --- /dev/null +++ b/DownKyi.Core/Settings/Models/NetworkSettings.cs @@ -0,0 +1,23 @@ +using DownKyi.Core.Aria2cNet.Server; + +namespace DownKyi.Core.Settings.Models +{ + /// + /// 网络 + /// + public class NetworkSettings + { + public AllowStatus IsLiftingOfRegion { get; set; } + public int AriaListenPort { get; set; } + public AriaConfigLogLevel AriaLogLevel { get; set; } + public int AriaMaxConcurrentDownloads { get; set; } + public int AriaSplit { get; set; } + public int AriaMaxOverallDownloadLimit { get; set; } + public int AriaMaxDownloadLimit { get; set; } + public AriaConfigFileAllocation AriaFileAllocation { get; set; } + + public AllowStatus IsAriaHttpProxy { get; set; } + public string AriaHttpProxy { get; set; } + public int AriaHttpProxyListenPort { get; set; } + } +} diff --git a/DownKyi.Core/Settings/Models/UserInfoSettings.cs b/DownKyi.Core/Settings/Models/UserInfoSettings.cs new file mode 100644 index 0000000..774b7ec --- /dev/null +++ b/DownKyi.Core/Settings/Models/UserInfoSettings.cs @@ -0,0 +1,10 @@ +namespace DownKyi.Core.Settings.Models +{ + public class UserInfoSettings + { + public long Mid { get; set; } + public string Name { get; set; } + public bool IsLogin { get; set; } // 是否登录 + public bool IsVip { get; set; } // 是否为大会员,未登录时为false + } +} diff --git a/DownKyi.Core/Settings/Models/VideoSettings.cs b/DownKyi.Core/Settings/Models/VideoSettings.cs new file mode 100644 index 0000000..0863423 --- /dev/null +++ b/DownKyi.Core/Settings/Models/VideoSettings.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.Settings.Models +{ + /// + /// 视频 + /// + public class VideoSettings + { + public VideoCodecs VideoCodecs { get; set; } + public int Quality { get; set; } + public int AudioQuality { get; set; } + public AllowStatus IsAddOrder { get; set; } + public AllowStatus IsTranscodingFlvToMp4 { get; set; } + public string SaveVideoRootPath { get; set; } + public List HistoryVideoRootPaths { get; set; } + public AllowStatus IsUseSaveVideoRootPath { get; set; } + public AllowStatus IsCreateFolderForMedia { get; set; } + public AllowStatus IsDownloadDanmaku { get; set; } + public AllowStatus IsDownloadCover { get; set; } + } +} diff --git a/DownKyi.Core/Settings/ParseScope.cs b/DownKyi.Core/Settings/ParseScope.cs new file mode 100644 index 0000000..b028eac --- /dev/null +++ b/DownKyi.Core/Settings/ParseScope.cs @@ -0,0 +1,10 @@ +namespace DownKyi.Core.Settings +{ + public enum ParseScope + { + NONE = 1, + SELECTED_ITEM, + CURRENT_SECTION, + ALL + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.About.cs b/DownKyi.Core/Settings/SettingsManager.About.cs new file mode 100644 index 0000000..b4a2f75 --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.About.cs @@ -0,0 +1,66 @@ +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + // 是否接收测试版更新 + private readonly AllowStatus isReceiveBetaVersion = AllowStatus.NO; + + // 是否在启动时自动检查更新 + private readonly AllowStatus autoUpdateWhenLaunch = AllowStatus.YES; + + /// + /// 获取是否接收测试版更新 + /// + /// + public AllowStatus IsReceiveBetaVersion() + { + appSettings = GetSettings(); + if (appSettings.About.IsReceiveBetaVersion == 0) + { + // 第一次获取,先设置默认值 + IsReceiveBetaVersion(isReceiveBetaVersion); + return isReceiveBetaVersion; + } + return appSettings.About.IsReceiveBetaVersion; + } + + /// + /// 设置是否接收测试版更新 + /// + /// + /// + public bool IsReceiveBetaVersion(AllowStatus isReceiveBetaVersion) + { + appSettings.About.IsReceiveBetaVersion = isReceiveBetaVersion; + return SetSettings(); + } + + /// + /// 获取是否允许启动时检查更新 + /// + /// + public AllowStatus GetAutoUpdateWhenLaunch() + { + appSettings = GetSettings(); + if (appSettings.About.AutoUpdateWhenLaunch == 0) + { + // 第一次获取,先设置默认值 + SetAutoUpdateWhenLaunch(autoUpdateWhenLaunch); + return autoUpdateWhenLaunch; + } + return appSettings.About.AutoUpdateWhenLaunch; + } + + /// + /// 设置是否允许启动时检查更新 + /// + /// + /// + public bool SetAutoUpdateWhenLaunch(AllowStatus autoUpdateWhenLaunch) + { + appSettings.About.AutoUpdateWhenLaunch = autoUpdateWhenLaunch; + return SetSettings(); + } + + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.Basic.cs b/DownKyi.Core/Settings/SettingsManager.Basic.cs new file mode 100644 index 0000000..d5f93e7 --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.Basic.cs @@ -0,0 +1,156 @@ +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + // 默认下载完成后的操作 + private readonly AfterDownloadOperation afterDownload = AfterDownloadOperation.NONE; + + // 是否监听剪贴板 + private readonly AllowStatus isListenClipboard = AllowStatus.YES; + + // 视频详情页面是否自动解析 + private readonly AllowStatus isAutoParseVideo = AllowStatus.NO; + + // 默认的视频解析项 + private readonly ParseScope parseScope = ParseScope.NONE; + + // 下载完成列表排序 + private readonly DownloadFinishedSort finishedSort = DownloadFinishedSort.DOWNLOAD; + + /// + /// 获取下载完成后的操作 + /// + /// + public AfterDownloadOperation GetAfterDownloadOperation() + { + appSettings = GetSettings(); + if (appSettings.Basic.AfterDownload == 0) + { + // 第一次获取,先设置默认值 + SetAfterDownloadOperation(afterDownload); + return afterDownload; + } + return appSettings.Basic.AfterDownload; + } + + /// + /// 设置下载完成后的操作 + /// + /// + /// + public bool SetAfterDownloadOperation(AfterDownloadOperation afterDownload) + { + appSettings.Basic.AfterDownload = afterDownload; + return SetSettings(); + } + + /// + /// 是否监听剪贴板 + /// + /// + public AllowStatus IsListenClipboard() + { + appSettings = GetSettings(); + if (appSettings.Basic.IsListenClipboard == 0) + { + // 第一次获取,先设置默认值 + IsListenClipboard(isListenClipboard); + return isListenClipboard; + } + return appSettings.Basic.IsListenClipboard; + } + + /// + /// 是否监听剪贴板 + /// + /// + /// + public bool IsListenClipboard(AllowStatus isListen) + { + appSettings.Basic.IsListenClipboard = isListen; + return SetSettings(); + } + + /// + /// 视频详情页面是否自动解析 + /// + /// + public AllowStatus IsAutoParseVideo() + { + appSettings = GetSettings(); + if (appSettings.Basic.IsAutoParseVideo == 0) + { + // 第一次获取,先设置默认值 + IsAutoParseVideo(isAutoParseVideo); + return isAutoParseVideo; + } + return appSettings.Basic.IsAutoParseVideo; + } + + /// + /// 视频详情页面是否自动解析 + /// + /// + /// + public bool IsAutoParseVideo(AllowStatus IsAuto) + { + appSettings.Basic.IsAutoParseVideo = IsAuto; + return SetSettings(); + } + + /// + /// 获取视频解析项 + /// + /// + public ParseScope GetParseScope() + { + appSettings = GetSettings(); + if (appSettings.Basic.ParseScope == 0) + { + // 第一次获取,先设置默认值 + SetParseScope(parseScope); + return parseScope; + } + return appSettings.Basic.ParseScope; + } + + /// + /// 设置视频解析项 + /// + /// + /// + public bool SetParseScope(ParseScope parseScope) + { + appSettings.Basic.ParseScope = parseScope; + return SetSettings(); + } + + /// + /// 获取下载完成列表排序 + /// + /// + public DownloadFinishedSort GetDownloadFinishedSort() + { + appSettings = GetSettings(); + if (appSettings.Basic.DownloadFinishedSort == 0) + { + // 第一次获取,先设置默认值 + SetDownloadFinishedSort(finishedSort); + return finishedSort; + } + return appSettings.Basic.DownloadFinishedSort; + } + + /// + /// 设置下载完成列表排序 + /// + /// + /// + public bool SetDownloadFinishedSort(DownloadFinishedSort finishedSort) + { + appSettings.Basic.DownloadFinishedSort = finishedSort; + return SetSettings(); + } + + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.Danmaku.cs b/DownKyi.Core/Settings/SettingsManager.Danmaku.cs new file mode 100644 index 0000000..34f2b95 --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.Danmaku.cs @@ -0,0 +1,307 @@ +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + // 是否屏蔽顶部弹幕 + private readonly AllowStatus danmakuTopFilter = AllowStatus.NO; + + // 是否屏蔽底部弹幕 + private readonly AllowStatus danmakuBottomFilter = AllowStatus.NO; + + // 是否屏蔽滚动弹幕 + private readonly AllowStatus danmakuScrollFilter = AllowStatus.NO; + + // 是否自定义分辨率 + private readonly AllowStatus isCustomDanmakuResolution = AllowStatus.NO; + + // 分辨率-宽 + private readonly int danmakuScreenWidth = 1920; + + // 分辨率-高 + private readonly int danmakuScreenHeight = 1080; + + // 弹幕字体 + private readonly string danmakuFontName = "黑体"; + + // 弹幕字体大小 + private readonly int danmakuFontSize = 50; + + // 弹幕限制行数 + private readonly int danmakuLineCount = 0; + + // 弹幕布局算法 + private readonly DanmakuLayoutAlgorithm danmakuLayoutAlgorithm = DanmakuLayoutAlgorithm.SYNC; + + + /// + /// 获取是否屏蔽顶部弹幕 + /// + /// + public AllowStatus GetDanmakuTopFilter() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuTopFilter == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuTopFilter(danmakuTopFilter); + return danmakuTopFilter; + } + return appSettings.Danmaku.DanmakuTopFilter; + } + + /// + /// 设置是否屏蔽顶部弹幕 + /// + /// + /// + public bool SetDanmakuTopFilter(AllowStatus danmakuFilter) + { + appSettings.Danmaku.DanmakuTopFilter = danmakuFilter; + return SetSettings(); + } + + /// + /// 获取是否屏蔽底部弹幕 + /// + /// + public AllowStatus GetDanmakuBottomFilter() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuBottomFilter == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuBottomFilter(danmakuBottomFilter); + return danmakuBottomFilter; + } + return appSettings.Danmaku.DanmakuBottomFilter; + } + + /// + /// 设置是否屏蔽底部弹幕 + /// + /// + /// + public bool SetDanmakuBottomFilter(AllowStatus danmakuFilter) + { + appSettings.Danmaku.DanmakuBottomFilter = danmakuFilter; + return SetSettings(); + } + + /// + /// 获取是否屏蔽滚动弹幕 + /// + /// + public AllowStatus GetDanmakuScrollFilter() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuScrollFilter == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuScrollFilter(danmakuScrollFilter); + return danmakuScrollFilter; + } + return appSettings.Danmaku.DanmakuScrollFilter; + } + + /// + /// 设置是否屏蔽滚动弹幕 + /// + /// + /// + public bool SetDanmakuScrollFilter(AllowStatus danmakuFilter) + { + appSettings.Danmaku.DanmakuScrollFilter = danmakuFilter; + return SetSettings(); + } + + /// + /// 获取是否自定义分辨率 + /// + /// + public AllowStatus IsCustomDanmakuResolution() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.IsCustomDanmakuResolution == 0) + { + // 第一次获取,先设置默认值 + IsCustomDanmakuResolution(isCustomDanmakuResolution); + return isCustomDanmakuResolution; + } + return appSettings.Danmaku.IsCustomDanmakuResolution; + } + + /// + /// 设置是否自定义分辨率 + /// + /// + /// + public bool IsCustomDanmakuResolution(AllowStatus isCustomResolution) + { + appSettings.Danmaku.IsCustomDanmakuResolution = isCustomResolution; + return SetSettings(); + } + + /// + /// 获取分辨率-宽 + /// + /// + public int GetDanmakuScreenWidth() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuScreenWidth == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuScreenWidth(danmakuScreenWidth); + return danmakuScreenWidth; + } + return appSettings.Danmaku.DanmakuScreenWidth; + } + + /// + /// 设置分辨率-宽 + /// + /// + /// + public bool SetDanmakuScreenWidth(int screenWidth) + { + appSettings.Danmaku.DanmakuScreenWidth = screenWidth; + return SetSettings(); + } + + /// + /// 获取分辨率-高 + /// + /// + public int GetDanmakuScreenHeight() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuScreenHeight == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuScreenHeight(danmakuScreenHeight); + return danmakuScreenHeight; + } + return appSettings.Danmaku.DanmakuScreenHeight; + } + + /// + /// 设置分辨率-高 + /// + /// + /// + public bool SetDanmakuScreenHeight(int screenHeight) + { + appSettings.Danmaku.DanmakuScreenHeight = screenHeight; + return SetSettings(); + } + + /// + /// 获取弹幕字体 + /// + /// + public string GetDanmakuFontName() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuFontName == null) + { + // 第一次获取,先设置默认值 + SetDanmakuFontName(danmakuFontName); + return danmakuFontName; + } + return appSettings.Danmaku.DanmakuFontName; + } + + /// + /// 设置弹幕字体 + /// + /// + /// + public bool SetDanmakuFontName(string danmakuFontName) + { + appSettings.Danmaku.DanmakuFontName = danmakuFontName; + return SetSettings(); + } + + /// + /// 获取弹幕字体大小 + /// + /// + public int GetDanmakuFontSize() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuFontSize == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuFontSize(danmakuFontSize); + return danmakuFontSize; + } + return appSettings.Danmaku.DanmakuFontSize; + } + + /// + /// 设置弹幕字体大小 + /// + /// + /// + public bool SetDanmakuFontSize(int danmakuFontSize) + { + appSettings.Danmaku.DanmakuFontSize = danmakuFontSize; + return SetSettings(); + } + + /// + /// 获取弹幕限制行数 + /// + /// + public int GetDanmakuLineCount() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuLineCount == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuLineCount(danmakuLineCount); + return danmakuLineCount; + } + return appSettings.Danmaku.DanmakuLineCount; + } + + /// + /// 设置弹幕限制行数 + /// + /// + /// + public bool SetDanmakuLineCount(int danmakuLineCount) + { + appSettings.Danmaku.DanmakuLineCount = danmakuLineCount; + return SetSettings(); + } + + /// + /// 获取弹幕布局算法 + /// + /// + public DanmakuLayoutAlgorithm GetDanmakuLayoutAlgorithm() + { + appSettings = GetSettings(); + if (appSettings.Danmaku.DanmakuLayoutAlgorithm == 0) + { + // 第一次获取,先设置默认值 + SetDanmakuLayoutAlgorithm(danmakuLayoutAlgorithm); + return danmakuLayoutAlgorithm; + } + return appSettings.Danmaku.DanmakuLayoutAlgorithm; + } + + /// + /// 设置弹幕布局算法 + /// + /// + /// + public bool SetDanmakuLayoutAlgorithm(DanmakuLayoutAlgorithm danmakuLayoutAlgorithm) + { + appSettings.Danmaku.DanmakuLayoutAlgorithm = danmakuLayoutAlgorithm; + return SetSettings(); + } + + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.Network.cs b/DownKyi.Core/Settings/SettingsManager.Network.cs new file mode 100644 index 0000000..95675e2 --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.Network.cs @@ -0,0 +1,334 @@ +using DownKyi.Core.Aria2cNet.Server; + +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + // 是否开启解除地区限制 + private readonly AllowStatus isLiftingOfRegion = AllowStatus.YES; + + // Aria服务器端口号 + private readonly int ariaListenPort = 6800; + + // Aria日志等级 + private readonly AriaConfigLogLevel ariaLogLevel = AriaConfigLogLevel.INFO; + + // Aria最大同时下载数(任务数) + private readonly int ariaMaxConcurrentDownloads = 3; + + // Aria单文件最大线程数 + private readonly int ariaSplit = 5; + + // Aria下载速度限制 + private readonly int ariaMaxOverallDownloadLimit = 0; + + // Aria下载单文件速度限制 + private readonly int ariaMaxDownloadLimit = 0; + + // Aria文件预分配 + private readonly AriaConfigFileAllocation ariaFileAllocation = AriaConfigFileAllocation.PREALLOC; + + // Aria HttpProxy代理 + private readonly AllowStatus isAriaHttpProxy = AllowStatus.NO; + private readonly string ariaHttpProxy = ""; + private readonly int ariaHttpProxyListenPort = 0; + + /// + /// 获取是否解除地区限制 + /// + /// + public AllowStatus IsLiftingOfRegion() + { + appSettings = GetSettings(); + if (appSettings.Network.IsLiftingOfRegion == 0) + { + // 第一次获取,先设置默认值 + IsLiftingOfRegion(isLiftingOfRegion); + return isLiftingOfRegion; + } + return appSettings.Network.IsLiftingOfRegion; + } + + /// + /// 设置是否解除地区限制 + /// + /// + /// + public bool IsLiftingOfRegion(AllowStatus isLiftingOfRegion) + { + appSettings.Network.IsLiftingOfRegion = isLiftingOfRegion; + return SetSettings(); + } + + /// + /// 获取Aria服务器的端口号 + /// + /// + public int GetAriaListenPort() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaListenPort == 0) + { + // 第一次获取,先设置默认值 + SetAriaListenPort(ariaListenPort); + return ariaListenPort; + } + return appSettings.Network.AriaListenPort; + } + + /// + /// 设置Aria服务器的端口号 + /// + /// + /// + public bool SetAriaListenPort(int ariaListenPort) + { + appSettings.Network.AriaListenPort = ariaListenPort; + return SetSettings(); + } + + /// + /// 获取Aria日志等级 + /// + /// + public AriaConfigLogLevel GetAriaLogLevel() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaLogLevel == 0) + { + // 第一次获取,先设置默认值 + SetAriaLogLevel(ariaLogLevel); + return ariaLogLevel; + } + return appSettings.Network.AriaLogLevel; + } + + /// + /// 设置Aria日志等级 + /// + /// + /// + public bool SetAriaLogLevel(AriaConfigLogLevel ariaLogLevel) + { + appSettings.Network.AriaLogLevel = ariaLogLevel; + return SetSettings(); + } + + /// + /// 获取Aria最大同时下载数(任务数) + /// + /// + public int GetAriaMaxConcurrentDownloads() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaMaxConcurrentDownloads == 0) + { + // 第一次获取,先设置默认值 + SetAriaMaxConcurrentDownloads(ariaMaxConcurrentDownloads); + return ariaMaxConcurrentDownloads; + } + return appSettings.Network.AriaMaxConcurrentDownloads; + } + + /// + /// 设置Aria最大同时下载数(任务数) + /// + /// + /// + public bool SetAriaMaxConcurrentDownloads(int ariaMaxConcurrentDownloads) + { + appSettings.Network.AriaMaxConcurrentDownloads = ariaMaxConcurrentDownloads; + return SetSettings(); + } + + /// + /// 获取Aria单文件最大线程数 + /// + /// + public int GetAriaSplit() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaSplit == 0) + { + // 第一次获取,先设置默认值 + SetAriaSplit(ariaSplit); + return ariaSplit; + } + return appSettings.Network.AriaSplit; + } + + /// + /// 设置Aria单文件最大线程数 + /// + /// + /// + public bool SetAriaSplit(int ariaSplit) + { + appSettings.Network.AriaSplit = ariaSplit; + return SetSettings(); + } + + /// + /// 获取Aria下载速度限制 + /// + /// + public int GetAriaMaxOverallDownloadLimit() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaMaxOverallDownloadLimit == 0) + { + // 第一次获取,先设置默认值 + SetAriaMaxOverallDownloadLimit(ariaMaxOverallDownloadLimit); + return ariaMaxOverallDownloadLimit; + } + return appSettings.Network.AriaMaxOverallDownloadLimit; + } + + /// + /// 设置Aria下载速度限制 + /// + /// + /// + public bool SetAriaMaxOverallDownloadLimit(int ariaMaxOverallDownloadLimit) + { + appSettings.Network.AriaMaxOverallDownloadLimit = ariaMaxOverallDownloadLimit; + return SetSettings(); + } + + /// + /// 获取Aria下载单文件速度限制 + /// + /// + public int GetAriaMaxDownloadLimit() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaMaxDownloadLimit == 0) + { + // 第一次获取,先设置默认值 + SetAriaMaxDownloadLimit(ariaMaxDownloadLimit); + return ariaMaxDownloadLimit; + } + return appSettings.Network.AriaMaxDownloadLimit; + } + + /// + /// 设置Aria下载单文件速度限制 + /// + /// + /// + public bool SetAriaMaxDownloadLimit(int ariaMaxDownloadLimit) + { + appSettings.Network.AriaMaxDownloadLimit = ariaMaxDownloadLimit; + return SetSettings(); + } + + /// + /// 获取Aria文件预分配 + /// + /// + public AriaConfigFileAllocation GetAriaFileAllocation() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaFileAllocation == 0) + { + // 第一次获取,先设置默认值 + SetAriaFileAllocation(ariaFileAllocation); + return ariaFileAllocation; + } + return appSettings.Network.AriaFileAllocation; + } + + /// + /// 设置Aria文件预分配 + /// + /// + /// + public bool SetAriaFileAllocation(AriaConfigFileAllocation ariaFileAllocation) + { + appSettings.Network.AriaFileAllocation = ariaFileAllocation; + return SetSettings(); + } + + /// + /// 获取是否开启Aria http代理 + /// + /// + public AllowStatus IsAriaHttpProxy() + { + appSettings = GetSettings(); + if (appSettings.Network.IsAriaHttpProxy == 0) + { + // 第一次获取,先设置默认值 + IsAriaHttpProxy(isAriaHttpProxy); + return isAriaHttpProxy; + } + return appSettings.Network.IsAriaHttpProxy; + } + + /// + /// 设置是否开启Aria http代理 + /// + /// + /// + public bool IsAriaHttpProxy(AllowStatus isAriaHttpProxy) + { + appSettings.Network.IsAriaHttpProxy = isAriaHttpProxy; + return SetSettings(); + } + + /// + /// 获取Aria的http代理的地址 + /// + /// + public string GetAriaHttpProxy() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaHttpProxy == null) + { + // 第一次获取,先设置默认值 + SetAriaHttpProxy(ariaHttpProxy); + return ariaHttpProxy; + } + return appSettings.Network.AriaHttpProxy; + } + + /// + /// 设置Aria的http代理的地址 + /// + /// + /// + public bool SetAriaHttpProxy(string ariaHttpProxy) + { + appSettings.Network.AriaHttpProxy = ariaHttpProxy; + return SetSettings(); + } + + /// + /// 获取Aria的http代理的端口 + /// + /// + public int GetAriaHttpProxyListenPort() + { + appSettings = GetSettings(); + if (appSettings.Network.AriaHttpProxyListenPort == 0) + { + // 第一次获取,先设置默认值 + SetAriaHttpProxyListenPort(ariaHttpProxyListenPort); + return ariaHttpProxyListenPort; + } + return appSettings.Network.AriaHttpProxyListenPort; + } + + /// + /// 设置Aria的http代理的端口 + /// + /// + /// + public bool SetAriaHttpProxyListenPort(int ariaHttpProxyListenPort) + { + appSettings.Network.AriaHttpProxyListenPort = ariaHttpProxyListenPort; + return SetSettings(); + } + + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.UserInfo.cs b/DownKyi.Core/Settings/SettingsManager.UserInfo.cs new file mode 100644 index 0000000..fda9352 --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.UserInfo.cs @@ -0,0 +1,44 @@ +using DownKyi.Core.Settings.Models; + +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + // 登录用户的mid + private readonly UserInfoSettings userInfo = new UserInfoSettings + { + Mid = -1, + Name = "", + IsLogin = false, + IsVip = false + }; + + /// + /// 获取登录用户信息 + /// + /// + public UserInfoSettings GetUserInfo() + { + appSettings = GetSettings(); + if (appSettings.UserInfo == null) + { + // 第一次获取,先设置默认值 + SetUserInfo(userInfo); + return userInfo; + } + return appSettings.UserInfo; + } + + /// + /// 设置中保存登录用户的信息,在index刷新用户状态时使用 + /// + /// + /// + public bool SetUserInfo(UserInfoSettings userInfo) + { + appSettings.UserInfo = userInfo; + return SetSettings(); + } + + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.Video.cs b/DownKyi.Core/Settings/SettingsManager.Video.cs new file mode 100644 index 0000000..1b6700c --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.Video.cs @@ -0,0 +1,340 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + // 设置优先下载的视频编码 + private readonly VideoCodecs videoCodecs = VideoCodecs.AVC; + + // 设置优先下载画质 + private readonly int quality = 120; + + // 设置优先下载音质 + private readonly int audioQuality = 30280; + + // 是否在下载的视频前增加序号 + private readonly AllowStatus isAddOrder = AllowStatus.NO; + + // 是否下载flv视频后转码为mp4 + private readonly AllowStatus isTranscodingFlvToMp4 = AllowStatus.YES; + + // 默认下载目录 + private readonly string saveVideoRootPath = Path.Combine(Environment.CurrentDirectory, "Media"); + + // 历史下载目录 + private readonly List historyVideoRootPaths = new List(); + + // 是否使用默认下载目录,如果是,则每次点击下载选中项时不再询问下载目录 + private readonly AllowStatus isUseSaveVideoRootPath = AllowStatus.NO; + + // 是否为不同视频分别创建文件夹 + private readonly AllowStatus isCreateFolderForMedia = AllowStatus.YES; + + // 是否在下载视频的同时下载弹幕 + private readonly AllowStatus isDownloadDanmaku = AllowStatus.YES; + + // 是否在下载视频的同时下载封面 + private readonly AllowStatus isDownloadCover = AllowStatus.YES; + + /// + /// 获取优先下载的视频编码 + /// + /// + public VideoCodecs GetVideoCodecs() + { + appSettings = GetSettings(); + if (appSettings.Video.VideoCodecs == 0) + { + // 第一次获取,先设置默认值 + SetVideoCodecs(videoCodecs); + return videoCodecs; + } + return appSettings.Video.VideoCodecs; + } + + /// + /// 设置优先下载的视频编码 + /// + /// + /// + public bool SetVideoCodecs(VideoCodecs videoCodecs) + { + appSettings.Video.VideoCodecs = videoCodecs; + return SetSettings(); + } + + /// + /// 获取优先下载画质 + /// + /// + public int GetQuality() + { + appSettings = GetSettings(); + if (appSettings.Video.Quality == 0) + { + // 第一次获取,先设置默认值 + SetQuality(quality); + return quality; + } + return appSettings.Video.Quality; + } + + /// + /// 设置优先下载画质 + /// + /// + /// + public bool SetQuality(int quality) + { + appSettings.Video.Quality = quality; + return SetSettings(); + } + + /// + /// 获取优先下载音质 + /// + /// + public int GetAudioQuality() + { + appSettings = GetSettings(); + if (appSettings.Video.AudioQuality == 0) + { + // 第一次获取,先设置默认值 + SetAudioQuality(audioQuality); + return audioQuality; + } + return appSettings.Video.AudioQuality; + } + + /// + /// 设置优先下载音质 + /// + /// + /// + public bool SetAudioQuality(int quality) + { + appSettings.Video.AudioQuality = quality; + return SetSettings(); + } + + /// + /// 获取是否给视频增加序号 + /// + /// + public AllowStatus IsAddOrder() + { + appSettings = GetSettings(); + if (appSettings.Video.IsAddOrder == 0) + { + // 第一次获取,先设置默认值 + IsAddOrder(isAddOrder); + return isAddOrder; + } + return appSettings.Video.IsAddOrder; + } + + /// + /// 设置是否给视频增加序号 + /// + /// + /// + public bool IsAddOrder(AllowStatus isAddOrder) + { + appSettings.Video.IsAddOrder = isAddOrder; + return SetSettings(); + } + + /// + /// 获取是否下载flv视频后转码为mp4 + /// + /// + public AllowStatus IsTranscodingFlvToMp4() + { + appSettings = GetSettings(); + if (appSettings.Video.IsTranscodingFlvToMp4 == 0) + { + // 第一次获取,先设置默认值 + IsTranscodingFlvToMp4(isTranscodingFlvToMp4); + return isTranscodingFlvToMp4; + } + return appSettings.Video.IsTranscodingFlvToMp4; + } + + /// + /// 设置是否下载flv视频后转码为mp4 + /// + /// + /// + public bool IsTranscodingFlvToMp4(AllowStatus isTranscodingFlvToMp4) + { + appSettings.Video.IsTranscodingFlvToMp4 = isTranscodingFlvToMp4; + return SetSettings(); + } + + /// + /// 获取下载目录 + /// + /// + public string GetSaveVideoRootPath() + { + appSettings = GetSettings(); + if (appSettings.Video.SaveVideoRootPath == null) + { + // 第一次获取,先设置默认值 + SetSaveVideoRootPath(saveVideoRootPath); + return saveVideoRootPath; + } + return appSettings.Video.SaveVideoRootPath; + } + + /// + /// 设置下载目录 + /// + /// + /// + public bool SetSaveVideoRootPath(string path) + { + appSettings.Video.SaveVideoRootPath = path; + return SetSettings(); + } + + /// + /// 获取历史下载目录 + /// + /// + public List GetHistoryVideoRootPaths() + { + appSettings = GetSettings(); + if (appSettings.Video.HistoryVideoRootPaths == null) + { + // 第一次获取,先设置默认值 + SetHistoryVideoRootPaths(historyVideoRootPaths); + return historyVideoRootPaths; + } + return appSettings.Video.HistoryVideoRootPaths; + } + + /// + /// 设置历史下载目录 + /// + /// + /// + public bool SetHistoryVideoRootPaths(List historyPaths) + { + appSettings.Video.HistoryVideoRootPaths = historyPaths; + return SetSettings(); + } + + /// + /// 获取是否使用默认下载目录 + /// + /// + public AllowStatus IsUseSaveVideoRootPath() + { + appSettings = GetSettings(); + if (appSettings.Video.IsUseSaveVideoRootPath == 0) + { + // 第一次获取,先设置默认值 + IsUseSaveVideoRootPath(isUseSaveVideoRootPath); + return isUseSaveVideoRootPath; + } + return appSettings.Video.IsUseSaveVideoRootPath; + } + + /// + /// 设置是否使用默认下载目录 + /// + /// + /// + public bool IsUseSaveVideoRootPath(AllowStatus isUseSaveVideoRootPath) + { + appSettings.Video.IsUseSaveVideoRootPath = isUseSaveVideoRootPath; + return SetSettings(); + } + + /// + /// 获取是否为不同视频分别创建文件夹 + /// + /// + public AllowStatus IsCreateFolderForMedia() + { + appSettings = GetSettings(); + if (appSettings.Video.IsCreateFolderForMedia == 0) + { + // 第一次获取,先设置默认值 + IsCreateFolderForMedia(isCreateFolderForMedia); + return isCreateFolderForMedia; + } + return appSettings.Video.IsCreateFolderForMedia; + } + + /// + /// 设置是否为不同视频分别创建文件夹 + /// + /// + /// + public bool IsCreateFolderForMedia(AllowStatus isCreateFolderForMedia) + { + appSettings.Video.IsCreateFolderForMedia = isCreateFolderForMedia; + return SetSettings(); + } + + /// + /// 获取是否在下载视频的同时下载弹幕 + /// + /// + public AllowStatus IsDownloadDanmaku() + { + appSettings = GetSettings(); + if (appSettings.Video.IsDownloadDanmaku == 0) + { + // 第一次获取,先设置默认值 + IsDownloadDanmaku(isDownloadDanmaku); + return isDownloadDanmaku; + } + return appSettings.Video.IsDownloadDanmaku; + } + + /// + /// 设置是否在下载视频的同时下载弹幕 + /// + /// + /// + public bool IsDownloadDanmaku(AllowStatus isDownloadDanmaku) + { + appSettings.Video.IsDownloadDanmaku = isDownloadDanmaku; + return SetSettings(); + } + + /// + /// 获取是否在下载视频的同时下载封面 + /// + /// + public AllowStatus IsDownloadCover() + { + appSettings = GetSettings(); + if (appSettings.Video.IsDownloadCover == 0) + { + // 第一次获取,先设置默认值 + IsDownloadCover(isDownloadCover); + return isDownloadCover; + } + return appSettings.Video.IsDownloadCover; + } + + /// + /// 设置是否在下载视频的同时下载封面 + /// + /// + /// + public bool IsDownloadCover(AllowStatus isDownloadCover) + { + appSettings.Video.IsDownloadCover = isDownloadCover; + return SetSettings(); + } + + } +} diff --git a/DownKyi.Core/Settings/SettingsManager.cs b/DownKyi.Core/Settings/SettingsManager.cs new file mode 100644 index 0000000..b511e84 --- /dev/null +++ b/DownKyi.Core/Settings/SettingsManager.cs @@ -0,0 +1,81 @@ +using DownKyi.Core.Settings.Models; +using Newtonsoft.Json; +using System; +using System.IO; + +namespace DownKyi.Core.Settings +{ + public partial class SettingsManager + { + private static SettingsManager instance; + + /// + /// 获取SettingsManager实例 + /// + /// + public static SettingsManager GetInstance() + { + if (instance == null) + { + instance = new SettingsManager(); + } + return instance; + } + + /// + /// 隐藏Settings()方法,必须使用单例模式 + /// + private SettingsManager() + { + appSettings = GetSettings(); + } + + // 内存中保存一份配置 + private AppSettings appSettings; + + // 设置的配置文件 + private readonly string settingsName = Storage.StorageManager.GetSettings(); + + /// + /// 获取AppSettingsModel + /// + /// + private AppSettings GetSettings() + { + try + { + StreamReader streamReader = File.OpenText(settingsName); + string jsonWordTemplate = streamReader.ReadToEnd(); + streamReader.Close(); + + return JsonConvert.DeserializeObject(jsonWordTemplate); + } + catch (Exception e) + { + Logging.LogManager.Error(e); + return new AppSettings(); + } + } + + /// + /// 设置AppSettingsModel + /// + /// + private bool SetSettings() + { + string json = JsonConvert.SerializeObject(appSettings, Formatting.Indented); + + try + { + File.WriteAllText(settingsName, json); + return true; + } + catch (Exception e) + { + Logging.LogManager.Error(e); + return false; + } + } + + } +} diff --git a/DownKyi.Core/Settings/VideoCodecs.cs b/DownKyi.Core/Settings/VideoCodecs.cs new file mode 100644 index 0000000..4694aa0 --- /dev/null +++ b/DownKyi.Core/Settings/VideoCodecs.cs @@ -0,0 +1,9 @@ +namespace DownKyi.Core.Settings +{ + public enum VideoCodecs + { + NONE = 0, + AVC, + HEVC + } +} diff --git a/DownKyi.Core/Storage/Constant.cs b/DownKyi.Core/Storage/Constant.cs new file mode 100644 index 0000000..2fe9aa4 --- /dev/null +++ b/DownKyi.Core/Storage/Constant.cs @@ -0,0 +1,65 @@ +using System; + +namespace DownKyi.Core.Storage +{ + /// + /// 存储到本地时使用的一些常量 + /// + internal static class Constant + { + // 根目录 + private static string Root { get; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/Downkyi"; + + // 日志 + public static string Logs { get; } = $"{Root}/Logs"; + + // 数据库 + public static string Database { get; } = $"{Root}/Storage"; + + // 历史(搜索、下载) (加密) + public static string History { get; } = $"{Database}/History.db"; + + // 配置 + public static string Config { get; } = $"{Root}/Config"; + + // 设置 + public static string Settings { get; } = $"{Config}/Settings.json"; + + // 登录cookies + public static string Login { get; } = $"{Config}/Login"; + + // Bilibili + private static string Bilibili { get; } = $"{Root}/Bilibili"; + + // 弹幕 + public static string Danmaku { get; } = $"{Bilibili}/Danmakus"; + + // 字幕 + public static string Subtitle { get; } = $"{Bilibili}/Subtitle"; + + // 评论 + // TODO + + // 头图 + public static string Toutu { get; } = $"{Bilibili}/Toutu"; + + // 封面 + public static string Cover { get; } = $"{Bilibili}/Cover"; + + // 封面文件索引 + public static string CoverIndex { get; } = $"{Cover}/Index.db"; + + // 视频快照 + public static string Snapshot { get; } = $"{Bilibili}/Snapshot"; + + // 视频快照文件索引 + public static string SnapshotIndex { get; } = $"{Cover}/Index.db"; + + // 用户头像 + public static string Header { get; } = $"{Bilibili}/Header"; + + // 用户头像文件索引 + public static string HeaderIndex { get; } = $"{Header}/Index.db"; + + } +} diff --git a/DownKyi.Core/Storage/Database/Cover.cs b/DownKyi.Core/Storage/Database/Cover.cs new file mode 100644 index 0000000..47c6da7 --- /dev/null +++ b/DownKyi.Core/Storage/Database/Cover.cs @@ -0,0 +1,11 @@ +namespace DownKyi.Core.Storage.Database +{ + public class Cover + { + public long Avid { get; set; } + public string Bvid { get; set; } + public long Cid { get; set; } + public string Url { get; set; } + public string Md5 { get; set; } + } +} diff --git a/DownKyi.Core/Storage/Database/CoverDb.cs b/DownKyi.Core/Storage/Database/CoverDb.cs new file mode 100644 index 0000000..bcaea92 --- /dev/null +++ b/DownKyi.Core/Storage/Database/CoverDb.cs @@ -0,0 +1,130 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.Storage.Database +{ + public class CoverDb + { + private const string key = "b5018ecc-09d1-4da2-aa49-4625e41e623e"; + private readonly DbHelper dbHelper = new DbHelper(StorageManager.GetCoverIndex(), key); + + public CoverDb() + { + CreateTable(); + } + + /// + /// 关闭数据库连接 + /// + public void Close() + { + dbHelper.Close(); + } + + /// + /// 插入新的数据 + /// + /// + public void Insert(Cover cover) + { + string sql = $"insert into cover values ({cover.Avid}, '{cover.Bvid}', {cover.Cid}, '{cover.Url}', '{cover.Md5}')"; + dbHelper.ExecuteNonQuery(sql); + } + + /// + /// 更新数据,以url检索 + /// + /// + public void Update(Cover cover) + { + string sql = $"update cover set avid={cover.Avid}, bvid='{cover.Bvid}', cid={cover.Cid}, md5='{cover.Md5}' where url glob '{cover.Url}'"; + dbHelper.ExecuteNonQuery(sql); + } + + /// + /// 查询所有数据 + /// + /// + public List QueryAll() + { + string sql = $"select * from cover"; + return Query(sql); + } + + /// + /// 查询url对应的数据 + /// + /// + /// + public Cover QueryByUrl(string url) + { + string sql = $"select * from cover where url glob '{url}'"; + var query = Query(sql); + + if (query.Count > 0) + { + return query[0]; + } + else + { + return null; + } + } + + /// + /// 查询md5对应的数据 + /// + /// + /// + public Cover QueryByMd5(string md5) + { + string sql = $"select * from cover where md5 glob '{md5}'"; + var query = Query(sql); + + if (query.Count > 0) + { + return query[0]; + } + else + { + return null; + } + } + + /// + /// 查询数据 + /// + /// + /// + private List Query(string sql) + { + List covers = new List(); + + dbHelper.ExecuteQuery(sql, reader => + { + while (reader.Read()) + { + Cover cover = new Cover + { + Avid = (long)reader["avid"], + Bvid = (string)reader["bvid"], + Cid = (long)reader["cid"], + Url = (string)reader["url"], + Md5 = (string)reader["md5"] + }; + covers.Add(cover); + } + }); + return covers; + } + + /// + /// 如果表不存在则创建表 + /// + private void CreateTable() + { + string sql = "create table if not exists cover (avid unsigned big int, bvid varchar(20), cid unsigned big int, url varchar(255) unique, md5 varchar(32) unique)"; + dbHelper.ExecuteNonQuery(sql); + } + + } +} diff --git a/DownKyi.Core/Storage/Database/DbHelper.cs b/DownKyi.Core/Storage/Database/DbHelper.cs new file mode 100644 index 0000000..d2c67af --- /dev/null +++ b/DownKyi.Core/Storage/Database/DbHelper.cs @@ -0,0 +1,104 @@ +using System; +using System.Data.SQLite; + +namespace DownKyi.Core.Storage.Database +{ + public class DbHelper + { + private readonly SQLiteConnection conn; + + /// + /// 创建一个数据库 + /// + /// + public DbHelper(string dbPath) + { + string connStr = $"Data Source={dbPath};Version=3;"; + conn = new SQLiteConnection(connStr); + } + + /// + /// 创建一个带密码的数据库 + /// + /// + /// + public DbHelper(string dbPath, string secretKey) + { + string connStr = $"Data Source={dbPath};Version=3;"; + conn = new SQLiteConnection(connStr); + conn.SetPassword(secretKey); + } + + /// + /// 连接是否开启 + /// + /// + public bool IsOpen() + { + return conn.State == System.Data.ConnectionState.Open; + } + + /// + /// 开启连接 + /// + public void Open() + { + if (!IsOpen()) + { + conn.Open(); + } + } + + /// + /// 关闭数据库 + /// + public void Close() + { + if (IsOpen()) + { + conn.Close(); + } + } + + /// + /// 执行一条SQL语句 + /// + /// + public void ExecuteNonQuery(string sql) + { + lock (conn) + { + Open(); + using (var tr = conn.BeginTransaction()) + { + using (var command = conn.CreateCommand()) + { + command.CommandText = sql; + command.ExecuteNonQuery(); + } + tr.Commit(); + } + } + } + + /// + /// 执行一条SQL语句,并执行提供的操作,一般用于查询 + /// + /// + /// + public void ExecuteQuery(string sql, Action action) + { + lock (conn) + { + Open(); + using (var command = conn.CreateCommand()) + { + command.CommandText = sql; + var reader = command.ExecuteReader(); + action(reader); + } + } + } + + } +} diff --git a/DownKyi.Core/Storage/Database/Header.cs b/DownKyi.Core/Storage/Database/Header.cs new file mode 100644 index 0000000..bcabba0 --- /dev/null +++ b/DownKyi.Core/Storage/Database/Header.cs @@ -0,0 +1,10 @@ +namespace DownKyi.Core.Storage.Database +{ + public class Header + { + public long Mid { get; set; } + public string Name { get; set; } + public string Url { get; set; } + public string Md5 { get; set; } + } +} diff --git a/DownKyi.Core/Storage/Database/HeaderDb.cs b/DownKyi.Core/Storage/Database/HeaderDb.cs new file mode 100644 index 0000000..6cb4500 --- /dev/null +++ b/DownKyi.Core/Storage/Database/HeaderDb.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.Storage.Database +{ + public class HeaderDb + { + private const string key = "7c1f1f40-7cdf-4d11-ad28-f0137a3c5308"; + private readonly DbHelper dbHelper = new DbHelper(StorageManager.GetHeaderIndex(), key); + + public HeaderDb() + { + CreateTable(); + } + + /// + /// 关闭数据库连接 + /// + public void Close() + { + dbHelper.Close(); + } + + /// + /// 插入新的数据 + /// + /// + public void Insert(Header header) + { + string sql = $"insert into header values ({header.Mid}, '{header.Name}', '{header.Url}', '{header.Md5}')"; + dbHelper.ExecuteNonQuery(sql); + } + + /// + /// 更新数据 + /// + /// + public void Update(Header header) + { + string sql = $"update header set name='{header.Name}', url='{header.Url}', md5='{header.Md5}' where mid={header.Mid}"; + dbHelper.ExecuteNonQuery(sql); + } + + /// + /// 查询所有数据 + /// + /// + public List
QueryAll() + { + string sql = $"select * from header"; + return Query(sql); + } + + /// + /// 查询mid对应的数据 + /// + /// + /// + public Header QueryByMid(long mid) + { + string sql = $"select * from header where mid={mid}"; + var query = Query(sql); + + if (query.Count > 0) + { + return query[0]; + } + else + { + return null; + } + } + + + /// + /// 查询数据 + /// + /// + /// + private List
Query(string sql) + { + List
headers = new List
(); + + dbHelper.ExecuteQuery(sql, reader => + { + while (reader.Read()) + { + Header header = new Header + { + Mid = (long)reader["mid"], + Name = (string)reader["name"], + Url = (string)reader["url"], + Md5=(string)reader["md5"] + }; + headers.Add(header); + } + }); + return headers; + } + + /// + /// 如果表不存在则创建表 + /// + private void CreateTable() + { + string sql = "create table if not exists header (mid unsigned big int unique, name varchar(255), url varchar(255), md5 varchar(32))"; + dbHelper.ExecuteNonQuery(sql); + } + + } +} diff --git a/DownKyi.Core/Storage/StorageCover.cs b/DownKyi.Core/Storage/StorageCover.cs new file mode 100644 index 0000000..ae58849 --- /dev/null +++ b/DownKyi.Core/Storage/StorageCover.cs @@ -0,0 +1,208 @@ +using DownKyi.Core.Logging; +using DownKyi.Core.Storage.Database; +using DownKyi.Core.Utils.Encryptor; +using System; +using System.Drawing; +using System.IO; +using System.Windows.Media.Imaging; + +namespace DownKyi.Core.Storage +{ + public class StorageCover + { + // 先判断本地有没有 + // 如果有 + // 则返回本地的图片路径 + // 如果没有 + // 则下载图片并返回本地的图片路径 + + /// + /// 获取封面缩略图 + /// + /// + /// + /// + /// + /// + /// + /// + public BitmapImage GetCoverThumbnail(long avid, string bvid, long cid, string url, int width, int height) + { + string header = GetCover(avid, bvid, cid, url); + + return GetGetCoverThumbnail(header, width, height); + } + + /// + /// 获取封面缩略图 + /// + /// + /// + /// + /// + public BitmapImage GetGetCoverThumbnail(string cover, int width, int height) + { + var bitmap = new Bitmap(cover); + var thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero); + + return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail)); + } + + /// + /// 获取封面 + /// + /// + /// + public string GetCover(string url) + { + return GetCover(0, "", 0, url); + } + + /// + /// 获取封面 + /// + /// + /// + /// + /// + /// + public string GetCover(long avid, string bvid, long cid, string url) + { + CoverDb coverDb = new CoverDb(); + var cover = coverDb.QueryByUrl(url); + + // 如果存在,直接返回 + // 如果不存在,则先下载 + if (cover != null) + { + string coverPath = $"{StorageManager.GetCover()}/{cover.Md5}"; + if (File.Exists(coverPath)) + { + Cover newCover = new Cover + { + Avid = avid, + Bvid = bvid, + Cid = cid, + Url = url, + Md5 = cover.Md5 + }; + coverDb.Update(newCover); + + coverDb.Close(); + return $"{StorageManager.GetCover()}/{cover.Md5}"; + } + else + { + string md5 = DownloadImage(url); + if (md5 != null) + { + Cover newCover = new Cover + { + Avid = avid, + Bvid = bvid, + Cid = cid, + Url = url, + Md5 = md5 + }; + coverDb.Update(newCover); + + coverDb.Close(); + return $"{StorageManager.GetCover()}/{md5}"; + } + else + { + coverDb.Close(); + return null; + } + } + } + else + { + string md5 = DownloadImage(url); + if (md5 != null) + { + Cover newCover = new Cover + { + Avid = avid, + Bvid = bvid, + Cid = cid, + Url = url, + Md5 = md5 + }; + coverDb.Insert(newCover); + + coverDb.Close(); + return $"{StorageManager.GetCover()}/{md5}"; + } + else + { + coverDb.Close(); + return null; + } + } + } + + /// + /// 下载图片 + /// + /// + /// + private string DownloadImage(string url) + { + string localFile = Path.GetTempPath() + Guid.NewGuid().ToString("N"); + + // 下载 + bool isSuccessed = StorageUtils.DownloadImage(url, localFile); + if (isSuccessed) + { + try + { + string md5 = Hash.GetMD5HashFromFile(localFile); + + if (File.Exists(localFile)) + { + File.Move(localFile, $"{StorageManager.GetCover()}/{md5}"); + + return md5; + } + else + { + return null; + } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("DownloadImage()发生异常: {0}", e); + LogManager.Error("StorageCover", e); + return null; + } + } + + return null; + } + + /// + /// 本地是否存在 + /// + /// + /// + public bool IsLocal(CoverDb coverDb, string url) + { + var cover = coverDb.QueryByUrl(url); + return cover != null; + } + + /// + /// 返回图片md5值 + /// + /// + /// + /// + public string LocalCover(CoverDb coverDb, string url) + { + var cover = coverDb.QueryByUrl(url); + return cover.Md5; + } + + } +} diff --git a/DownKyi.Core/Storage/StorageHeader.cs b/DownKyi.Core/Storage/StorageHeader.cs new file mode 100644 index 0000000..d80e438 --- /dev/null +++ b/DownKyi.Core/Storage/StorageHeader.cs @@ -0,0 +1,164 @@ +using DownKyi.Core.Logging; +using DownKyi.Core.Storage.Database; +using DownKyi.Core.Utils.Encryptor; +using System; +using System.Drawing; +using System.IO; +using System.Windows.Media.Imaging; + +namespace DownKyi.Core.Storage +{ + public class StorageHeader + { + // 先判断本地有没有 + // 如果有 + // 则返回本地的图片路径 + // 如果没有 + // 则下载图片并返回本地的图片路径 + + /// + /// 获取用户头像缩略图 + /// + /// + /// + /// + /// + /// + /// + public BitmapImage GetHeaderThumbnail(long mid, string name, string url, int width, int height) + { + string header = GetHeader(mid, name, url); + + return GetHeaderThumbnail(header, width, height); + } + + /// + /// 获取用户头像缩略图 + /// + /// + /// + /// + /// + public BitmapImage GetHeaderThumbnail(string header, int width, int height) + { + var bitmap = new Bitmap(header); + var thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero); + + return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail)); + } + + /// + /// 获取用户头像 + /// + /// + /// + public string GetHeader(long mid, string name, string url) + { + HeaderDb headerDb = new HeaderDb(); + var header = headerDb.QueryByMid(mid); + + if (header != null) + { + string headerPath = $"{StorageManager.GetHeader()}/{header.Md5}"; + if (File.Exists(headerPath)) + { + Header newHeader = new Header + { + Mid = mid, + Name = name, + Url = url, + Md5 = header.Md5 + }; + headerDb.Update(newHeader); + headerDb.Close(); + return $"{StorageManager.GetHeader()}/{header.Md5}"; + } + else + { + string md5 = DownloadImage(url); + if (md5 != null) + { + Header newHeader = new Header + { + Mid = mid, + Name = name, + Url = url, + Md5 = md5 + }; + headerDb.Insert(newHeader); + headerDb.Close(); + return $"{StorageManager.GetHeader()}/{md5}"; + } + else + { + headerDb.Close(); + return null; + } + } + } + else + { + string md5 = DownloadImage(url); + if (md5 != null) + { + Header newHeader = new Header + { + Mid = mid, + Name = name, + Url = url, + Md5 = md5 + }; + headerDb.Insert(newHeader); + headerDb.Close(); + return $"{StorageManager.GetHeader()}/{md5}"; + } + else + { + headerDb.Close(); + return null; + } + } + } + + + /// + /// 下载图片 + /// + /// + /// + private string DownloadImage(string url) + { + string localFile = Path.GetTempPath() + Guid.NewGuid().ToString("N"); + + // 下载 + bool isSuccessed = StorageUtils.DownloadImage(url, localFile); + if (isSuccessed) + { + try + { + string md5 = Hash.GetMD5HashFromFile(localFile); + + if (File.Exists(localFile)) + { + File.Move(localFile, $"{StorageManager.GetHeader()}/{md5}"); + + return md5; + } + else + { + return null; + } + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("DownloadImage()发生异常: {0}", e); + LogManager.Error("StorageHeader", e); + return null; + } + } + + return null; + } + + } +} diff --git a/DownKyi.Core/Storage/StorageManager.cs b/DownKyi.Core/Storage/StorageManager.cs new file mode 100644 index 0000000..7531ef3 --- /dev/null +++ b/DownKyi.Core/Storage/StorageManager.cs @@ -0,0 +1,136 @@ +using System.IO; + +namespace DownKyi.Core.Storage +{ + public static class StorageManager + { + /// + /// 获取历史记录的文件路径 + /// + /// + public static string GetHistory() + { + CreateDirectory(Constant.Database); + return Constant.History; + } + + /// + /// 获取设置的文件路径 + /// + /// + public static string GetSettings() + { + CreateDirectory(Constant.Config); + return Constant.Settings; + } + + /// + /// 获取登录cookies的文件路径 + /// + /// + public static string GetLogin() + { + CreateDirectory(Constant.Config); + return Constant.Login; + } + + /// + /// 获取弹幕的文件夹路径 + /// + /// + public static string GetDanmaku() + { + return CreateDirectory(Constant.Danmaku); + } + + /// + /// 获取字幕的文件夹路径 + /// + /// + public static string GetSubtitle() + { + return CreateDirectory(Constant.Subtitle); + } + + /// + /// 获取头图的文件夹路径 + /// + /// + public static string GetToutu() + { + return CreateDirectory(Constant.Toutu); + } + + /// + /// 获取封面的文件夹路径 + /// + /// + public static string GetCover() + { + return CreateDirectory(Constant.Cover); + } + + /// + /// 获取封面索引的文件路径 + /// + /// + public static string GetCoverIndex() + { + CreateDirectory(Constant.Cover); + return Constant.CoverIndex; + } + + /// + /// 获取视频快照的文件夹路径 + /// + /// + public static string GetSnapshot() + { + return CreateDirectory(Constant.Snapshot); + } + + /// + /// 获取视频快照索引的文件路径 + /// + /// + public static string GetSnapshotIndex() + { + CreateDirectory(Constant.Snapshot); + return Constant.SnapshotIndex; + } + + /// + /// 获取用户头像的文件夹路径 + /// + /// + public static string GetHeader() + { + return CreateDirectory(Constant.Header); + } + + /// + /// 获取用户头像索引的文件路径 + /// + /// + public static string GetHeaderIndex() + { + CreateDirectory(Constant.Header); + return Constant.HeaderIndex; + } + + + /// + /// 若文件夹不存在,则创建文件夹 + /// + /// + /// + private static string CreateDirectory(string directory) + { + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + return directory; + } + } +} diff --git a/DownKyi.Core/Storage/StorageUtils.cs b/DownKyi.Core/Storage/StorageUtils.cs new file mode 100644 index 0000000..0b4ab9e --- /dev/null +++ b/DownKyi.Core/Storage/StorageUtils.cs @@ -0,0 +1,58 @@ +using DownKyi.Core.Logging; +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Net; +using System.Windows.Media.Imaging; + +namespace DownKyi.Core.Storage +{ + internal static class StorageUtils + { + /// + /// 下载图片 + /// + /// + /// + /// + public static bool DownloadImage(string url, string localFile) + { + try + { + WebClient mywebclient = new WebClient(); + mywebclient.DownloadFile(url, localFile); + } + catch (Exception e) + { + Utils.Debug.Console.PrintLine("DownloadImage()发生异常: {0}", e); + LogManager.Error("StorageUtils", e); + return false; + } + return true; + } + + /// + /// Bitmap转BitmapImage + /// + /// + /// + public static BitmapImage BitmapToBitmapImage(Bitmap bitmap) + { + BitmapImage result = new BitmapImage(); + using (MemoryStream stream = new MemoryStream()) + { + bitmap.Save(stream, ImageFormat.Bmp); + stream.Position = 0; + result.BeginInit(); + result.CacheOption = BitmapCacheOption.OnLoad; + result.StreamSource = stream; + result.EndInit(); + result.Freeze(); + } + return result; + } + + } + +} diff --git a/DownKyi.Core/Utils/Encryptor/Encryptor.File.cs b/DownKyi.Core/Utils/Encryptor/Encryptor.File.cs new file mode 100644 index 0000000..1a9b9a5 --- /dev/null +++ b/DownKyi.Core/Utils/Encryptor/Encryptor.File.cs @@ -0,0 +1,227 @@ +using System; +using System.IO; +using System.Security.Cryptography; + +namespace DownKyi.Core.Utils.Encryptor +{ + public static partial class Encryptor + { + private const ulong FC_TAG = 0xFC010203040506CF; + private const int BUFFER_SIZE = 128 * 1024; + + /// + /// 加密文件 + /// + /// 待加密文件 + /// 加密后输入文件 + /// 加密密码 + public static void EncryptFile(string inFile, string outFile, string password) + { + using (FileStream fin = File.OpenRead(inFile), fout = File.OpenWrite(outFile)) + { + long lSize = fin.Length; // 输入文件长度 + int size = (int)lSize; + byte[] bytes = new byte[BUFFER_SIZE]; // 缓存 + int read = -1; // 输入文件读取数量 + int value = 0; + + // 获取IV和salt + byte[] IV = GenerateRandomBytes(16); + byte[] salt = GenerateRandomBytes(16); + + // 创建加密对象 + SymmetricAlgorithm sma = CreateRijndael(password, salt); + sma.IV = IV; + + // 在输出文件开始部分写入IV和salt + fout.Write(IV, 0, IV.Length); + fout.Write(salt, 0, salt.Length); + + // 创建散列加密 + HashAlgorithm hasher = SHA256.Create(); + using (CryptoStream cout = new CryptoStream(fout, sma.CreateEncryptor(), CryptoStreamMode.Write), + chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) + { + BinaryWriter bw = new BinaryWriter(cout); + bw.Write(lSize); + + bw.Write(FC_TAG); + + // 读写字节块到加密流缓冲区 + while ((read = fin.Read(bytes, 0, bytes.Length)) != 0) + { + cout.Write(bytes, 0, read); + chash.Write(bytes, 0, read); + value += read; + } + // 关闭加密流 + chash.Flush(); + chash.Close(); + + // 读取散列 + byte[] hash = hasher.Hash; + + // 输入文件写入散列 + cout.Write(hash, 0, hash.Length); + + // 关闭文件流 + cout.Flush(); + cout.Close(); + } + } + } + + /// + /// 解密文件 + /// + /// 待解密文件 + /// 解密后输出文件 + /// 解密密码 + public static void DecryptFile(string inFile, string outFile, string password) + { + // 创建打开文件流 + using (FileStream fin = File.OpenRead(inFile), fout = File.OpenWrite(outFile)) + { + int size = (int)fin.Length; + byte[] bytes = new byte[BUFFER_SIZE]; + int read = -1; + int value = 0; + int outValue = 0; + + byte[] IV = new byte[16]; + fin.Read(IV, 0, 16); + byte[] salt = new byte[16]; + fin.Read(salt, 0, 16); + + SymmetricAlgorithm sma = CreateRijndael(password, salt); + sma.IV = IV; + + value = 32; + long lSize = -1; + + // 创建散列对象, 校验文件 + HashAlgorithm hasher = SHA256.Create(); + + try + { + using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read), + chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write)) + { + // 读取文件长度 + BinaryReader br = new BinaryReader(cin); + lSize = br.ReadInt64(); + ulong tag = br.ReadUInt64(); + + if (FC_TAG != tag) + throw new CryptoHelpException("文件被破坏"); + + long numReads = lSize / BUFFER_SIZE; + + long slack = (long)lSize % BUFFER_SIZE; + + for (int i = 0; i < numReads; ++i) + { + read = cin.Read(bytes, 0, bytes.Length); + fout.Write(bytes, 0, read); + chash.Write(bytes, 0, read); + value += read; + outValue += read; + } + + if (slack > 0) + { + read = cin.Read(bytes, 0, (int)slack); + fout.Write(bytes, 0, read); + chash.Write(bytes, 0, read); + value += read; + outValue += read; + } + + chash.Flush(); + chash.Close(); + + fout.Flush(); + fout.Close(); + + byte[] curHash = hasher.Hash; + + // 获取比较和旧的散列对象 + byte[] oldHash = new byte[hasher.HashSize / 8]; + read = cin.Read(oldHash, 0, oldHash.Length); + if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash))) + throw new CryptoHelpException("文件被破坏"); + } + } + catch (Exception e) + { + Console.WriteLine("DecryptFile()发生异常: {0}", e); + } + + if (outValue != lSize) + throw new CryptoHelpException("文件大小不匹配"); + } + } + + /// + /// 检验两个Byte数组是否相同 + /// + /// Byte数组 + /// Byte数组 + /// true-相等 + private static bool CheckByteArrays(byte[] b1, byte[] b2) + { + if (b1.Length == b2.Length) + { + for (int i = 0; i < b1.Length; ++i) + { + if (b1[i] != b2[i]) + return false; + } + return true; + } + return false; + } + + /// + /// 创建DebugLZQ ,http://www.cnblogs.com/DebugLZQ + /// + /// 密码 + /// + /// 加密对象 + private static SymmetricAlgorithm CreateRijndael(string password, byte[] salt) + { + PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt, "SHA256", 1000); + + SymmetricAlgorithm sma = Rijndael.Create(); + sma.KeySize = 256; + sma.Key = pdb.GetBytes(32); + sma.Padding = PaddingMode.PKCS7; + return sma; + } + + /// + /// 生成指定长度的随机Byte数组 + /// + /// Byte数组长度 + /// 随机Byte数组 + private static byte[] GenerateRandomBytes(int count) + { + // 加密文件随机数生成 + RandomNumberGenerator rand = new RNGCryptoServiceProvider(); + + byte[] bytes = new byte[count]; + rand.GetBytes(bytes); + return bytes; + } + + } + + /// + /// 异常处理类 + /// + public class CryptoHelpException : ApplicationException + { + public CryptoHelpException(string msg) : base(msg) { } + } + +} diff --git a/DownKyi.Core/Utils/Encryptor/Encryptor.String.cs b/DownKyi.Core/Utils/Encryptor/Encryptor.String.cs new file mode 100644 index 0000000..87493f1 --- /dev/null +++ b/DownKyi.Core/Utils/Encryptor/Encryptor.String.cs @@ -0,0 +1,70 @@ +using DownKyi.Core.Logging; +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace DownKyi.Core.Utils.Encryptor +{ + public static partial class Encryptor + { + /// + /// DES加密字符串 + /// + /// 待加密的字符串 + /// 加密密钥,要求为8位 + /// 加密成功返回加密后的字符串,失败返回源串 + public static string EncryptString(string encryptString, string encryptKey) + { + try + { + byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));//转换为字节 + byte[] rgbIV = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8)); + byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); + DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();//实例化数据加密标准 + MemoryStream mStream = new MemoryStream();//实例化内存流 + //将数据流链接到加密转换的流 + CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write); + cStream.Write(inputByteArray, 0, inputByteArray.Length); + cStream.FlushFinalBlock(); + // 转base64 + return Convert.ToBase64String(mStream.ToArray()); + } + catch (Exception e) + { + Debug.Console.PrintLine("EncryptString()发生异常: {0}", e); + LogManager.Error("Encryptor", e); + return encryptString; + } + } + + /// + /// DES解密字符串 + /// + /// 待解密的字符串 + /// 解密密钥,要求为8位,和加密密钥相同 + /// 解密成功返回解密后的字符串,失败返源串 + public static string DecryptString(string decryptString, string decryptKey) + { + try + { + byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey); + byte[] rgbIV = Encoding.UTF8.GetBytes(decryptKey); + byte[] inputByteArray = Convert.FromBase64String(decryptString); + DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); + MemoryStream mStream = new MemoryStream(); + CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write); + cStream.Write(inputByteArray, 0, inputByteArray.Length); + cStream.FlushFinalBlock(); + return Encoding.UTF8.GetString(mStream.ToArray()); + } + catch (Exception e) + { + Debug.Console.PrintLine("DecryptString()发生异常: {0}", e); + LogManager.Error("Encryptor", e); + return decryptString; + } + } + + } +} diff --git a/DownKyi.Core/Utils/Encryptor/Hash.cs b/DownKyi.Core/Utils/Encryptor/Hash.cs new file mode 100644 index 0000000..a170ccb --- /dev/null +++ b/DownKyi.Core/Utils/Encryptor/Hash.cs @@ -0,0 +1,68 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace DownKyi.Core.Utils.Encryptor +{ + public static class Hash + { + /// + /// 计算字符串MD5值 + /// + /// + /// + public static string GetMd5Hash(string input) + { + if (input == null) + { + return null; + } + + MD5 md5Hash = MD5.Create(); + + // 将输入字符串转换为字节数组并计算哈希数据 + byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input)); + + // 创建一个 Stringbuilder 来收集字节并创建字符串 + StringBuilder sBuilder = new StringBuilder(); + + // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串 + for (int i = 0; i < data.Length; i++) + { + sBuilder.Append(data[i].ToString("x2")); + } + + // 返回十六进制字符串 + return sBuilder.ToString(); + } + + /// + /// 计算文件MD5值 + /// + /// + /// + public static string GetMD5HashFromFile(string fileName) + { + try + { + FileStream file = new FileStream(fileName, FileMode.Open); + MD5 md5 = new MD5CryptoServiceProvider(); + byte[] retVal = md5.ComputeHash(file); + file.Close(); + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < retVal.Length; i++) + { + sb.Append(retVal[i].ToString("x2")); + } + return sb.ToString(); + } + catch (Exception e) + { + throw new Exception("GetMD5HashFromFile()发生异常: {0}" + e.Message); + } + } + + } +} diff --git a/DownKyi.Core/Utils/Format.cs b/DownKyi.Core/Utils/Format.cs new file mode 100644 index 0000000..d8f08c8 --- /dev/null +++ b/DownKyi.Core/Utils/Format.cs @@ -0,0 +1,168 @@ +namespace DownKyi.Core.Utils +{ + public static class Format + { + + /// + /// 格式化Duration时间 + /// + /// + /// + public static string FormatDuration(long duration) + { + string formatDuration; + if (duration / 60 > 0) + { + long dur = duration / 60; + if (dur / 60 > 0) + { + formatDuration = $"{dur / 60}h{dur % 60}m{duration % 60}s"; + } + else + { + formatDuration = $"{duration / 60}m{duration % 60}s"; + } + } + else + { + formatDuration = $"{duration}s"; + } + return formatDuration; + } + + /// + /// 格式化Duration时间,格式为00:00:00 + /// + /// + /// + public static string FormatDuration2(long duration) + { + string formatDuration; + if (duration / 60 > 0) + { + long dur = duration / 60; + if (dur / 60 > 0) + { + formatDuration = string.Format("{0:D2}", dur / 60) + ":" + string.Format("{0:D2}", dur % 60) + ":" + string.Format("{0:D2}", duration % 60); + } + else + { + formatDuration = "00:" + string.Format("{0:D2}", duration / 60) + ":" + string.Format("{0:D2}", duration % 60); + } + } + else + { + formatDuration = "00:00:" + string.Format("{0:D2}", duration); + } + return formatDuration; + } + + /// + /// 格式化Duration时间,格式为00:00 + /// + /// + /// + public static string FormatDuration3(long duration) + { + string formatDuration; + if (duration / 60 > 0) + { + long dur = duration / 60; + if (dur / 60 > 0) + { + formatDuration = string.Format("{0:D2}", dur / 60) + ":" + string.Format("{0:D2}", dur % 60) + ":" + string.Format("{0:D2}", duration % 60); + } + else + { + formatDuration = string.Format("{0:D2}", duration / 60) + ":" + string.Format("{0:D2}", duration % 60); + } + } + else + { + formatDuration = "00:" + string.Format("{0:D2}", duration); + } + return formatDuration; + } + + /// + /// 格式化数字,超过10000的数字将单位改为万,超过100000000的数字将单位改为亿,并保留1位小数 + /// + /// + /// + public static string FormatNumber(long number) + { + if (number > 99999999) + { + return (number / 100000000.0f).ToString("F1") + "亿"; + } + + if (number > 9999) + { + return (number / 10000.0f).ToString("F1") + "万"; + } + else + { + return number.ToString(); + } + } + + /// + /// 格式化网速 + /// + /// + /// + public static string FormatSpeed(float speed) + { + string formatSpeed; + if (speed <= 0) + { + formatSpeed = "0B/s"; + } + else if (speed < 1024) + { + formatSpeed = speed.ToString("#.##") + "B/s"; + } + else if (speed < 1024 * 1024) + { + formatSpeed = (speed / 1024).ToString("#.##") + "KB/s"; + } + else + { + formatSpeed = (speed / 1024 / 1024).ToString("#.##") + "MB/s"; + } + return formatSpeed; + } + + /// + /// 格式化字节大小,可用于文件大小的显示 + /// + /// + /// + public static string FormatFileSize(long fileSize) + { + string formatFileSize; + if (fileSize <= 0) + { + formatFileSize = "0B"; + } + else if (fileSize < 1024) + { + formatFileSize = fileSize.ToString() + "B"; + } + else if (fileSize < 1024 * 1024) + { + formatFileSize = (fileSize / 1024.0).ToString("#.##") + "KB"; + } + else if (fileSize < 1024 * 1024 * 1024) + { + formatFileSize = (fileSize / 1024.0 / 1024.0).ToString("#.##") + "MB"; + } + else + { + formatFileSize = (fileSize / 1024.0 / 1024.0 / 1024.0).ToString("#.##") + "GB"; + } + return formatFileSize; + } + + } +} diff --git a/DownKyi.Core/Utils/HardDisk.cs b/DownKyi.Core/Utils/HardDisk.cs new file mode 100644 index 0000000..046384d --- /dev/null +++ b/DownKyi.Core/Utils/HardDisk.cs @@ -0,0 +1,52 @@ +using System.IO; + +namespace DownKyi.Core.Utils +{ + public static class HardDisk + { + /// + /// 获取指定驱动器的空间总大小 + /// + /// 只需输入代表驱动器的字母即可 + /// + public static long GetHardDiskSpace(string hardDiskName) + { + long totalSize = new long(); + hardDiskName = $"{hardDiskName}:\\"; + DriveInfo[] drives = DriveInfo.GetDrives(); + + foreach (DriveInfo drive in drives) + { + if (drive.Name == hardDiskName) + { + totalSize = drive.TotalSize; + } + } + + return totalSize; + } + + /// + /// 获取指定驱动器的剩余空间总大小 + /// + /// 只需输入代表驱动器的字母即可 + /// + public static long GetHardDiskFreeSpace(string hardDiskName) + { + long freeSpace = new long(); + hardDiskName = $"{hardDiskName}:\\"; + DriveInfo[] drives = DriveInfo.GetDrives(); + + foreach (DriveInfo drive in drives) + { + if (drive.Name == hardDiskName) + { + freeSpace = drive.TotalFreeSpace; + } + } + + return freeSpace; + } + + } +} diff --git a/DownKyi.Core/Utils/ListHelper.cs b/DownKyi.Core/Utils/ListHelper.cs new file mode 100644 index 0000000..bee195d --- /dev/null +++ b/DownKyi.Core/Utils/ListHelper.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +namespace DownKyi.Core.Utils +{ + public static class ListHelper + { + + /// + /// 判断List中是否存在,不存在则添加 + /// + /// + /// + public static void AddUnique(List list, T item) + { + if (!list.Exists(t => t.Equals(item))) + { + list.Add(item); + } + } + + /// + /// 判断List中是否存在,不存在则添加 + /// + /// + /// + /// + /// + public static void InsertUnique(List list, T item, int index) + { + if (!list.Exists(t => t.Equals(item))) + { + list.Insert(index, item); + } + else + { + list.Remove(item); + list.Insert(index, item); + } + } + + } +} diff --git a/DownKyi.Core/Utils/MachineCode.cs b/DownKyi.Core/Utils/MachineCode.cs new file mode 100644 index 0000000..5c13cb2 --- /dev/null +++ b/DownKyi.Core/Utils/MachineCode.cs @@ -0,0 +1,145 @@ +using System; +using System.Management; + +namespace DownKyi.Core.Utils +{ + public class MachineCode + { + private static MachineCode machineCode; + + /// + /// 获取机器码 + /// + /// + public static string GetMachineCodeString() + { + if (machineCode == null) + { + machineCode = new MachineCode(); + } + + string machineCodeString = "PC." + + machineCode.GetMainBordId() + "." + + machineCode.GetCpuInfo() + "." + + machineCode.GetDiskID();// + "." + + //machineCode.GetMoAddress(); + return machineCodeString.Replace(" ", ""); + } + + /// + /// 获取主板ID + /// + /// + public string GetMainBordId() + { + string strId = ""; + try + { + using (ManagementClass mc = new ManagementClass("Win32_BaseBoard")) + { + ManagementObjectCollection moc = mc.GetInstances(); + foreach (ManagementObject mo in moc) + { + strId = mo.Properties["SerialNumber"].Value.ToString(); + mo.Dispose(); + break; + } + } + } + catch (Exception) + { + return "unknown"; + //throw; + } + return strId; + } + + /// + /// 获取cpu序列号 + /// + /// + public string GetCpuInfo() + { + string cpuInfo = ""; + try + { + using (ManagementClass cimobject = new ManagementClass("Win32_Processor")) + { + ManagementObjectCollection moc = cimobject.GetInstances(); + + foreach (ManagementObject mo in moc) + { + cpuInfo = mo.Properties["ProcessorId"].Value.ToString(); + mo.Dispose(); + } + } + } + catch (Exception) + { + return "unknown"; + //throw; + } + return cpuInfo; + } + + /// + /// 获取硬盘ID + /// + /// + public string GetDiskID() + { + string diskName = ""; + string diskID = ""; + try + { + using (ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive")) + { + ManagementObjectCollection moc1 = cimobject1.GetInstances(); + foreach (ManagementObject mo in moc1) + { + diskName = mo.Properties["Model"].Value.ToString(); + diskID = mo.Properties["SerialNumber"].Value.ToString(); + mo.Dispose(); + } + } + } + catch (Exception) + { + return "unknown"; + //throw; + } + return diskName + diskID; + } + + /// + /// 获取网卡硬件地址 + /// + /// + public string GetMoAddress() + { + string MoAddress = ""; + try + { + using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration")) + { + ManagementObjectCollection moc2 = mc.GetInstances(); + foreach (ManagementObject mo in moc2) + { + if ((bool)mo["IPEnabled"]) + { + MoAddress = mo["MacAddress"].ToString(); + } + + mo.Dispose(); + } + } + } + catch (Exception) + { + return "unknown"; + //throw; + } + return MoAddress; + } + } +} diff --git a/DownKyi.Core/Utils/ObjectHelper.cs b/DownKyi.Core/Utils/ObjectHelper.cs new file mode 100644 index 0000000..13d7632 --- /dev/null +++ b/DownKyi.Core/Utils/ObjectHelper.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Runtime.Serialization.Formatters.Binary; + +namespace DownKyi.Core.Utils +{ + public static class ObjectHelper + { + + /// + /// 解析二维码登录返回的url,用于设置cookie + /// + /// + /// + public static CookieContainer ParseCookie(string url) + { + CookieContainer cookieContainer = new CookieContainer(); + + if (url == null || url == "") { return cookieContainer; } + + string[] strList = url.Split('?'); + if (strList.Count() < 2) { return cookieContainer; } + + string[] strList2 = strList[1].Split('&'); + if (strList2.Count() == 0) { return cookieContainer; } + + // 获取expires + string expires = strList2.FirstOrDefault(it => it.Contains("Expires")).Split('=')[1]; + DateTime dateTime = DateTime.Now; + dateTime = dateTime.AddSeconds(int.Parse(expires)); + + foreach (var item in strList2) + { + string[] strList3 = item.Split('='); + if (strList3.Count() < 2) { continue; } + + string name = strList3[0]; + string value = strList3[1]; + + // 不需要 + if (name == "Expires" || name == "gourl") { continue; } + + // 添加cookie + cookieContainer.Add(new Cookie(name, value, "/", ".bilibili.com") { Expires = dateTime }); + Debug.Console.PrintLine(name + ": " + value + "\t" + cookieContainer.Count); + } + + return cookieContainer; + } + + /// + /// 将CookieContainer中的所有的Cookie读出来 + /// + /// + /// + public static List GetAllCookies(CookieContainer cc) + { + List lstCookies = new List(); + + Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | + System.Reflection.BindingFlags.Instance, null, cc, new object[] { }); + + foreach (object pathList in table.Values) + { + SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField + | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { }); + foreach (CookieCollection colCookies in lstCookieCol.Values) + { + foreach (Cookie c in colCookies) + { + lstCookies.Add(c); + } + } + } + + return lstCookies; + } + + /// + /// 写入cookies到磁盘 + /// + /// + /// + /// + public static bool WriteCookiesToDisk(string file, CookieContainer cookieJar) + { + return WriteObjectToDisk(file, cookieJar); + } + + /// + /// 从磁盘读取cookie + /// + /// + /// + public static CookieContainer ReadCookiesFromDisk(string file) + { + return (CookieContainer)ReadObjectFromDisk(file); + } + + /// + /// 写入序列化对象到磁盘 + /// + /// + /// + /// + public static bool WriteObjectToDisk(string file, object obj) + { + try + { + using (Stream stream = File.Create(file)) + { + Debug.Console.PrintLine("Writing object to disk... "); + + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(stream, obj); + + Debug.Console.PrintLine("Done."); + return true; + } + } + catch (IOException e) + { + Debug.Console.PrintLine("WriteObjectToDisk()发生IO异常: {0}", e); + Logging.LogManager.Error(e); + return false; + } + catch (Exception e) + { + Debug.Console.PrintLine("WriteObjectToDisk()发生异常: {0}", e); + Logging.LogManager.Error(e); + return false; + } + } + + /// + /// 从磁盘读取序列化对象 + /// + /// + /// + public static object ReadObjectFromDisk(string file) + { + try + { + using (Stream stream = File.Open(file, FileMode.Open)) + { + Debug.Console.PrintLine("Reading object from disk... "); + BinaryFormatter formatter = new BinaryFormatter(); + Debug.Console.PrintLine("Done."); + return formatter.Deserialize(stream); + } + } + catch (IOException e) + { + Debug.Console.PrintLine("ReadObjectFromDisk()发生IO异常: {0}", e); + Logging.LogManager.Error(e); + return null; + } + catch (Exception e) + { + Debug.Console.PrintLine("ReadObjectFromDisk()发生异常: {0}", e); + Logging.LogManager.Error(e); + return null; + } + } + } +} diff --git a/DownKyi.Core/Utils/QRCode.cs b/DownKyi.Core/Utils/QRCode.cs new file mode 100644 index 0000000..d7e703f --- /dev/null +++ b/DownKyi.Core/Utils/QRCode.cs @@ -0,0 +1,41 @@ +using System.Drawing; + +namespace DownKyi.Core.Utils +{ + public static class QRCode + { + /// + /// 生成二维码 + /// + /// 信息 + /// 版本 1 ~ 40 + /// 像素点大小 + /// 图标路径 + /// 图标尺寸 + /// 图标边框厚度 + /// 二维码白边 + /// 位图 + public static Bitmap EncodeQRCode(string msg, int version, int pixel, string icon_path, int icon_size, int icon_border, bool white_edge) + { + QRCoder.QRCodeGenerator code_generator = new QRCoder.QRCodeGenerator(); + + QRCoder.QRCodeData code_data = code_generator.CreateQrCode(msg, QRCoder.QRCodeGenerator.ECCLevel.H/* 这里设置容错率的一个级别 */, true, false, QRCoder.QRCodeGenerator.EciMode.Utf8, version); + + QRCoder.QRCode code = new QRCoder.QRCode(code_data); + + Bitmap icon; + if (icon_path == null || icon_path == "") + { + icon = null; + } + else + { + icon = new Bitmap(icon_path); + } + + Bitmap bmp = code.GetGraphic(pixel, Color.Black, Color.White, icon, icon_size, icon_border, white_edge); + return bmp; + } + + } +} diff --git a/DownKyi.Core/Utils/StringLogicalComparer.cs b/DownKyi.Core/Utils/StringLogicalComparer.cs new file mode 100644 index 0000000..d56c1af --- /dev/null +++ b/DownKyi.Core/Utils/StringLogicalComparer.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; + +namespace DownKyi.Core.Utils +{ + public class StringLogicalComparer : IComparer + { + /// + /// 比较两个字符串,如果含用数字,则数字按数字的大小来比较。 + /// + /// + /// + /// + public int Compare(T x, T y) + { + if (x == null || y == null) + { + throw new ArgumentException("Parameters can't be null"); + } + + string fileA = x as string; + string fileB = y as string; + char[] arr1 = fileA.ToCharArray(); + char[] arr2 = fileB.ToCharArray(); + int i = 0, j = 0; + while (i < arr1.Length && j < arr2.Length) + { + if (char.IsDigit(arr1[i]) && char.IsDigit(arr2[j])) + { + string s1 = "", s2 = ""; + while (i < arr1.Length && char.IsDigit(arr1[i])) + { + s1 += arr1[i]; + i++; + } + while (j < arr2.Length && char.IsDigit(arr2[j])) + { + s2 += arr2[j]; + j++; + } + if (int.Parse(s1) > int.Parse(s2)) + { + return 1; + } + if (int.Parse(s1) < int.Parse(s2)) + { + return -1; + } + } + else + { + if (arr1[i] > arr2[j]) + { + return 1; + } + if (arr1[i] < arr2[j]) + { + return -1; + } + i++; + j++; + } + } + if (arr1.Length == arr2.Length) + { + return 0; + } + else + { + return arr1.Length > arr2.Length ? 1 : -1; + } + } + + } +} diff --git a/DownKyi.Core/Utils/Validator/Number.cs b/DownKyi.Core/Utils/Validator/Number.cs new file mode 100644 index 0000000..899ecdf --- /dev/null +++ b/DownKyi.Core/Utils/Validator/Number.cs @@ -0,0 +1,29 @@ +using System.Text.RegularExpressions; + +namespace DownKyi.Core.Utils.Validator +{ + public static class Number + { + + /// + /// 字符串转数字(长整型) + /// + /// + /// + public static long GetInt(string value) + { + return IsInt(value) ? long.Parse(value) : -1; + } + + /// + /// 是否为数字 + /// + /// + /// + public static bool IsInt(string value) + { + return Regex.IsMatch(value, @"^\d+$"); + } + + } +} diff --git a/DownKyi.Core/Utils/Web.cs b/DownKyi.Core/Utils/Web.cs new file mode 100644 index 0000000..7342460 --- /dev/null +++ b/DownKyi.Core/Utils/Web.cs @@ -0,0 +1,8 @@ +namespace DownKyi.Core.Utils +{ + public static class Web + { + // TODO 这里的代码只是为了测试Brotli.Core,不是最终的,需要修改 + + } +} diff --git a/DownKyi.Core/app.config b/DownKyi.Core/app.config new file mode 100644 index 0000000..f10b4ac --- /dev/null +++ b/DownKyi.Core/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi.Core/packages.config b/DownKyi.Core/packages.config new file mode 100644 index 0000000..25076d7 --- /dev/null +++ b/DownKyi.Core/packages.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi.sln b/DownKyi.sln new file mode 100644 index 0000000..9afa28f --- /dev/null +++ b/DownKyi.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31019.35 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DownKyi", "DownKyi\DownKyi.csproj", "{97075FCD-6E8F-4FF9-B73A-994197F3765A}" + ProjectSection(ProjectDependencies) = postProject + {4FDE0364-F65B-4812-BFE8-34E886624FBD} = {4FDE0364-F65B-4812-BFE8-34E886624FBD} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DownKyi.Core", "DownKyi.Core\DownKyi.Core.csproj", "{4FDE0364-F65B-4812-BFE8-34E886624FBD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Brotli.Core", "Brotli.Core\Brotli.Core.csproj", "{3107CD63-E257-455E-AE81-1FD3582B067A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DownKyi.Core.Test", "DownKyi.Core.Test\DownKyi.Core.Test.csproj", "{81B9719E-DA29-444F-BB72-CBD5819A654D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseManager", "DatabaseManager\DatabaseManager.csproj", "{95F12C16-86B5-43D5-AF3E-D2489E2DB239}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|Any CPU.Build.0 = Release|Any CPU + {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|Any CPU.Build.0 = Release|Any CPU + {3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3107CD63-E257-455E-AE81-1FD3582B067A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3107CD63-E257-455E-AE81-1FD3582B067A}.Release|Any CPU.Build.0 = Release|Any CPU + {81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|Any CPU.Build.0 = Release|Any CPU + {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B8FC6858-6EAD-46C9-AC9A-01E6DEBA32BC} + EndGlobalSection +EndGlobal diff --git a/DownKyi/App.xaml b/DownKyi/App.xaml new file mode 100644 index 0000000..34ef81c --- /dev/null +++ b/DownKyi/App.xaml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/DownKyi/App.xaml.cs b/DownKyi/App.xaml.cs new file mode 100644 index 0000000..cd38faf --- /dev/null +++ b/DownKyi/App.xaml.cs @@ -0,0 +1,81 @@ +using DownKyi.Utils; +using DownKyi.ViewModels; +using DownKyi.ViewModels.Dialogs; +using DownKyi.ViewModels.DownloadManager; +using DownKyi.ViewModels.Settings; +using DownKyi.ViewModels.Toolbox; +using DownKyi.Views; +using DownKyi.Views.Dialogs; +using DownKyi.Views.DownloadManager; +using DownKyi.Views.Settings; +using DownKyi.Views.Toolbox; +using Prism.Ioc; +using System; +using System.Windows; + +namespace DownKyi +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App + { + protected override Window CreateShell() + { + // 设置主题 + DictionaryResource.LoadTheme("ThemeDefault"); + //DictionaryResource.LoadTheme("ThemeDiy"); + + // 切换语言 + DictionaryResource.LoadLanguage("Default"); + //DictionaryResource.LoadLanguage("en_US"); + + return Container.Resolve(); + } + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + // pages + containerRegistry.RegisterForNavigation(ViewIndexViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewLoginViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewVideoDetailViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewSettingsViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewDownloadManagerViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewToolboxViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewUserSpaceViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewMySpaceViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewPublicFavoritesViewModel.Tag); + + // downloadManager pages + containerRegistry.RegisterForNavigation(ViewDownloadingViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewDownloadFinishedViewModel.Tag); + + // settings pages + containerRegistry.RegisterForNavigation(ViewBasicViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewNetworkViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewVideoViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewDanmakuViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewAboutViewModel.Tag); + + // tools pages + containerRegistry.RegisterForNavigation(ViewBiliHelperViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewDelogoViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewExtractMediaViewModel.Tag); + + // dialogs + containerRegistry.RegisterDialog(ViewDirectorySelectorViewModel.Tag); + containerRegistry.RegisterDialog(ViewParsingSelectorViewModel.Tag); + + } + + /// + /// 异步修改绑定到UI的属性 + /// + /// + public static void PropertyChangeAsync(Action callback) + { + Current.Dispatcher.Invoke(callback); + } + + } +} diff --git a/DownKyi/CustomControl/GifImage.cs b/DownKyi/CustomControl/GifImage.cs new file mode 100644 index 0000000..402f5f5 --- /dev/null +++ b/DownKyi/CustomControl/GifImage.cs @@ -0,0 +1,103 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Interop; +using System.Windows.Media.Imaging; +using System.Windows.Threading; + +namespace DownKyi.CustomControl +{ + public class GifImage : System.Windows.Controls.Image + { + /// + /// gif动画的System.Drawing.Bitmap + /// + private Bitmap gifBitmap; + + /// + /// 用于显示每一帧的BitmapSource + /// + private BitmapSource bitmapSource; + + public GifImage(string gifPath) + { + gifBitmap = new Bitmap(gifPath); + bitmapSource = GetBitmapSource(); + Source = bitmapSource; + } + + public GifImage(Bitmap gifBitmap) + { + this.gifBitmap = gifBitmap; + bitmapSource = GetBitmapSource(); + Source = bitmapSource; + } + + /// + /// 从System.Drawing.Bitmap中获得用于显示的那一帧图像的BitmapSource + /// + /// + private BitmapSource GetBitmapSource() + { + IntPtr handle = IntPtr.Zero; + + try + { + handle = gifBitmap.GetHbitmap(); + bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); + } + finally + { + if (handle != IntPtr.Zero) + { + DeleteObject(handle); + } + } + return bitmapSource; + } + + /// + /// Start animation + /// + public void StartAnimate() + { + ImageAnimator.Animate(gifBitmap, OnFrameChanged); + } + + /// + /// Stop animation + /// + public void StopAnimate() + { + ImageAnimator.StopAnimate(gifBitmap, OnFrameChanged); + } + + /// + /// Event handler for the frame changed + /// + private void OnFrameChanged(object sender, EventArgs e) + { + Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => + { + ImageAnimator.UpdateFrames(); // 更新到下一帧 + if (bitmapSource != null) + { + bitmapSource.Freeze(); + } + + //// Convert the bitmap to BitmapSource that can be display in WPF Visual Tree + bitmapSource = GetBitmapSource(); + Source = bitmapSource; + InvalidateVisual(); + })); + } + + /// + /// Delete local bitmap resource + /// Reference: http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx + /// + [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool DeleteObject(IntPtr hObject); + } +} diff --git a/DownKyi/DownKyi.csproj b/DownKyi/DownKyi.csproj new file mode 100644 index 0000000..cf0d869 --- /dev/null +++ b/DownKyi/DownKyi.csproj @@ -0,0 +1,447 @@ + + + + + Debug + AnyCPU + {97075FCD-6E8F-4FF9-B73A-994197F3765A} + WinExe + Properties + DownKyi + DownKyi + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + PackageReference + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Resources\favicon.ico + + + app.manifest + + + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ViewDirectorySelector.xaml + + + ViewParsingSelector.xaml + + + ViewDownloadFinished.xaml + + + ViewDownloading.xaml + + + ViewAbout.xaml + + + ViewBasic.xaml + + + ViewDanmaku.xaml + + + ViewNetwork.xaml + + + ViewVideo.xaml + + + ViewBiliHelper.xaml + + + ViewDelogo.xaml + + + ViewExtractMedia.xaml + + + ViewDownloadManager.xaml + + + ViewIndex.xaml + + + ViewLogin.xaml + + + ViewMySpace.xaml + + + ViewPublicFavorites.xaml + + + ViewSettings.xaml + + + ViewToolbox.xaml + + + ViewUserSpace.xaml + + + ViewVideoDetail.xaml + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + MainWindow.xaml + Code + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + 1.0.112.2 + + + + + + + + + + + {4fde0364-f65b-4812-bfe8-34e886624fbd} + DownKyi.Core + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Events/MessageEvent.cs b/DownKyi/Events/MessageEvent.cs new file mode 100644 index 0000000..0375cb0 --- /dev/null +++ b/DownKyi/Events/MessageEvent.cs @@ -0,0 +1,6 @@ +using Prism.Events; + +namespace DownKyi.Events +{ + public class MessageEvent : PubSubEvent { } +} diff --git a/DownKyi/Events/NavigationEvent.cs b/DownKyi/Events/NavigationEvent.cs new file mode 100644 index 0000000..9a2ca03 --- /dev/null +++ b/DownKyi/Events/NavigationEvent.cs @@ -0,0 +1,6 @@ +using Prism.Events; + +namespace DownKyi.Events +{ + public class NavigationEvent : PubSubEvent { } +} diff --git a/DownKyi/Events/NavigationParam.cs b/DownKyi/Events/NavigationParam.cs new file mode 100644 index 0000000..42ad90b --- /dev/null +++ b/DownKyi/Events/NavigationParam.cs @@ -0,0 +1,9 @@ +namespace DownKyi.Events +{ + public class NavigationParam + { + public string ViewName { get; set; } + public string ParentViewName { get; set; } + public object Parameter { get; set; } + } +} diff --git a/DownKyi/FFmpeg_LICENSE.txt b/DownKyi/FFmpeg_LICENSE.txt new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/DownKyi/FFmpeg_LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/DownKyi/Images/ButtonIcon.cs b/DownKyi/Images/ButtonIcon.cs new file mode 100644 index 0000000..73caefb --- /dev/null +++ b/DownKyi/Images/ButtonIcon.cs @@ -0,0 +1,79 @@ +namespace DownKyi.Images +{ + public class ButtonIcon + { + private static ButtonIcon instance; + public static ButtonIcon Instance() + { + if (instance == null) + { + instance = new ButtonIcon(); + } + return instance; + } + + public ButtonIcon() + { + GeneralSearch = new VectorImage + { + Height = 20, + Width = 20, + Data = @"M697.91 755.7 q-132.36 103.48 -290.59 98.06 q-158.23 -5.41 -278.56 -120.92 q-127.54 -133.56 -128.75 -304.43 + q-1.21 -170.86 120.33 -304.43 q127.55 -126.34 297.21 -123.94 q169.66 2.41 303.22 123.94 q110.71 114.31 122.14 263.52 + q11.43 149.21 -75.21 275.55 l238.25 239.45 q18.05 18.05 18.05 42.12 q0 24.06 -18.05 41.51 q-18.05 17.45 -42.12 17.45 + q-24.07 0 -42.12 -16.85 l-223.81 -231.03 ZM643.76 647.41 q92.66 -96.26 92.66 -219 q0 -122.73 -92.66 -218.99 q-96.26 -92.66 -219 -92.66 + q-122.74 0 -218.99 92.66 q-92.65 96.26 -92.65 218.99 q0 122.74 92.65 219 q96.26 92.65 218.99 90.25 q122.74 -2.4 219 -90.25 Z", + Fill = "#FF000000" + }; + + Settings = new VectorImage + { + Height = 32, + Width = 32, + Data = @"M19.4,13c0-0.3,0.1-0.6,0.1-1s0-0.7-0.1-1l2.1-1.7c0.2-0.2,0.2-0.4,0.1-0.6l-2-3.5C19.5,5,19.3,5,19,5l-2.5,1 + c-0.5-0.4-1.1-0.7-1.7-1l-0.4-2.7C14.5,2.2,14.3,2,14,2h-4C9.8,2,9.5,2.2,9.5,2.4L9.1,5.1C8.5,5.3,8,5.7,7.4,6L5,5 + C4.7,5,4.5,5,4.3,5.3l-2,3.5C2.2,9,2.3,9.2,2.5,9.4L4.6,11c0,0.3-0.1,0.6-0.1,1s0,0.7,0.1,1l-2.1,1.7c-0.2,0.1-0.2,0.4-0.1,0.6 + l2,3.5C4.5,19,4.7,19,5,19l2.5-1c0.5,0.4,1.1,0.7,1.7,1l0.4,2.7c0,0.2,0.2,0.4,0.5,0.4h4c0.3,0,0.5-0.2,0.5-0.4l0.4-2.7 + c0.6-0.3,1.2-0.6,1.7-1l2.5,1c0.2,0.1,0.5,0,0.6-0.2l2-3.5c0.1-0.2,0.1-0.5-0.1-0.6L19.4,13z M12,15.5c-1.9,0-3.5-1.6-3.5-3.5 + s1.6-3.5,3.5-3.5s3.5,1.6,3.5,3.5S13.9,15.5,12,15.5z", + Fill = "#FF000000" + }; + + DownloadManage = new VectorImage + { + Height = 27, + Width = 32, + //Height = 20, + //Width = 24, + Data = @"M24,34c-2.4,0-4.9,0-7.3,0c-2.8,0-4.6-1.9-4.6-4.7c0-3.5,0-7,0-10.5c0-2.9,1.9-4.7,4.6-4.7c1.3,0,2.6,0,3.9,0 + c1.1-0.1,2,0.4,2.7,1.3c1.1,1.7,2.6,2.3,4.6,2.1c1.3-0.2,2.6-0.1,4,0c2.5,0.2,4,1.7,4.2,4.3c0.2,2.7,0.2,5.5,0,8.3 + c-0.2,2.4-2,4-4.3,4C29,34,26.5,34,24,34L24,34z + M23.9,32.6c2.5,0,5,0,7.5,0c1.7,0,2.9-1,3-2.7c0.2-2.8,0.2-5.6,0-8.5 + c-0.1-1.5-1.1-2.4-2.5-2.6c-1.3-0.2-2.6-0.1-3.9-0.1c-4.1-0.1-3,0.5-6-2.6c-0.5-0.5-1-0.8-1.7-0.8c-1.3,0-2.5,0-3.8,0 + c-2,0-3.2,1.2-3.3,3.2c0,3.6,0,7.1,0,10.7c0,2,1.2,3.2,3.2,3.2C19,32.6,21.5,32.6,23.9,32.6L23.9,32.6z + M29.9,14.2h3.3c0.5,0,0.9,0,0.9,0.7c0,0.7-0.4,0.8-0.9,0.8c-2.2,0-4.5,0-6.7,0c-0.5,0-0.9-0.1-0.9-0.7 + s0.4-0.7,0.9-0.7C27.6,14.2,28.7,14.2,29.9,14.2L29.9,14.2z M23.3,27.6v-5.4c0-0.5,0-1.1,0.7-1.1c0.7,0,0.6,0.6,0.6,1v5.2 + c0.7-0.7,1.2-1.2,1.7-1.7c0.3-0.4,0.7-0.7,1.2-0.2c0.5,0.5,0.1,0.9-0.2,1.2c-0.9,1-1.8,1.9-2.7,2.8c-0.4,0.5-0.8,0.5-1.3,0.1 + c-1-1-2-2.1-3-3.1c-0.3-0.3-0.4-0.7-0.1-1c0.3-0.4,0.7-0.3,1,0.1C22,26.1,22.6,26.7,23.3,27.6L23.3,27.6z", + Fill = "#FF000000" + }; + + Toolbox = new VectorImage + { + Height = 28, // 21 + Width = 32, // 24 + Data = @"M20.2,14.5c-0.8,2.3-3.4,3.6-5.7,2.7c-1.3-0.5-2.3-1.5-2.7-2.7H5.5V13h21v1.5H20.2z M18.6,14.5h-5.2 + c0.8,1.4,2.7,1.9,4.1,1.1C18,15.3,18.3,15,18.6,14.5L18.6,14.5z M10,8.5V7c0-0.8,0.7-1.5,1.5-1.5h9C21.3,5.5,22,6.2,22,7v1.5h4.5 + c0.8,0,1.5,0.7,1.5,1.5v15c0,0.8-0.7,1.5-1.5,1.5l0,0h-21C4.7,26.5,4,25.8,4,25l0,0V10c0-0.8,0.7-1.5,1.5-1.5H10z M11.5,8.5h9V7h-9 + V8.5z M5.5,10v15h21V10H5.5z", + Fill = "#FF000000" + }; + } + + public VectorImage GeneralSearch { get; private set; } + public VectorImage Settings { get; private set; } + public VectorImage DownloadManage { get; private set; } + public VectorImage Toolbox { get; private set; } + + } +} diff --git a/DownKyi/Images/LogoIcon.cs b/DownKyi/Images/LogoIcon.cs new file mode 100644 index 0000000..853394f --- /dev/null +++ b/DownKyi/Images/LogoIcon.cs @@ -0,0 +1,54 @@ +namespace DownKyi.Images +{ + class LogoIcon + { + private static LogoIcon instance; + public static LogoIcon Instance() + { + if (instance == null) + { + instance = new LogoIcon(); + } + return instance; + } + + private LogoIcon() + { + TextLogo = new VectorImage + { + Height = 100, + Width = 336, + Data = @"M602.247902 495.326917q0-146.045116 60.22479-219.820484a198.13956 198.13956 0 0 1 308.953174 0q61.73041 + 74.076492 62.031534 213.798005 0 150.561976-60.22479 225.54184a198.13956 198.13956 0 0 1-309.254298 0Q602.247902 640.468662 + 602.247902 495.326917z m80.098971 0A273.721671 273.721671 0 0 0 722.697482 657.331603a120.44958 120.44958 0 0 0 98.467532 + 53.298939 115.029349 115.029349 0 0 0 94.251797-53.901187 273.420548 273.420548 0 0 0 39.447238-161.703562 271.011556 + 271.011556 0 0 0-39.748362-162.004685 120.44958 120.44958 0 0 0-98.467532-53.29894A114.125977 114.125977 0 0 0 722.697482 + 333.322232a271.011556 271.011556 0 0 0-39.748361 161.703561zM1212.023903 776.275564L1070.194522 214.077147h80.701219l73.474244 + 324.611619 27.101155 120.449581 24.391041-116.836093L1349.035301 214.077147h80.701218l68.656261 326.117239 23.186545 107.501251 + 26.498907-108.705747L1626.069336 214.077147h76.184359l-143.335001 562.198417h-81.303466l-73.474244-336.656578-17.46519-95.757416L1294.832989 + 776.275564zM1768.500964 776.275564V214.077147h70.463005v79.496723a180.674371 180.674371 0 0 1 62.031534-69.258509 154.476587 + 154.476587 0 0 1 84.314706-22.88542 161.703562 161.703562 0 0 1 68.355137 14.45395 140.624885 140.624885 0 0 1 50.588824 + 38.242742 153.874339 153.874339 0 0 1 30.112395 60.22479 509.802849 509.802849 0 0 1 9.635966 + 115.330473v346.593668h-79.195599V433.897631a279.141903 279.141903 0 0 0-10.539338-90.337185 87.62707 87.62707 0 0 + 0-85.218078-60.22479 109.00687 109.00687 0 0 0-90.337186 41.856229q-33.424759 42.157353-33.424758 143.636125v307.447554zM2270.775715 + 776.275564V0.279142h84.314706v384.836409L2670.969446 0.279142h114.427101l-267.096945 314.674529 278.539655 + 461.321893h-111.114738l-225.842963-391.461137-104.791135 123.46082v268.903689zM2853.149436 993.98818l-8.732595-90.337185a146.34624 + 146.34624 0 0 0 44.566345 8.431471 78.292227 78.292227 0 0 0 41.253981-9.937091 76.786608 76.786608 0 0 0 26.498908-30.112395c2.710116-5.119107 + 12.94833-36.134874 30.112395-93.348425L2812.196579 214.077147h84.314706l96.359664 325.514991c12.044958 40.350609 + 22.88542 83.712458 33.123635 130.085547 9.033719-43.662973 19.573057-86.422574 31.919139-127.977679l98.467532-327.622859h78.292227l-174.953016 + 572.135507a1012.679847 1012.679847 0 0 1-54.202311 147.550736 141.227133 141.227133 0 0 1-45.168592 53.600063 103.285515 103.285515 0 0 + 1-56.912427 16.561818 132.494538 132.494538 0 0 1-50.2877-9.937091zM3300.318503 109.88826V0.279142h77.68998v109.609118z + m0 666.387304V214.077147h77.68998v562.198417zM0 776.275564V0.279142h219.51936a417.357796 417.357796 0 0 1 124.063068 + 14.152826 210.786766 210.786766 0 0 1 96.359664 67.752889 358.337502 358.337502 0 0 1 63.537154 124.364191 616.400728 616.400728 0 0 1 + 22.584296 177.362008 579.663606 579.663606 0 0 1-38.543865 223.735095 273.420548 273.420548 0 0 1-99.370904 130.386671 294.1981 + 294.1981 0 0 1-158.391198 38.242742zM463.730885 391.740278q10.840462-7.528099 + 0-16.260693l-51.79332-30.112395q-136.40915-82.507963-276.431787-150.561976l-13.249454-6.624727a22.283172 22.283172 + 0 0 0-16.561817 0v405.613962a18.669685 18.669685 0 0 0 14.755073-4.817983q148.152984-76.786608 296.607092-164.413677c15.357322-10.238214 + 31.015767-21.379801 46.674213-32.822511z", + Fill = "#FF000000" + }; + } + + public VectorImage TextLogo { get; private set; } + } +} diff --git a/DownKyi/Images/NavigationIcon.cs b/DownKyi/Images/NavigationIcon.cs new file mode 100644 index 0000000..bdbe329 --- /dev/null +++ b/DownKyi/Images/NavigationIcon.cs @@ -0,0 +1,29 @@ +namespace DownKyi.Images +{ + public class NavigationIcon + { + private static NavigationIcon instance; + public static NavigationIcon Instance() + { + if (instance == null) + { + instance = new NavigationIcon(); + } + return instance; + } + + public NavigationIcon() + { + ArrowBack = new VectorImage + { + Height = 24, + Width = 24, + Data = @"M16.62 2.99c-.49-.49-1.28-.49-1.77 0L6.54 11.3c-.39.39-.39 1.02 0 1.41l8.31 8.31c.49.49 1.28.49 1.77 + 0s.49-1.28 0-1.77L9.38 12l7.25-7.25c.48-.48.48-1.28-.01-1.76z", + Fill = "#FF000000" + }; + } + + public VectorImage ArrowBack { get; private set; } + } +} diff --git a/DownKyi/Images/NormalIcon.cs b/DownKyi/Images/NormalIcon.cs new file mode 100644 index 0000000..0eba593 --- /dev/null +++ b/DownKyi/Images/NormalIcon.cs @@ -0,0 +1,68 @@ +namespace DownKyi.Images +{ + public class NormalIcon + { + private static NormalIcon instance; + public static NormalIcon Instance() + { + if (instance == null) + { + instance = new NormalIcon(); + } + return instance; + } + + public NormalIcon() + { + CloudDownload = new VectorImage + { + Height = 32, + Width = 48, + Data = @"M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.3,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5 + C24,12.4,22,10.2,19.4,10z M19,18H6c-2.2,0-4-1.8-4-4c0-2.1,1.5-3.8,3.6-4l1.1-0.1L7.1,9C8.1,7.1,9.9,6,12,6c2.6,0,4.9,1.9,5.4,4.4 + l0.3,1.5l1.5,0.1c1.6,0.1,2.8,1.4,2.8,3C22,16.6,20.6,18,19,18z M13.4,10h-2.9v3H8l4,4l4-4h-2.6V10z", + Fill = "#FF000000" + }; + + Folder = new VectorImage + { + Height = 32, + Width = 40, + Data = @"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z", + Fill = "#FF000000" + }; + + Downloading = new VectorImage + { + Height = 16, + Width = 16, + Data = @"M1,11.7c0.6,0,1,0.5,1,1V24H1.4C0.6,24,0,23.4,0,22.6c0,0,0,0,0,0v-9.9C0,12.1,0.5,11.7,1,11.7C1,11.7,1,11.7,1,11.7z + M0,21.9h24v0.7c0,0.8-0.6,1.4-1.3,1.4H1.4C0.6,24,0,23.4,0,22.6V21.9z + M23,11.7c0.6,0,1,0.5,1,1v9.9c0,0.8-0.6,1.4-1.3,1.4H22V12.7C22,12.1,22.5,11.7,23,11.7C23,11.7,23,11.7,23,11.7z M13,17.4 + h-2V1c0-0.6,0.4-1,1-1s1,0.5,1,1c0,0,0,0,0,0V17.4z + M6.9,12.5c0.4-0.4,1-0.4,1.4,0l4.9,5.1L12.8,18c-0.5,0.5-1.4,0.5-1.9,0l-4-4.1C6.5,13.5,6.5,12.9,6.9,12.5L6.9,12.5z + M16.8,12.5c0.4,0.4,0.4,1.1,0,1.5l-4,4.1c-0.5,0.5-1.4,0.5-1.9,0l-0.5-0.5l4.9-5.1C15.8,12.1,16.4,12.1,16.8,12.5L16.8,12.5z", + Fill = "#FF000000" + }; + + DownloadFinished = new VectorImage + { + Height = 16, + Width = 16, + Data = @"M12,0C8.6,0.1,5.8,1.3,3.5,3.5S0.1,8.6,0,12c0.1,3.4,1.3,6.2,3.5,8.5S8.6,23.9,12,24c3.4-0.1,6.2-1.3,8.5-3.5 + s3.4-5.1,3.5-8.5c-0.1-3.4-1.3-6.2-3.5-8.5S15.4,0.1,12,0z M12,22.5c-3-0.1-5.5-1.1-7.4-3.1S1.6,15,1.5,12c0.1-3,1.1-5.5,3.1-7.4 + S9,1.6,12,1.5c3,0.1,5.5,1.1,7.4,3.1s3,4.4,3.1,7.4c-0.1,3-1.1,5.5-3.1,7.4S15,22.4,12,22.5z + M16.5,8.1c0.2-0.2,0.4-0.2,0.6-0.2c0.5,0,0.9,0.4,0.9,0.9c0,0.2-0.1,0.5-0.2,0.6l-6.5,6.5 + c-0.2,0.2-0.4,0.3-0.6,0.3c-0.2,0-0.5-0.1-0.7-0.3l-3.8-3.7C6.1,12,6,11.7,6,11.5c0-0.2,0.1-0.5,0.3-0.6c0.2-0.2,0.4-0.3,0.6-0.3 + c0.2,0,0.5,0.1,0.6,0.2l3.1,3.1L16.5,8.1L16.5,8.1z", + Fill = "#FF000000" + }; + + } + + public VectorImage CloudDownload { get; private set; } + public VectorImage Folder { get; private set; } + public VectorImage Downloading { get; private set; } + public VectorImage DownloadFinished { get; private set; } + } +} diff --git a/DownKyi/Images/SystemIcon.cs b/DownKyi/Images/SystemIcon.cs new file mode 100644 index 0000000..b6bec27 --- /dev/null +++ b/DownKyi/Images/SystemIcon.cs @@ -0,0 +1,76 @@ +namespace DownKyi.Images +{ + public class SystemIcon + { + private static SystemIcon instance; + public static SystemIcon Instance() + { + if (instance == null) + { + instance = new SystemIcon(); + } + return instance; + } + + private SystemIcon() + { + Close = new VectorImage + { + Height = 12, + Width = 12, + Data = @"M25,23.9l-6.6-6.6c-0.3-0.3-0.9-0.3-1.1,0c-0.3,0.3-0.3,0.9,0,1.1l0,0l6.6,6.6l-6.6,6.6c-0.3,0.3-0.3,0.9,0,1.1 + c0.3,0.3,0.9,0.3,1.1,0l0,0l6.6-6.6l6.6,6.6c0.3,0.3,0.9,0.3,1.1,0.1c0.3-0.3,0.3-0.9,0.1-1.1c0,0,0,0-0.1-0.1L26.1,25l6.6-6.6 + c0.3-0.3,0.3-0.9,0-1.1c-0.3-0.3-0.9-0.3-1.1,0l0,0L25,23.9L25,23.9z", + Fill = "#FF000000" + }; + + Maximize = new VectorImage + { + Height = 12, + Width = 12, + Data = @"M31.1,33H18.9c-1,0-1.9-0.9-1.9-1.9V18.9c0-1,0.9-1.9,1.9-1.9h12.3c1,0,1.9,0.9,1.9,1.9v12.3C33,32.1,32.1,33,31.1,33z + M18.9,18.3c-0.3,0-0.6,0.3-0.6,0.6v12.3c0,0.3,0.3,0.6,0.6,0.6h12.3c0.3,0,0.6-0.3,0.6-0.6V18.9c0-0.3-0.3-0.6-0.6-0.6 + C31.1,18.3,18.9,18.3,18.9,18.3z", + Fill = "#FF000000" + }; + + Minimize = new VectorImage + { + Height = 1.2, + Width = 12, + Data = @"M17.8,25.8c-0.5,0-0.8-0.3-0.8-0.8s0.3-0.8,0.8-0.8h14.4c0.5,0,0.8,0.3,0.8,0.8s-0.3,0.8-0.8,0.8H17.8z", + Fill = "#FF000000" + }; + + Restore = new VectorImage + { + Height = 12, + Width = 12, + Data = @"M29,33H18.3c-0.7,0-1.3-0.6-1.3-1.3V21c0-0.7,0.6-1.3,1.3-1.3H29c0.7,0,1.3,0.6,1.3,1.3v10.7C30.4,32.4,29.8,33,29,33z + M18.3,20.9c-0.1,0-0.1,0.1-0.1,0.1v10.7c0,0.1,0.1,0.1,0.1,0.1H29c0.1,0,0.1-0.1,0.1-0.1V21c0-0.1-0.1-0.1-0.1-0.1H18.3z + M31.7,30.4h-1.9v-1.2h1.9c0.1,0,0.1-0.1,0.1-0.1V18.3c0-0.1-0.1-0.1-0.1-0.1H21c-0.1,0-0.1,0.1-0.1,0.1v1.9h-1.2v-1.9 + c0-0.7,0.6-1.3,1.3-1.3h10.7c0.7,0,1.3,0.6,1.3,1.3v10.7C33,29.8,32.4,30.4,31.7,30.4z", + Fill = "#FF000000" + }; + + Skin = new VectorImage + { + Height = 12, + Width = 12, + Data = @"M29.1,18.1l2.7,3.2l-1.3,1.6c-0.1-0.1-0.3-0.1-0.5-0.1c-0.6,0-1,0.5-1,1.2v8.1h-8.2v-8.1c0-0.7-0.5-1.2-1-1.2 + c-0.1,0-0.3,0-0.5,0.1l-1.3-1.6l2.7-3.2h0.8c0.7,0.9,2.4,1.5,3.3,1.5c0.9,0,2.6-0.4,3.3-1.5H29.1 M29.2,17h-0.9 + c-0.2,0-0.5,0.1-0.7,0.4c-0.5,0.5-1.8,1.1-2.6,1.1c-0.8,0-2.2-0.5-2.6-1.2c-0.2-0.1-0.5-0.3-0.7-0.3h-0.9c-0.2,0-0.5,0.1-0.6,0.3 + l-3.1,3.6c-0.1,0.3-0.1,0.7,0,0.8l1.8,2.2C19,24,19.3,24,19.4,24s0.2,0,0.3-0.1v-0.1h0.1c0,0,0.1,0,0.1,0.1v8.2 + c0,0.5,0.3,0.9,0.8,0.9h8.6c0.5,0,0.8-0.4,0.8-0.9v-8.2c0-0.1,0-0.1,0.1-0.1h0.1l0.1,0.1c0.1,0.1,0.2,0.1,0.3,0.1s0.2,0,0.3-0.1 + l1.8-2.2c0-0.1,0-0.5-0.1-0.8l-3.1-3.6C29.7,17.1,29.5,17,29.2,17z", + Fill = "#FF000000" + }; + } + + public VectorImage Close { get; private set; } + public VectorImage Maximize { get; private set; } + public VectorImage Minimize { get; private set; } + public VectorImage Restore { get; private set; } + public VectorImage Skin { get; private set; } + } +} diff --git a/DownKyi/Images/VectorImage.cs b/DownKyi/Images/VectorImage.cs new file mode 100644 index 0000000..921d09a --- /dev/null +++ b/DownKyi/Images/VectorImage.cs @@ -0,0 +1,36 @@ +using Prism.Mvvm; + +namespace DownKyi.Images +{ + public class VectorImage : BindableBase + { + private double width; + public double Width + { + get { return width; } + set { SetProperty(ref width, value); } + } + + private double height; + public double Height + { + get { return height; } + set { SetProperty(ref height, value); } + } + + private string data; + public string Data + { + get { return data; } + set { SetProperty(ref data, value); } + } + + private string fill; + public string Fill + { + get { return fill; } + set { SetProperty(ref fill, value); } + } + + } +} diff --git a/DownKyi/Languages/Default.xaml b/DownKyi/Languages/Default.xaml new file mode 100644 index 0000000..5ff0b24 --- /dev/null +++ b/DownKyi/Languages/Default.xaml @@ -0,0 +1,199 @@ + + + + 哔哩下载姬 + 未知 + + + 关闭 + 最大化 + 最小化 + 还原 + 皮肤 + + + 登录 + 请输入B站网址链接或av、BV号等…… + 请输入B站视频播放地址…… + 设置 + 下载管理 + 工具箱 + + + 扫描二维码登录 + 请使用哔哩哔哩客户端 扫码登录 或扫码下载APP + 获取登录链接失败! + 密钥错误!尝试重新获取! + 已超时!尝试重新获取二维码! + 登录成功!(3秒后自动回到主页) + 未保存登录信息!(3秒后自动回到主页) + + + 复制封面图片 + 复制封面URL + 播放 + 弹幕 + 点赞 + 投币 + 收藏 + 分享 + 评论 + + 番剧 + 电影 + 纪录片 + 国创 + 电视剧 + 综艺 + 课程 + + 序号 + 名称 + 时长 + 音质 + 画质 + 视频编码 + + 全选 + 解析 + 解析视频 + 下载选中项 + + + 正在下载 + 已下载 + + + 按回车键应用设置 + + 基本 + 下载完成后的动作: + + 关闭程序 + 关闭计算机 + 监听剪贴板 + 视频自动解析 + 视频解析范围: + + 网络 + Aria服务器端口: + Aria日志等级: + Aria同时下载数: + Aria最大线程数: + Aria下载速度限制(KB/s) + 全局下载速度限制[0: 无限制] + 单任务下载速度限制[0: 无限制] + 使用Http代理 + 代理地址: + 端口: + Aria文件预分配: + + 视频 + 优先下载的视频编码: + 优先下载的视频画质: + 启用视频编号 + 勾选后,将为下载完成的视频的文件名添加上序号 + 下载FLV视频后转码为mp4 + 使用默认下载目录 + 默认下载目录: + 默认将文件下载到该文件夹中 + 更改目录 + 为不同视频分别创建文件夹 + 在下载视频的同时下载弹幕 + 在下载视频的同时下载封面 + + 弹幕 + 按类型屏蔽 + 顶部 + 底部 + 滚动 + 分辨率: + 字体名称: + 字体大小: + 限制行数: + 布局算法: + 速度同步 + 每一条滚动弹幕的移动速度都是相同的 + 速度异步 + 弹幕滚动速度取决于它的文本长度 + + 关于 + 访问主页 + 当前版本: + 检查更新 + 意见反馈 + 接收测试版更新 + 启动时检查更新 + 设置已更新~ + 设置失败! + 第三方 + 名称 + 作者 + 版本 + 许可证 + 免责申明 + 1. 本软件只提供视频解析,不提供任何资源上传、存储到服务器的功能。 + 2. 本软件仅解析来自B站的内容,不会对解析到的音视频进行二次编码,部分视频会进行有限的格式转换、拼接等操作。 + 3. 本软件解析得到的所有内容均来自B站UP主上传、分享,其版权均归原作者所有。内容提供者、上传者(UP主)应对其提供、上传的内容承担全部责任。 + 4. 本软件提供的所有资源,仅可用作学习交流使用,未经原作者授权,禁止用于其他用途。请在下载24小时内删除。为尊重作者版权,请前往资源的原始发布网站观看,支持原创,谢谢。 + 5. 任何涉及商业盈利目的均不得使用,否则产生的一切后果将由您自己承担。 + 6. 因使用本软件产生的版权问题,软件作者概不负责。 + + + B站助手 + AV和BV互转 + AV号形如"av123",BV号形如"BVxxx"。 + AVID: + BVID: + 访问网页 + 弹幕中的userID: + 查询弹幕发送者-> + + 去水印 + 视频地址: + 选择视频 + 水印尺寸与位置(左上角为原点,单位:像素) + 宽: + 高: + X: + Y: + 请等待当前任务完成! + 没有选择视频! + 请输入正确的宽度(正整数)! + 请输入正确的高度(正整数)! + 请输入正确的X(正整数)! + 请输入正确的Y(正整数)! + 输出信息: + + 音视频分离 + 提取音频 + 提取视频 + + + 取消 + 请选择文件夹 + + + 设置下载文件夹 + 位置: + 浏览 + 盘剩余空间: + 设此文件夹为默认下载文件夹 + 选中后下次将不会弹出此窗口 + 下载 + + 文件夹路径不能为空 + + + 选择解析项 + + 解析选中项 + 解析当前页视频 + 解析所有视频 + 设为默认,下次不再弹出 + + \ No newline at end of file diff --git a/DownKyi/Languages/en_US.xaml b/DownKyi/Languages/en_US.xaml new file mode 100644 index 0000000..d952741 --- /dev/null +++ b/DownKyi/Languages/en_US.xaml @@ -0,0 +1,173 @@ + + + + DownKyi + Unknown + + + Close + Maximize + Minimize + Restore + Skin + + + Login + Please input the Bilibili url, av id, and BV id etc. + Settings + Download Manager + Toolbox + + + Scan to Login + 请使用哔哩哔哩客户端 扫码登录 或扫码下载APP + 获取登录链接失败! + 密钥错误!尝试重新获取! + 已超时!尝试重新获取二维码! + 登录成功!(3秒后自动回到主页) + 未保存登录信息!(3秒后自动回到主页) + + + 复制封面图片 + 复制封面URL + 播放 + 弹幕 + 点赞 + 投币 + 收藏 + 分享 + 评论 + + 番剧 + 电影 + 纪录片 + 国创 + 电视剧 + 综艺 + 课程 + + 序号 + 名称 + 时长 + 音质 + 画质 + 视频编码 + + 全选 + 解析 + 解析视频 + 下载选中项 + + + 正在下载 + 已下载 + + + 按回车键应用设置 + + 基本 + 下载完成后的动作: + + 关闭程序 + 关闭计算机 + 监听剪贴板 + 视频自动解析 + 视频解析范围: + + 网络 + Aria服务器端口: + Aria日志等级: + Aria同时下载数: + Aria最大线程数: + Aria下载速度限制(KB/s) + 全局下载速度限制[0: 无限制] + 单任务下载速度限制[0: 无限制] + 使用Http代理 + 代理地址: + 端口: + Aria文件预分配: + + 视频 + 优先下载的视频编码: + 优先下载的视频画质: + 启用视频编号 + 勾选后,将为下载完成的视频的文件名添加上序号 + 下载FLV视频后转码为mp4 + 使用默认下载目录 + 默认下载目录: + 默认将文件下载到该文件夹中 + 更改目录 + 为不同视频分别创建文件夹 + 在下载视频的同时下载弹幕 + 在下载视频的同时下载封面 + + 弹幕 + 按类型屏蔽 + 顶部 + 底部 + 滚动 + 分辨率: + 字体名称: + 字体大小: + 限制行数: + 布局算法: + 速度同步 + 每一条滚动弹幕的移动速度都是相同的 + 速度异步 + 弹幕滚动速度取决于它的文本长度 + + 关于 + 访问主页 + 当前版本: + 检查更新 + 意见反馈 + 接收测试版更新 + 启动时检查更新 + 设置已更新~ + 设置失败! + 第三方 + 名称 + 作者 + 版本 + 许可证 + 免责申明 + 1. 本软件只提供视频解析,不提供任何资源上传、存储到服务器的功能。 + 2. 本软件仅解析来自B站的内容,不会对解析到的音视频进行二次编码,部分视频会进行有限的格式转换、拼接等操作。 + 3. 本软件解析得到的所有内容均来自B站UP主上传、分享,其版权均归原作者所有。内容提供者、上传者(UP主)应对其提供、上传的内容承担全部责任。 + 4. 本软件提供的所有资源,仅可用作学习交流使用,未经原作者授权,禁止用于其他用途。请在下载24小时内删除。为尊重作者版权,请前往资源的原始发布网站观看,支持原创,谢谢。 + 5. 任何涉及商业盈利目的均不得使用,否则产生的一切后果将由您自己承担。 + 6. 因使用本软件产生的版权问题,软件作者概不负责。 + + + B站助手 + 去水印 + 音视频分离 + + + 取消 + 请选择文件夹 + + + 设置下载文件夹 + 位置: + 浏览 + 盘剩余空间: + 设此文件夹为默认下载文件夹 + 选中后下次将不会弹出此窗口 + 下载 + + 文件夹路径不能为空 + + + 选择解析项 + + 解析选中项 + 解析当前页视频 + 解析所有视频 + 设为默认,下次不再弹出 + + \ No newline at end of file diff --git a/DownKyi/Languages/zh_CN.xaml b/DownKyi/Languages/zh_CN.xaml new file mode 100644 index 0000000..28994d8 --- /dev/null +++ b/DownKyi/Languages/zh_CN.xaml @@ -0,0 +1,174 @@ + + + + 哔哩下载姬 + 未知 + + + 关闭 + 最大化 + 最小化 + 还原 + 皮肤 + + + 登录 + 请输入B站网址链接或av、BV号等…… + 请输入B站视频播放地址…… + 设置 + 下载管理 + 工具箱 + + + 扫描二维码登录 + 请使用哔哩哔哩客户端 扫码登录 或扫码下载APP + 获取登录链接失败! + 密钥错误!尝试重新获取! + 已超时!尝试重新获取二维码! + 登录成功!(3秒后自动回到主页) + 未保存登录信息!(3秒后自动回到主页) + + + 复制封面图片 + 复制封面URL + 播放 + 弹幕 + 点赞 + 投币 + 收藏 + 分享 + 评论 + + 番剧 + 电影 + 纪录片 + 国创 + 电视剧 + 综艺 + 课程 + + 序号 + 名称 + 时长 + 音质 + 画质 + 视频编码 + + 全选 + 解析 + 解析视频 + 下载选中项 + + + 正在下载 + 已下载 + + + 按回车键应用设置 + + 基本 + 下载完成后的动作: + + 关闭程序 + 关闭计算机 + 监听剪贴板 + 视频自动解析 + 视频解析范围: + + 网络 + Aria服务器端口: + Aria日志等级: + Aria同时下载数: + Aria最大线程数: + Aria下载速度限制(KB/s) + 全局下载速度限制[0: 无限制] + 单任务下载速度限制[0: 无限制] + 使用Http代理 + 代理地址: + 端口: + Aria文件预分配: + + 视频 + 优先下载的视频编码: + 优先下载的视频画质: + 启用视频编号 + 勾选后,将为下载完成的视频的文件名添加上序号 + 下载FLV视频后转码为mp4 + 使用默认下载目录 + 默认下载目录: + 默认将文件下载到该文件夹中 + 更改目录 + 为不同视频分别创建文件夹 + 在下载视频的同时下载弹幕 + 在下载视频的同时下载封面 + + 弹幕 + 按类型屏蔽 + 顶部 + 底部 + 滚动 + 分辨率: + 字体名称: + 字体大小: + 限制行数: + 布局算法: + 速度同步 + 每一条滚动弹幕的移动速度都是相同的 + 速度异步 + 弹幕滚动速度取决于它的文本长度 + + 关于 + 访问主页 + 当前版本: + 检查更新 + 意见反馈 + 接收测试版更新 + 启动时检查更新 + 设置已更新~ + 设置失败! + 第三方 + 名称 + 作者 + 版本 + 许可证 + 免责申明 + 1. 本软件只提供视频解析,不提供任何资源上传、存储到服务器的功能。 + 2. 本软件仅解析来自B站的内容,不会对解析到的音视频进行二次编码,部分视频会进行有限的格式转换、拼接等操作。 + 3. 本软件解析得到的所有内容均来自B站UP主上传、分享,其版权均归原作者所有。内容提供者、上传者(UP主)应对其提供、上传的内容承担全部责任。 + 4. 本软件提供的所有资源,仅可用作学习交流使用,未经原作者授权,禁止用于其他用途。请在下载24小时内删除。为尊重作者版权,请前往资源的原始发布网站观看,支持原创,谢谢。 + 5. 任何涉及商业盈利目的均不得使用,否则产生的一切后果将由您自己承担。 + 6. 因使用本软件产生的版权问题,软件作者概不负责。 + + + B站助手 + 去水印 + 音视频分离 + + + 取消 + 请选择文件夹 + + + 设置下载文件夹 + 位置: + 浏览 + 盘剩余空间: + 设此文件夹为默认下载文件夹 + 选中后下次将不会弹出此窗口 + 下载 + + 文件夹路径不能为空 + + + 选择解析项 + + 解析选中项 + 解析当前页视频 + 解析所有视频 + 设为默认,下次不再弹出 + + \ No newline at end of file diff --git a/DownKyi/Languages/zh_TW.xaml b/DownKyi/Languages/zh_TW.xaml new file mode 100644 index 0000000..28994d8 --- /dev/null +++ b/DownKyi/Languages/zh_TW.xaml @@ -0,0 +1,174 @@ + + + + 哔哩下载姬 + 未知 + + + 关闭 + 最大化 + 最小化 + 还原 + 皮肤 + + + 登录 + 请输入B站网址链接或av、BV号等…… + 请输入B站视频播放地址…… + 设置 + 下载管理 + 工具箱 + + + 扫描二维码登录 + 请使用哔哩哔哩客户端 扫码登录 或扫码下载APP + 获取登录链接失败! + 密钥错误!尝试重新获取! + 已超时!尝试重新获取二维码! + 登录成功!(3秒后自动回到主页) + 未保存登录信息!(3秒后自动回到主页) + + + 复制封面图片 + 复制封面URL + 播放 + 弹幕 + 点赞 + 投币 + 收藏 + 分享 + 评论 + + 番剧 + 电影 + 纪录片 + 国创 + 电视剧 + 综艺 + 课程 + + 序号 + 名称 + 时长 + 音质 + 画质 + 视频编码 + + 全选 + 解析 + 解析视频 + 下载选中项 + + + 正在下载 + 已下载 + + + 按回车键应用设置 + + 基本 + 下载完成后的动作: + + 关闭程序 + 关闭计算机 + 监听剪贴板 + 视频自动解析 + 视频解析范围: + + 网络 + Aria服务器端口: + Aria日志等级: + Aria同时下载数: + Aria最大线程数: + Aria下载速度限制(KB/s) + 全局下载速度限制[0: 无限制] + 单任务下载速度限制[0: 无限制] + 使用Http代理 + 代理地址: + 端口: + Aria文件预分配: + + 视频 + 优先下载的视频编码: + 优先下载的视频画质: + 启用视频编号 + 勾选后,将为下载完成的视频的文件名添加上序号 + 下载FLV视频后转码为mp4 + 使用默认下载目录 + 默认下载目录: + 默认将文件下载到该文件夹中 + 更改目录 + 为不同视频分别创建文件夹 + 在下载视频的同时下载弹幕 + 在下载视频的同时下载封面 + + 弹幕 + 按类型屏蔽 + 顶部 + 底部 + 滚动 + 分辨率: + 字体名称: + 字体大小: + 限制行数: + 布局算法: + 速度同步 + 每一条滚动弹幕的移动速度都是相同的 + 速度异步 + 弹幕滚动速度取决于它的文本长度 + + 关于 + 访问主页 + 当前版本: + 检查更新 + 意见反馈 + 接收测试版更新 + 启动时检查更新 + 设置已更新~ + 设置失败! + 第三方 + 名称 + 作者 + 版本 + 许可证 + 免责申明 + 1. 本软件只提供视频解析,不提供任何资源上传、存储到服务器的功能。 + 2. 本软件仅解析来自B站的内容,不会对解析到的音视频进行二次编码,部分视频会进行有限的格式转换、拼接等操作。 + 3. 本软件解析得到的所有内容均来自B站UP主上传、分享,其版权均归原作者所有。内容提供者、上传者(UP主)应对其提供、上传的内容承担全部责任。 + 4. 本软件提供的所有资源,仅可用作学习交流使用,未经原作者授权,禁止用于其他用途。请在下载24小时内删除。为尊重作者版权,请前往资源的原始发布网站观看,支持原创,谢谢。 + 5. 任何涉及商业盈利目的均不得使用,否则产生的一切后果将由您自己承担。 + 6. 因使用本软件产生的版权问题,软件作者概不负责。 + + + B站助手 + 去水印 + 音视频分离 + + + 取消 + 请选择文件夹 + + + 设置下载文件夹 + 位置: + 浏览 + 盘剩余空间: + 设此文件夹为默认下载文件夹 + 选中后下次将不会弹出此窗口 + 下载 + + 文件夹路径不能为空 + + + 选择解析项 + + 解析选中项 + 解析当前页视频 + 解析所有视频 + 设为默认,下次不再弹出 + + \ No newline at end of file diff --git a/DownKyi/Models/AppInfo.cs b/DownKyi/Models/AppInfo.cs new file mode 100644 index 0000000..eedf32b --- /dev/null +++ b/DownKyi/Models/AppInfo.cs @@ -0,0 +1,9 @@ +namespace DownKyi.Models +{ + public class AppInfo + { + public string Name { get; } = "哔哩下载姬"; + public string VersionName { get; } = "1.5.0-alpha1"; + public int VersionCode { get; } = 500; + } +} diff --git a/DownKyi/Models/ParseScopeDisplay.cs b/DownKyi/Models/ParseScopeDisplay.cs new file mode 100644 index 0000000..f7b81d5 --- /dev/null +++ b/DownKyi/Models/ParseScopeDisplay.cs @@ -0,0 +1,10 @@ +using DownKyi.Core.Settings; + +namespace DownKyi.Models +{ + public class ParseScopeDisplay + { + public string Name { get; set; } + public ParseScope ParseScope { get; set; } + } +} diff --git a/DownKyi/Models/Resolution.cs b/DownKyi/Models/Resolution.cs new file mode 100644 index 0000000..84ff490 --- /dev/null +++ b/DownKyi/Models/Resolution.cs @@ -0,0 +1,8 @@ +namespace DownKyi.Models +{ + public class Resolution + { + public string Name { get; set; } + public int Id { get; set; } + } +} diff --git a/DownKyi/Models/TabHeader.cs b/DownKyi/Models/TabHeader.cs new file mode 100644 index 0000000..3fb6b17 --- /dev/null +++ b/DownKyi/Models/TabHeader.cs @@ -0,0 +1,37 @@ +using DownKyi.Images; +using Prism.Mvvm; + +namespace DownKyi.Models +{ + public class TabHeader : BindableBase + { + private int id; + public int Id + { + get { return id; } + set { SetProperty(ref id, value); } + } + + private VectorImage image; + public VectorImage Image + { + get { return image; } + set { SetProperty(ref image, value); } + } + + private string title; + public string Title + { + get { return title; } + set { SetProperty(ref title, value); } + } + + private string subTitle; + public string SubTitle + { + get { return subTitle; } + set { SetProperty(ref subTitle, value); } + } + + } +} diff --git a/DownKyi/Models/VideoInfoView.cs b/DownKyi/Models/VideoInfoView.cs new file mode 100644 index 0000000..7eab89c --- /dev/null +++ b/DownKyi/Models/VideoInfoView.cs @@ -0,0 +1,111 @@ +using Prism.Mvvm; +using System; +using System.Windows.Media.Imaging; + +namespace DownKyi.Models +{ + [Serializable] + public class VideoInfoView : BindableBase + { + public string CoverUrl { get; set; } + + private BitmapImage cover; + public BitmapImage Cover + { + get { return cover; } + set { SetProperty(ref cover, value); } + } + + private string title; + public string Title + { + get { return title; } + set { SetProperty(ref title, value); } + } + + private string videoZone; + public string VideoZone + { + get { return videoZone; } + set { SetProperty(ref videoZone, value); } + } + + private string createTime; + public string CreateTime + { + get { return createTime; } + set { SetProperty(ref createTime, value); } + } + + private string playNumber; + public string PlayNumber + { + get { return playNumber; } + set { SetProperty(ref playNumber, value); } + } + + private string danmakuNumber; + public string DanmakuNumber + { + get { return danmakuNumber; } + set { SetProperty(ref danmakuNumber, value); } + } + + private string likeNumber; + public string LikeNumber + { + get { return likeNumber; } + set { SetProperty(ref likeNumber, value); } + } + + private string coinNumber; + public string CoinNumber + { + get { return coinNumber; } + set { SetProperty(ref coinNumber, value); } + } + + private string favoriteNumber; + public string FavoriteNumber + { + get { return favoriteNumber; } + set { SetProperty(ref favoriteNumber, value); } + } + + private string shareNumber; + public string ShareNumber + { + get { return shareNumber; } + set { SetProperty(ref shareNumber, value); } + } + + private string replyNumber; + public string ReplyNumber + { + get { return replyNumber; } + set { SetProperty(ref replyNumber, value); } + } + + private string description; + public string Description + { + get { return description; } + set { SetProperty(ref description, value); } + } + + private string upName; + public string UpName + { + get { return upName; } + set { SetProperty(ref upName, value); } + } + + private BitmapImage upHeader; + public BitmapImage UpHeader + { + get { return upHeader; } + set { SetProperty(ref upHeader, value); } + } + + } +} diff --git a/DownKyi/Models/VideoPage.cs b/DownKyi/Models/VideoPage.cs new file mode 100644 index 0000000..11ea48d --- /dev/null +++ b/DownKyi/Models/VideoPage.cs @@ -0,0 +1,73 @@ +using DownKyi.Core.BiliApi.VideoStream.Models; +using Prism.Mvvm; +using System.Collections.Generic; + +namespace DownKyi.Models +{ + public class VideoPage : BindableBase + { + public PlayUrl PlayUrl { get; set; } + + public long Avid { get; set; } + public string Bvid { get; set; } + public long Cid { get; set; } + public long EpisodeId { get; set; } + + private bool isSelected; + public bool IsSelected + { + get { return isSelected; } + set { SetProperty(ref isSelected, value); } + } + + private int order; + public int Order + { + get { return order; } + set { SetProperty(ref order, value); } + } + + private string name; + public string Name + { + get { return name; } + set { SetProperty(ref name, value); } + } + + private string duration; + public string Duration + { + get { return duration; } + set { SetProperty(ref duration, value); } + } + + private List audioQualityFormatList; + public List AudioQualityFormatList + { + get { return audioQualityFormatList; } + set { SetProperty(ref audioQualityFormatList, value); } + } + + private string audioQualityFormat; + public string AudioQualityFormat + { + get { return audioQualityFormat; } + set { SetProperty(ref audioQualityFormat, value); } + } + + private List videoQualityList; + public List VideoQualityList + { + get { return videoQualityList; } + set { SetProperty(ref videoQualityList, value); } + } + + private VideoQuality videoQuality; + public VideoQuality VideoQuality + { + get { return videoQuality; } + set { SetProperty(ref videoQuality, value); } + } + + } +} diff --git a/DownKyi/Models/VideoQuality.cs b/DownKyi/Models/VideoQuality.cs new file mode 100644 index 0000000..6df9996 --- /dev/null +++ b/DownKyi/Models/VideoQuality.cs @@ -0,0 +1,37 @@ +using Prism.Mvvm; +using System.Collections.Generic; + +namespace DownKyi.Models +{ + public class VideoQuality : BindableBase + { + private int quality; + public int Quality + { + get { return quality; } + set { SetProperty(ref quality, value); } + } + + private string qualityFormat; + public string QualityFormat + { + get { return qualityFormat; } + set { SetProperty(ref qualityFormat, value); } + } + + private List videoCodecList; + public List VideoCodecList + { + get { return videoCodecList; } + set { SetProperty(ref videoCodecList, value); } + } + + private string selectedVideoCodec; + public string SelectedVideoCodec + { + get { return selectedVideoCodec; } + set { SetProperty(ref selectedVideoCodec, value); } + } + + } +} diff --git a/DownKyi/Models/VideoSection.cs b/DownKyi/Models/VideoSection.cs new file mode 100644 index 0000000..748bc00 --- /dev/null +++ b/DownKyi/Models/VideoSection.cs @@ -0,0 +1,31 @@ +using Prism.Mvvm; +using System.Collections.Generic; + +namespace DownKyi.Models +{ + public class VideoSection : BindableBase + { + public long Id { get; set; } + + private string title; + public string Title + { + get { return title; } + set { SetProperty(ref title, value); } + } + + private bool isSelected; + public bool IsSelected + { + get { return isSelected; } + set { SetProperty(ref isSelected, value); } + } + + private List videoPages; + public List VideoPages + { + get { return videoPages; } + set { SetProperty(ref videoPages, value); } + } + } +} diff --git a/DownKyi/Properties/AssemblyInfo.cs b/DownKyi/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..557ec1b --- /dev/null +++ b/DownKyi/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DownKyi")] +[assembly: AssemblyDescription("DownKyi")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("DownKyi")] +[assembly: AssemblyProduct("DownKyi")] +[assembly: AssemblyCopyright("Copyright © Downkyi 2020-2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.5.0.0")] +[assembly: AssemblyFileVersion("1.5.0.0")] diff --git a/DownKyi/Properties/Resources.Designer.cs b/DownKyi/Properties/Resources.Designer.cs new file mode 100644 index 0000000..fe85cfb --- /dev/null +++ b/DownKyi/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace DownKyi.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DownKyi.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap loading { + get { + object obj = ResourceManager.GetObject("loading", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/DownKyi/Properties/Resources.resx b/DownKyi/Properties/Resources.resx new file mode 100644 index 0000000..34f9a23 --- /dev/null +++ b/DownKyi/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\resources\loading\loading.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/DownKyi/Properties/Settings.Designer.cs b/DownKyi/Properties/Settings.Designer.cs new file mode 100644 index 0000000..8f48214 --- /dev/null +++ b/DownKyi/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DownKyi.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/DownKyi/Properties/Settings.settings b/DownKyi/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/DownKyi/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/DownKyi/Resources/default_header.jpg b/DownKyi/Resources/default_header.jpg new file mode 100644 index 0000000..5e5ea0b Binary files /dev/null and b/DownKyi/Resources/default_header.jpg differ diff --git a/DownKyi/Resources/favicon.ico b/DownKyi/Resources/favicon.ico new file mode 100644 index 0000000..0145cb9 Binary files /dev/null and b/DownKyi/Resources/favicon.ico differ diff --git a/DownKyi/Resources/loading/loading.gif b/DownKyi/Resources/loading/loading.gif new file mode 100644 index 0000000..31f8504 Binary files /dev/null and b/DownKyi/Resources/loading/loading.gif differ diff --git a/DownKyi/Resources/login/login_top_bar.png b/DownKyi/Resources/login/login_top_bar.png new file mode 100644 index 0000000..68dc5d3 Binary files /dev/null and b/DownKyi/Resources/login/login_top_bar.png differ diff --git a/DownKyi/Resources/login/qrcode_login_2233.png b/DownKyi/Resources/login/qrcode_login_2233.png new file mode 100644 index 0000000..3d9ff56 Binary files /dev/null and b/DownKyi/Resources/login/qrcode_login_2233.png differ diff --git a/DownKyi/Resources/login/qrcode_login_tip.png b/DownKyi/Resources/login/qrcode_login_tip.png new file mode 100644 index 0000000..177018b Binary files /dev/null and b/DownKyi/Resources/login/qrcode_login_tip.png differ diff --git a/DownKyi/Resources/login/scan_succeed.png b/DownKyi/Resources/login/scan_succeed.png new file mode 100644 index 0000000..2e3f72e Binary files /dev/null and b/DownKyi/Resources/login/scan_succeed.png differ diff --git a/DownKyi/Resources/no-data.png b/DownKyi/Resources/no-data.png new file mode 100644 index 0000000..7f1b5c4 Binary files /dev/null and b/DownKyi/Resources/no-data.png differ diff --git a/DownKyi/Services/BangumiInfoService.cs b/DownKyi/Services/BangumiInfoService.cs new file mode 100644 index 0000000..775319d --- /dev/null +++ b/DownKyi/Services/BangumiInfoService.cs @@ -0,0 +1,240 @@ +using DownKyi.Core.BiliApi.Bangumi; +using DownKyi.Core.BiliApi.Bangumi.Models; +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.VideoStream; +using DownKyi.Core.Storage; +using DownKyi.Core.Utils; +using DownKyi.Models; +using DownKyi.Utils; +using System; +using System.Collections.Generic; +using System.Windows.Media.Imaging; + +namespace DownKyi.Services +{ + public class BangumiInfoService : IInfoService + { + private readonly BangumiSeason bangumiSeason; + + public BangumiInfoService(string input) + { + if (input == null) + { + return; + } + + if (ParseEntrance.IsBangumiSeasonId(input) || ParseEntrance.IsBangumiSeasonUrl(input)) + { + long seasonId = ParseEntrance.GetBangumiSeasonId(input); + bangumiSeason = BangumiInfo.BangumiSeasonInfo(seasonId); + } + + if (ParseEntrance.IsBangumiEpisodeId(input) || ParseEntrance.IsBangumiEpisodeUrl(input)) + { + long episodeId = ParseEntrance.GetBangumiEpisodeId(input); + bangumiSeason = BangumiInfo.BangumiSeasonInfo(-1, episodeId); + } + + if (ParseEntrance.IsBangumiMediaId(input) || ParseEntrance.IsBangumiMediaUrl(input)) + { + long mediaId = ParseEntrance.GetBangumiMediaId(input); + var bangumiMedia = BangumiInfo.BangumiMediaInfo(mediaId); + bangumiSeason = BangumiInfo.BangumiSeasonInfo(bangumiMedia.SeasonId); + } + } + + /// + /// 获取视频剧集 + /// + /// + public List GetVideoPages() + { + List pages = new List(); + if (bangumiSeason == null) { return pages; } + if (bangumiSeason.Episodes == null) { return pages; } + if (bangumiSeason.Episodes.Count == 0) { return pages; } + + int order = 0; + foreach (var episode in bangumiSeason.Episodes) + { + order++; + + // 标题 + string name; + + // 判断title是否为数字,如果是,则将share_copy作为name,否则将title作为name + if (int.TryParse(episode.Title, out int result)) + { + name = episode.ShareCopy; + } + else + { + if (episode.LongTitle != null && episode.LongTitle != "") + { + name = $"{episode.Title} {episode.LongTitle}"; + } + else + { + name = episode.Title; + } + } + + VideoPage page = new VideoPage + { + Avid = episode.Aid, + Bvid = episode.Bvid, + Cid = episode.Cid, + EpisodeId = -1, + Order = order, + Name = name, + Duration = "N/A" + }; + pages.Add(page); + } + + return pages; + } + + /// + /// 获取视频章节与剧集 + /// + /// + public List GetVideoSections() + { + if (bangumiSeason == null) { return null; } + if (bangumiSeason.Section == null) { return null; } + if (bangumiSeason.Section.Count == 0) { return null; } + + List videoSections = new List + { + new VideoSection + { + Id = bangumiSeason.Positive.Id, + Title = bangumiSeason.Positive.Title, + IsSelected = true, + VideoPages = GetVideoPages() + } + }; + + foreach (var section in bangumiSeason.Section) + { + List pages = new List(); + int order = 0; + foreach (var episode in section.Episodes) + { + order++; + + // 标题 + string name; + if (episode.LongTitle != null && episode.LongTitle != "") + { + name = $"{episode.Title} {episode.LongTitle}"; + } + else + { + name = episode.Title; + } + + VideoPage page = new VideoPage + { + Avid = episode.Aid, + Bvid = episode.Bvid, + Cid = episode.Cid, + EpisodeId = -1, + Order = order, + Name = name, + Duration = "N/A" + }; + pages.Add(page); + } + + VideoSection videoSection = new VideoSection + { + Id = section.Id, + Title = section.Title, + VideoPages = pages + }; + videoSections.Add(videoSection); + } + + return videoSections; + } + + /// + /// 获取视频流的信息,从VideoPage返回 + /// + /// + public void GetVideoStream(VideoPage page) + { + var playUrl = VideoStream.GetBangumiPlayUrl(page.Avid, page.Bvid, page.Cid); + Utils.VideoPageInfo(playUrl, page); + } + + /// + /// 获取视频信息 + /// + /// + public VideoInfoView GetVideoView() + { + if (bangumiSeason == null) { return null; } + + + // 查询、保存封面 + // 将SeasonId保存到avid字段中 + // 每集封面的cid保存到cid字段,EpisodeId保存到bvid字段中 + StorageCover storageCover = new StorageCover(); + string coverUrl = bangumiSeason.Cover; + string cover = storageCover.GetCover(bangumiSeason.SeasonId, "", -1, coverUrl); + + // 获取用户头像 + string upName; + string header; + if (bangumiSeason.UpInfo != null) + { + upName = bangumiSeason.UpInfo.Name; + + StorageHeader storageHeader = new StorageHeader(); + header = storageHeader.GetHeader(bangumiSeason.UpInfo.Mid, bangumiSeason.UpInfo.Name, bangumiSeason.UpInfo.Avatar); + } + else + { + upName = ""; + header = null; + } + + // 为videoInfoView赋值 + VideoInfoView videoInfoView = new VideoInfoView(); + App.PropertyChangeAsync(new Action(() => + { + videoInfoView.CoverUrl = coverUrl; + + videoInfoView.Cover = new BitmapImage(new Uri(cover)); + videoInfoView.Title = bangumiSeason.Title; + + videoInfoView.VideoZone = DictionaryResource.GetString(BangumiType.Type[bangumiSeason.Type]); + + videoInfoView.PlayNumber = Format.FormatNumber(bangumiSeason.Stat.Views); + videoInfoView.DanmakuNumber = Format.FormatNumber(bangumiSeason.Stat.Danmakus); + videoInfoView.LikeNumber = Format.FormatNumber(bangumiSeason.Stat.Likes); + videoInfoView.CoinNumber = Format.FormatNumber(bangumiSeason.Stat.Coins); + videoInfoView.FavoriteNumber = Format.FormatNumber(bangumiSeason.Stat.Favorites); + videoInfoView.ShareNumber = Format.FormatNumber(bangumiSeason.Stat.Share); + videoInfoView.ReplyNumber = Format.FormatNumber(bangumiSeason.Stat.Reply); + videoInfoView.Description = bangumiSeason.Evaluate; + + videoInfoView.UpName = upName; + if (header != null) + { + StorageHeader storageHeader = new StorageHeader(); + videoInfoView.UpHeader = storageHeader.GetHeaderThumbnail(header, 48, 48); + } + else + { + videoInfoView.UpHeader = null; + } + })); + + return videoInfoView; + } + } +} diff --git a/DownKyi/Services/CheeseInfoService.cs b/DownKyi/Services/CheeseInfoService.cs new file mode 100644 index 0000000..92b7196 --- /dev/null +++ b/DownKyi/Services/CheeseInfoService.cs @@ -0,0 +1,160 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.Cheese; +using DownKyi.Core.BiliApi.Cheese.Models; +using DownKyi.Core.BiliApi.VideoStream; +using DownKyi.Core.Storage; +using DownKyi.Core.Utils; +using DownKyi.Models; +using DownKyi.Utils; +using System; +using System.Collections.Generic; +using System.Windows.Media.Imaging; + +namespace DownKyi.Services +{ + public class CheeseInfoService : IInfoService + { + private readonly CheeseView cheeseView; + + public CheeseInfoService(string input) + { + if (input == null) + { + return; + } + + if (ParseEntrance.IsCheeseSeasonUrl(input)) + { + long seasonId = ParseEntrance.GetCheeseSeasonId(input); + cheeseView = CheeseInfo.CheeseViewInfo(seasonId); + } + + if (ParseEntrance.IsCheeseEpisodeUrl(input)) + { + long episodeId = ParseEntrance.GetCheeseEpisodeId(input); + cheeseView = CheeseInfo.CheeseViewInfo(-1, episodeId); + } + } + + /// + /// 获取视频剧集 + /// + /// + public List GetVideoPages() + { + List pages = new List(); + if (cheeseView == null) { return pages; } + if (cheeseView.Episodes == null) { return pages; } + if (cheeseView.Episodes.Count == 0) { return pages; } + + int order = 0; + foreach (var episode in cheeseView.Episodes) + { + order++; + string name = episode.Title; + + string duration = Format.FormatDuration(episode.Duration - 1); + + VideoPage page = new VideoPage + { + Avid = episode.Aid, + Bvid = null, + Cid = episode.Cid, + EpisodeId = episode.Id, + Order = order, + Name = name, + Duration = "N/A" + }; + pages.Add(page); + } + + return pages; + } + + /// + /// 获取视频章节与剧集 + /// + /// + public List GetVideoSections() + { + return null; + } + + /// + /// 获取视频流的信息,从VideoPage返回 + /// + /// + public void GetVideoStream(VideoPage page) + { + var playUrl = VideoStream.GetCheesePlayUrl(page.Avid, page.Bvid, page.Cid, page.EpisodeId); + Utils.VideoPageInfo(playUrl, page); + } + + /// + /// 获取视频信息 + /// + /// + public VideoInfoView GetVideoView() + { + if (cheeseView == null) { return null; } + + + // 查询、保存封面 + // 将SeasonId保存到avid字段中 + // 每集封面的cid保存到cid字段,EpisodeId保存到bvid字段中 + StorageCover storageCover = new StorageCover(); + string coverUrl = cheeseView.Cover; + string cover = storageCover.GetCover(cheeseView.SeasonId, "", -1, coverUrl); + + // 获取用户头像 + string upName; + string header; + if (cheeseView.UpInfo != null) + { + upName = cheeseView.UpInfo.Name; + StorageHeader storageHeader = new StorageHeader(); + header = storageHeader.GetHeader(cheeseView.UpInfo.Mid, cheeseView.UpInfo.Name, cheeseView.UpInfo.Avatar); + } + else + { + upName = ""; + header = null; + } + + // 为videoInfoView赋值 + VideoInfoView videoInfoView = new VideoInfoView(); + App.PropertyChangeAsync(new Action(() => + { + videoInfoView.CoverUrl = coverUrl; + + videoInfoView.Cover = new BitmapImage(new Uri(cover)); + videoInfoView.Title = cheeseView.Title; + + videoInfoView.VideoZone = DictionaryResource.GetString("Cheese"); + videoInfoView.CreateTime = ""; + + videoInfoView.PlayNumber = Format.FormatNumber(cheeseView.Stat.Play); + videoInfoView.DanmakuNumber = Format.FormatNumber(0); + videoInfoView.LikeNumber = Format.FormatNumber(0); + videoInfoView.CoinNumber = Format.FormatNumber(0); + videoInfoView.FavoriteNumber = Format.FormatNumber(0); + videoInfoView.ShareNumber = Format.FormatNumber(0); + videoInfoView.ReplyNumber = Format.FormatNumber(0); + videoInfoView.Description = cheeseView.Subtitle; + + videoInfoView.UpName = upName; + if (header != null) + { + StorageHeader storageHeader = new StorageHeader(); + videoInfoView.UpHeader = storageHeader.GetHeaderThumbnail(header, 48, 48); + } + else + { + videoInfoView.UpHeader = null; + } + })); + + return videoInfoView; + } + } +} diff --git a/DownKyi/Services/IInfoService.cs b/DownKyi/Services/IInfoService.cs new file mode 100644 index 0000000..4aacf84 --- /dev/null +++ b/DownKyi/Services/IInfoService.cs @@ -0,0 +1,16 @@ +using DownKyi.Models; +using System.Collections.Generic; + +namespace DownKyi.Services +{ + public interface IInfoService + { + VideoInfoView GetVideoView(); + + List GetVideoSections(); + + List GetVideoPages(); + + void GetVideoStream(VideoPage page); + } +} diff --git a/DownKyi/Services/IResolutionService.cs b/DownKyi/Services/IResolutionService.cs new file mode 100644 index 0000000..d1c236a --- /dev/null +++ b/DownKyi/Services/IResolutionService.cs @@ -0,0 +1,10 @@ +using DownKyi.Models; +using System.Collections.Generic; + +namespace DownKyi.Services +{ + public interface IResolutionService + { + List GetResolution(); + } +} diff --git a/DownKyi/Services/ResolutionService.cs b/DownKyi/Services/ResolutionService.cs new file mode 100644 index 0000000..a298ab1 --- /dev/null +++ b/DownKyi/Services/ResolutionService.cs @@ -0,0 +1,26 @@ +using DownKyi.Models; +using System.Collections.Generic; + +namespace DownKyi.Services +{ + public class ResolutionService : IResolutionService + { + public List GetResolution() + { + List resolutions = new List + { + new Resolution { Name = "HDR 真彩", Id = 125 }, + new Resolution { Name = "4K 超清", Id = 120 }, + new Resolution { Name = "1080P 60帧", Id = 116 }, + new Resolution { Name = "1080P 高码率", Id = 112 }, + new Resolution { Name = "1080P 高清", Id = 80 }, + new Resolution { Name = "720P 60帧", Id = 74 }, + new Resolution { Name = "720P 高清", Id = 64 }, + new Resolution { Name = "480P 清晰", Id = 32 }, + new Resolution { Name = "360P 流畅", Id = 16 } + }; + + return resolutions; + } + } +} diff --git a/DownKyi/Services/Utils.cs b/DownKyi/Services/Utils.cs new file mode 100644 index 0000000..3807f04 --- /dev/null +++ b/DownKyi/Services/Utils.cs @@ -0,0 +1,210 @@ +using DownKyi.Core.BiliApi.VideoStream.Models; +using DownKyi.Core.Settings; +using DownKyi.Core.Settings.Models; +using DownKyi.Core.Utils; +using DownKyi.Models; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.Services +{ + internal static class Utils + { + /// + /// 从视频流更新VideoPage + /// + /// + /// + internal static void VideoPageInfo(PlayUrl playUrl, VideoPage page) + { + if (playUrl == null) + { + return; + } + + // 视频流信息 + page.PlayUrl = playUrl; + + // 获取设置 + var userInfo = SettingsManager.GetInstance().GetUserInfo(); + int defaultQuality = SettingsManager.GetInstance().GetQuality(); + var videoCodecs = SettingsManager.GetInstance().GetVideoCodecs(); + int defaultAudioQuality = SettingsManager.GetInstance().GetAudioQuality(); + + // 未登录时,最高仅720P + if (userInfo.Mid == -1) + { + if (defaultQuality > 64) + { + defaultQuality = 64; + } + } + + // 非大会员账户登录时,如果设置的画质高于1080P,则这里限制为1080P + if (!userInfo.IsVip) + { + if (defaultQuality > 80) + { + defaultQuality = 80; + } + } + + if (playUrl.Durl != null) + { + // 音质 + + // 画质 + + // 视频编码 + + // 时长 + + return; + } + + if (playUrl.Dash != null) + { + // 如果video列表或者audio列表没有内容,则返回false + if (playUrl.Dash.Video == null) { return; } + if (playUrl.Dash.Video.Count == 0) { return; } + + // 音质 + page.AudioQualityFormatList = GetAudioQualityFormatList(playUrl, defaultAudioQuality); + if (page.AudioQualityFormatList.Count > 0) + { + page.AudioQualityFormat = page.AudioQualityFormatList[0]; + } + + // 画质 & 视频编码 + page.VideoQualityList = GetVideoQualityList(playUrl, userInfo, defaultQuality, videoCodecs); + if (page.VideoQualityList.Count > 0) + { + page.VideoQuality = page.VideoQualityList[0]; + } + + // 时长 + page.Duration = Format.FormatDuration(playUrl.Dash.Duration); + } + } + + /// + /// 设置音质 + /// + /// + /// + /// + private static List GetAudioQualityFormatList(PlayUrl playUrl, int defaultAudioQuality) + { + List audioQualityFormatList = new List(); + foreach (var audio in playUrl.Dash.Audio) + { + // 音质id大于设置画质时,跳过 + if (audio.Id > defaultAudioQuality) { continue; } + + if (Core.BiliApi.BiliUtils.Constant.AudioQuality.ContainsKey(audio.Id)) + { + ListHelper.AddUnique(audioQualityFormatList, Core.BiliApi.BiliUtils.Constant.AudioQuality[audio.Id]); + } + } + + audioQualityFormatList.Sort(new StringLogicalComparer()); + audioQualityFormatList.Reverse(); + + return audioQualityFormatList; + } + + /// + /// 设置画质 & 视频编码 + /// + /// + /// + /// + /// + /// + private static List GetVideoQualityList(PlayUrl playUrl, UserInfoSettings userInfo, int defaultQuality, VideoCodecs videoCodecs) + { + List videoQualityList = new List(); + foreach (var video in playUrl.Dash.Video) + { + // 画质id大于设置画质时,跳过 + if (video.Id > defaultQuality) { continue; } + + // 非大会员账户登录时 + if (!userInfo.IsVip) + { + // 如果画质为720P60,跳过 + if (video.Id == 74) { continue; } + } + + string qualityFormat = string.Empty; + var selectedQuality = playUrl.SupportFormats.FirstOrDefault(t => t.Quality == video.Id); + if (selectedQuality != null) + { + qualityFormat = selectedQuality.NewDescription; + } + + // 寻找是否已存在这个画质 + // 不存在则添加,存在则修改 + string codecName = GetVideoCodecName(video.Codecs); + var videoQualityExist = videoQualityList.FirstOrDefault(t => t.Quality == video.Id); + if (videoQualityExist == null) + { + var videoCodecList = new List(); + ListHelper.AddUnique(videoCodecList, codecName); + + var videoQuality = new VideoQuality() + { + Quality = video.Id, + QualityFormat = qualityFormat, + VideoCodecList = videoCodecList + }; + videoQualityList.Add(videoQuality); + } + else + { + if (!videoQualityList[videoQualityList.IndexOf(videoQualityExist)].VideoCodecList.Exists(t => t.Equals(codecName))) + { + videoQualityList[videoQualityList.IndexOf(videoQualityExist)].VideoCodecList.Add(codecName); + } + } + + // 设置选中的视频编码 + var selectedVideoQuality = videoQualityList.FirstOrDefault(t => t.Quality == video.Id); + switch (videoCodecs) + { + case VideoCodecs.AVC: + if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.264/AVC")) + { + videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.264/AVC"; + } + break; + case VideoCodecs.HEVC: + if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Contains("H.265/HEVC")) + { + videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = "H.265/HEVC"; + } + break; + } + + if (videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList.Count == 1) + { + // 当获取的视频没有设置的视频编码时,执行 + videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].SelectedVideoCodec = videoQualityList[videoQualityList.IndexOf(selectedVideoQuality)].VideoCodecList[0]; + } + } + + return videoQualityList; + } + + /// + /// 根据输入的字符串判断是AVC还是HEVC + /// + /// + /// + private static string GetVideoCodecName(string origin) + { + return origin.Contains("avc") ? "H.264/AVC" : origin.Contains("hev") ? "H.265/HEVC" : ""; + } + + } +} diff --git a/DownKyi/Services/VideoInfoService.cs b/DownKyi/Services/VideoInfoService.cs new file mode 100644 index 0000000..c34585d --- /dev/null +++ b/DownKyi/Services/VideoInfoService.cs @@ -0,0 +1,236 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.Video; +using DownKyi.Core.BiliApi.Video.Models; +using DownKyi.Core.BiliApi.VideoStream; +using DownKyi.Core.Storage; +using DownKyi.Core.Utils; +using DownKyi.Models; +using System; +using System.Collections.Generic; +using System.Windows.Media.Imaging; + +namespace DownKyi.Services +{ + public class VideoInfoService : IInfoService + { + private readonly VideoView videoView; + + public VideoInfoService(string input) + { + if (input == null) + { + return; + } + + if (ParseEntrance.IsAvId(input) || ParseEntrance.IsAvUrl(input)) + { + long avid = ParseEntrance.GetAvId(input); + videoView = VideoInfo.VideoViewInfo(null, avid); + } + + if (ParseEntrance.IsBvId(input) || ParseEntrance.IsBvUrl(input)) + { + string bvid = ParseEntrance.GetBvId(input); + videoView = VideoInfo.VideoViewInfo(bvid); + } + } + + /// + /// 获取视频剧集 + /// + /// + public List GetVideoPages() + { + if (videoView == null) { return null; } + if (videoView.Pages == null) { return null; } + if (videoView.Pages.Count == 0) { return null; } + + List videoPages = new List(); + + int order = 0; + foreach (var page in videoView.Pages) + { + order++; + + // 标题 + string name; + if (videoView.Pages.Count == 1) + { + name = videoView.Title; + } + else + { + //name = page.part; + if (page.Part == "") + { + // 如果page.part为空字符串 + name = $"{videoView.Title}-P{order}"; + } + else + { + name = page.Part; + } + } + + Models.VideoPage videoPage = new Models.VideoPage + { + Avid = videoView.Aid, + Bvid = videoView.Bvid, + Cid = page.Cid, + EpisodeId = -1, + Order = order, + Name = name, + Duration = "N/A" + }; + videoPages.Add(videoPage); + } + + return videoPages; + } + + /// + /// 获取视频章节与剧集 + /// + /// + public List GetVideoSections() + { + if (videoView == null) { return null; } + if (videoView.UgcSeason == null) { return null; } + if (videoView.UgcSeason.Sections == null) { return null; } + if (videoView.UgcSeason.Sections.Count == 0) { return null; } + + List videoSections = new List(); + + foreach (var section in videoView.UgcSeason.Sections) + { + List pages = new List(); + int order = 0; + foreach (var episode in section.Episodes) + { + order++; + Models.VideoPage page = new Models.VideoPage + { + Avid = episode.Aid, + Bvid = episode.Bvid, + Cid = episode.Cid, + EpisodeId = -1, + Order = order, + Name = episode.Title, + Duration = "N/A" + }; + pages.Add(page); + } + + VideoSection videoSection = new VideoSection + { + Id = section.Id, + Title = section.Title, + VideoPages = pages + }; + videoSections.Add(videoSection); + } + + videoSections[0].IsSelected = true; + + return videoSections; + } + + /// + /// 获取视频流的信息,从VideoPage返回 + /// + /// + public void GetVideoStream(Models.VideoPage page) + { + var playUrl = VideoStream.GetVideoPlayUrl(page.Avid, page.Bvid, page.Cid); + Utils.VideoPageInfo(playUrl, page); + } + + /// + /// 获取视频信息 + /// + /// + public VideoInfoView GetVideoView() + { + if (videoView == null) { return null; } + + // 查询、保存封面 + StorageCover storageCover = new StorageCover(); + string coverUrl = videoView.Pic; + string cover = storageCover.GetCover(videoView.Aid, videoView.Bvid, videoView.Cid, coverUrl); + + // 分区 + string videoZone = string.Empty; + var zoneList = Core.BiliApi.Zone.VideoZone.Instance().GetZone(); + var zone = zoneList.Find(it => it.Id == videoView.Tid); + if (zone != null) + { + var zoneParent = zoneList.Find(it => it.Id == zone.ParentId); + if (zoneParent != null) + { + videoZone = zoneParent.Name + ">" + zone.Name; + } + else + { + videoZone = zone.Name; + } + } + else + { + videoZone = videoView.Tname; + } + + // 获取用户头像 + string upName; + string header; + if (videoView.Owner != null) + { + upName = videoView.Owner.Name; + StorageHeader storageHeader = new StorageHeader(); + header = storageHeader.GetHeader(videoView.Owner.Mid, videoView.Owner.Name, videoView.Owner.Face); + } + else + { + upName = ""; + header = null; + } + + // 为videoInfoView赋值 + VideoInfoView videoInfoView = new VideoInfoView(); + App.PropertyChangeAsync(new Action(() => + { + videoInfoView.CoverUrl = coverUrl; + + videoInfoView.Cover = new BitmapImage(new Uri(cover)); + videoInfoView.Title = videoView.Title; + + videoInfoView.VideoZone = videoZone; + + DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区 + DateTime dateTime = startTime.AddSeconds(videoView.Pubdate); + videoInfoView.CreateTime = dateTime.ToString("yyyy-MM-dd HH:mm:ss"); + + videoInfoView.PlayNumber = Format.FormatNumber(videoView.Stat.View); + videoInfoView.DanmakuNumber = Format.FormatNumber(videoView.Stat.Danmaku); + videoInfoView.LikeNumber = Format.FormatNumber(videoView.Stat.Like); + videoInfoView.CoinNumber = Format.FormatNumber(videoView.Stat.Coin); + videoInfoView.FavoriteNumber = Format.FormatNumber(videoView.Stat.Favorite); + videoInfoView.ShareNumber = Format.FormatNumber(videoView.Stat.Share); + videoInfoView.ReplyNumber = Format.FormatNumber(videoView.Stat.Reply); + videoInfoView.Description = videoView.Desc; + + videoInfoView.UpName = upName; + if (header != null) + { + StorageHeader storageHeader = new StorageHeader(); + videoInfoView.UpHeader = storageHeader.GetHeaderThumbnail(header, 48, 48); + } + else + { + videoInfoView.UpHeader = null; + } + })); + + return videoInfoView; + } + } +} diff --git a/DownKyi/Themes/ColorBrush.xaml b/DownKyi/Themes/ColorBrush.xaml new file mode 100644 index 0000000..ec39583 --- /dev/null +++ b/DownKyi/Themes/ColorBrush.xaml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Colors/ColorDefault.xaml b/DownKyi/Themes/Colors/ColorDefault.xaml new file mode 100644 index 0000000..e3e3a26 --- /dev/null +++ b/DownKyi/Themes/Colors/ColorDefault.xaml @@ -0,0 +1,43 @@ + + + Black + Black + white + + white + black + #FF6ECEF8 + #FF30B8F6 + #FFE81123 + #FFF1707A + + #FF00A1D6 + #C800A1D6 + #7F00A1D6 + #3300A1D6 + #FF00A1D6 + #FFFFFFFF + #FFFFFFFF + #FF00A1D6 + #FFBDBDBD + #FFBDBDBD + #C8BDBDBD + #7FBDBDBD + #33BDBDBD + + #FFF4F4F4 + + #FFF4F4F4 + #FF999999 + + #7FD0D0D0 + #7FD0D0D0 + + white + black + #FF999999 + + \ No newline at end of file diff --git a/DownKyi/Themes/Colors/ColorDiy.xaml b/DownKyi/Themes/Colors/ColorDiy.xaml new file mode 100644 index 0000000..268726e --- /dev/null +++ b/DownKyi/Themes/Colors/ColorDiy.xaml @@ -0,0 +1,29 @@ + + + Black + Black + #7FD0D0D0 + + white + black + #FF6ECEF8 + #FF30B8F6 + #FFF1707A + #FFE81123 + + #FF00A1D6 + #FF00A1D6 + #FFFFFFFF + #FFFFFFFF + #FF00A1D6 + + #7FD0D0D0 + #7FD0D0D0 + + white + black + + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleBtn.xaml b/DownKyi/Themes/Styles/StyleBtn.xaml new file mode 100644 index 0000000..dd31b21 --- /dev/null +++ b/DownKyi/Themes/Styles/StyleBtn.xaml @@ -0,0 +1,73 @@ + + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleCheckBox.xaml b/DownKyi/Themes/Styles/StyleCheckBox.xaml new file mode 100644 index 0000000..306c924 --- /dev/null +++ b/DownKyi/Themes/Styles/StyleCheckBox.xaml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleImageBtn.xaml b/DownKyi/Themes/Styles/StyleImageBtn.xaml new file mode 100644 index 0000000..be1214b --- /dev/null +++ b/DownKyi/Themes/Styles/StyleImageBtn.xaml @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleListBox.xaml b/DownKyi/Themes/Styles/StyleListBox.xaml new file mode 100644 index 0000000..0cd9181 --- /dev/null +++ b/DownKyi/Themes/Styles/StyleListBox.xaml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleListView.xaml b/DownKyi/Themes/Styles/StyleListView.xaml new file mode 100644 index 0000000..cf96bc8 --- /dev/null +++ b/DownKyi/Themes/Styles/StyleListView.xaml @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleRadio.xaml b/DownKyi/Themes/Styles/StyleRadio.xaml new file mode 100644 index 0000000..4b1ea85 --- /dev/null +++ b/DownKyi/Themes/Styles/StyleRadio.xaml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Styles/StyleSystemBtn.xaml b/DownKyi/Themes/Styles/StyleSystemBtn.xaml new file mode 100644 index 0000000..3e623e8 --- /dev/null +++ b/DownKyi/Themes/Styles/StyleSystemBtn.xaml @@ -0,0 +1,68 @@ + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/ThemeDefault.xaml b/DownKyi/Themes/ThemeDefault.xaml new file mode 100644 index 0000000..69411e4 --- /dev/null +++ b/DownKyi/Themes/ThemeDefault.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/ThemeDiy.xaml b/DownKyi/Themes/ThemeDiy.xaml new file mode 100644 index 0000000..284db2a --- /dev/null +++ b/DownKyi/Themes/ThemeDiy.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi/Utils/ClipboardHooker.cs b/DownKyi/Utils/ClipboardHooker.cs new file mode 100644 index 0000000..60048c9 --- /dev/null +++ b/DownKyi/Utils/ClipboardHooker.cs @@ -0,0 +1,45 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Interop; + +namespace DownKyi.Utils +{ + public class ClipboardHooker : IDisposable + { + private const int WM_CLIPBOARDUPDATE = 0x031D; + + [DllImport("User32.dll")] + private static extern bool AddClipboardFormatListener(IntPtr hwnd); + + private readonly HwndSource _hwndSource = null; + + public void Dispose() + { + _hwndSource?.Dispose(); + } + + public ClipboardHooker(Window window) + { + WindowInteropHelper helper = new WindowInteropHelper(window); + _hwndSource = HwndSource.FromHwnd(helper.Handle); + bool r = AddClipboardFormatListener(_hwndSource.Handle); + if (r) + { + _hwndSource.AddHook(new HwndSourceHook(OnHooked)); + } + } + + private IntPtr OnHooked(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + if (msg == WM_CLIPBOARDUPDATE) + { + ClipboardUpdated?.Invoke(this, EventArgs.Empty); + return IntPtr.Zero; + } + return IntPtr.Zero; + } + + public event EventHandler ClipboardUpdated; + } +} diff --git a/DownKyi/Utils/DialogUtils.cs b/DownKyi/Utils/DialogUtils.cs new file mode 100644 index 0000000..48bc315 --- /dev/null +++ b/DownKyi/Utils/DialogUtils.cs @@ -0,0 +1,26 @@ +using System.Windows.Forms; + +namespace DownKyi.Utils +{ + public static class DialogUtils + { + + /// + /// 弹出选择文件夹弹窗 + /// + /// + public static string SetDownloadDirectory() + { + // 选择文件夹 + FolderBrowserDialog dialog = new FolderBrowserDialog + { + Description = DictionaryResource.GetString("SelectDirectory") + }; + + DialogResult showDialog = dialog.ShowDialog(); + return showDialog == DialogResult.OK || showDialog == DialogResult.Yes + ? string.IsNullOrEmpty(dialog.SelectedPath) ? "" : dialog.SelectedPath : ""; + } + + } +} diff --git a/DownKyi/Utils/DictionaryResource.cs b/DownKyi/Utils/DictionaryResource.cs new file mode 100644 index 0000000..93290d8 --- /dev/null +++ b/DownKyi/Utils/DictionaryResource.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Windows; +using System.Windows.Media; + +namespace DownKyi.Utils +{ + public static class DictionaryResource + { + + /// + /// 从资源获取颜色的16进制字符串 + /// + /// + /// + public static string GetColor(string resourceKey) + { + Color color = (Color)Application.Current.Resources[resourceKey]; + return color.ToString(); + } + + /// + /// 从资源获取字符串 + /// + /// + /// + public static string GetString(string resourceKey) + { + return (string)Application.Current.Resources[resourceKey]; + } + + /// + /// 根据languageCode切换界面语言 + /// + /// 语言-国家代码 + public static void LoadLanguage(string languageCode) + { + LoadXamlDictionary(languageCode, "Languages"); + } + + /// + /// 切换主题 + /// + /// 主题 + public static void LoadTheme(string theme) + { + LoadXamlDictionary(theme, "Themes"); + } + + /// + /// 更换xaml资源字典 + /// + /// xaml文件名,不包含扩展名 + /// 文件所在包(路径) + private static void LoadXamlDictionary(string fileName, string package) + { + if (string.IsNullOrEmpty(fileName) == false) + { + var dictionariesToRemove = new List(); + + foreach (var dictionary in Application.Current.Resources.MergedDictionaries) + { + if (dictionary.Source.ToString().Contains($"{package}")) + { + dictionariesToRemove.Add(dictionary); + } + } + + foreach (var item in dictionariesToRemove) + { + Application.Current.Resources.MergedDictionaries.Remove(item); + } + + var languageDictionary = new ResourceDictionary() + { + Source = new Uri($"pack://application:,,,/DownKyi;component/{package}/{fileName}.xaml") + }; + + Application.Current.Resources.MergedDictionaries.Add(languageDictionary); + } + } + } +} diff --git a/DownKyi/ViewModels/BaseViewModel.cs b/DownKyi/ViewModels/BaseViewModel.cs new file mode 100644 index 0000000..9710162 --- /dev/null +++ b/DownKyi/ViewModels/BaseViewModel.cs @@ -0,0 +1,48 @@ +using Prism.Events; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Windows; + +namespace DownKyi.ViewModels +{ + public class BaseViewModel : BindableBase, INavigationAware + { + protected readonly IEventAggregator eventAggregator; + protected string ParentView = string.Empty; + + public BaseViewModel(IEventAggregator eventAggregator) + { + this.eventAggregator = eventAggregator; + } + + public bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + public virtual void OnNavigatedFrom(NavigationContext navigationContext) + { + } + + public virtual void OnNavigatedTo(NavigationContext navigationContext) + { + string viewName = navigationContext.Parameters.GetValue("Parent"); + if (viewName != null) + { + ParentView = viewName; + } + } + + + /// + /// 异步修改绑定到UI的属性 + /// + /// + protected void PropertyChangeAsync(Action callback) + { + Application.Current.Dispatcher.Invoke(callback); + } + + } +} diff --git a/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs b/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs new file mode 100644 index 0000000..2da4b97 --- /dev/null +++ b/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs @@ -0,0 +1,134 @@ +using DownKyi.Images; +using DownKyi.Models; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Mvvm; +using Prism.Services.Dialogs; +using System; + +namespace DownKyi.ViewModels.Dialogs +{ + public class BaseDialogViewModel : BindableBase, IDialogAware + { + #region 页面属性申明 + + private string title; + public string Title + { + get { return title; } + set { SetProperty(ref title, value); } + } + + private VectorImage closeIcon; + public VectorImage CloseIcon + { + get { return closeIcon; } + set { SetProperty(ref closeIcon, value); } + } + + #endregion + + public BaseDialogViewModel() + { + #region 属性初始化 + + Title = new AppInfo().Name; + CloseIcon = new VectorImage + { + Height = SystemIcon.Instance().Close.Height, + Width = SystemIcon.Instance().Close.Width, + Data = SystemIcon.Instance().Close.Data, + Fill = SystemIcon.Instance().Close.Fill + }; + + #endregion + + } + + + #region 命令申明 + + // 鼠标进入关闭按钮事件 + private DelegateCommand closeEnterCommand; + public DelegateCommand CloseEnterCommand => closeEnterCommand ?? (closeEnterCommand = new DelegateCommand(ExecuteCloseEnterCommand)); + + /// + /// 鼠标进入关闭按钮事件 + /// + private void ExecuteCloseEnterCommand() + { + SetEnterStyle(CloseIcon); + } + + // 鼠标离开关闭按钮事件 + private DelegateCommand closeLeaveCommand; + public DelegateCommand CloseLeaveCommand => closeLeaveCommand ?? (closeLeaveCommand = new DelegateCommand(ExecuteCloseLeaveCommand)); + + /// + /// 鼠标离开关闭按钮事件 + /// + private void ExecuteCloseLeaveCommand() + { + SetLeaveStyle(CloseIcon); + } + + // 关闭窗口事件 + private DelegateCommand closeCommand; + public DelegateCommand CloseCommand => closeCommand ?? (closeCommand = new DelegateCommand(ExecuteCloseCommand)); + + /// + /// 关闭窗口事件 + /// + private void ExecuteCloseCommand() + { + ButtonResult result = ButtonResult.Cancel; + RaiseRequestClose(new DialogResult(result)); + } + + #endregion + + /// + /// 鼠标进入系统按钮时的图标样式 + /// + /// 图标 + private void SetEnterStyle(VectorImage icon) + { + icon.Fill = DictionaryResource.GetColor("ColorSystemBtnTint"); + } + + /// + /// 鼠标离开系统按钮时的图标样式 + /// + /// 图标 + private void SetLeaveStyle(VectorImage icon) + { + icon.Fill = DictionaryResource.GetColor("ColorSystemBtnTintDark"); + } + + #region 接口实现 + + //触发窗体关闭事件 + public virtual void RaiseRequestClose(IDialogResult dialogResult) + { + RequestClose?.Invoke(dialogResult); + } + + public event Action RequestClose; + + public bool CanCloseDialog() + { + return true; + } + + public void OnDialogClosed() + { + } + + public void OnDialogOpened(IDialogParameters parameters) + { + } + + #endregion + + } +} diff --git a/DownKyi/ViewModels/Dialogs/ViewDirectorySelectorViewModel.cs b/DownKyi/ViewModels/Dialogs/ViewDirectorySelectorViewModel.cs new file mode 100644 index 0000000..8c9643d --- /dev/null +++ b/DownKyi/ViewModels/Dialogs/ViewDirectorySelectorViewModel.cs @@ -0,0 +1,203 @@ +using DownKyi.Core.Settings; +using DownKyi.Core.Utils; +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Services.Dialogs; +using System.Collections.Generic; + +namespace DownKyi.ViewModels.Dialogs +{ + public class ViewDirectorySelectorViewModel : BaseDialogViewModel + { + public const string Tag = "DialogDirectorySelector"; + private readonly IEventAggregator eventAggregator; + + // 历史文件夹的数量 + private readonly int maxDirectoryListCount = 20; + + #region 页面属性申明 + + private VectorImage cloudDownloadIcon; + public VectorImage CloudDownloadIcon + { + get { return cloudDownloadIcon; } + set { SetProperty(ref cloudDownloadIcon, value); } + } + + private VectorImage folderIcon; + public VectorImage FolderIcon + { + get { return folderIcon; } + set { SetProperty(ref folderIcon, value); } + } + + private bool isDefaultDownloadDirectory; + public bool IsDefaultDownloadDirectory + { + get { return isDefaultDownloadDirectory; } + set { SetProperty(ref isDefaultDownloadDirectory, value); } + } + + private List directoryList; + public List DirectoryList + { + get { return directoryList; } + set { SetProperty(ref directoryList, value); } + } + + private string directory; + public string Directory + { + get { return directory; } + set + { + SetProperty(ref directory, value); + + DriveName = directory.Substring(0, 1).ToUpper(); + DriveNameFreeSpace = Format.FormatFileSize(HardDisk.GetHardDiskFreeSpace(DriveName)); + } + } + + private string driveName; + public string DriveName + { + get { return driveName; } + set { SetProperty(ref driveName, value); } + } + + private string driveNameFreeSpace; + public string DriveNameFreeSpace + { + get { return driveNameFreeSpace; } + set { SetProperty(ref driveNameFreeSpace, value); } + } + + #endregion + + public ViewDirectorySelectorViewModel(IEventAggregator eventAggregator) + { + this.eventAggregator = eventAggregator; + + #region 属性初始化 + + Title = DictionaryResource.GetString("DownloadDirectorySelector"); + + CloudDownloadIcon = NormalIcon.Instance().CloudDownload; + CloudDownloadIcon.Fill = DictionaryResource.GetColor("ColorPrimary"); + + FolderIcon = NormalIcon.Instance().Folder; + FolderIcon.Fill = DictionaryResource.GetColor("ColorPrimary"); + + #endregion + + // 历史下载目录 + DirectoryList = SettingsManager.GetInstance().GetHistoryVideoRootPaths(); + string directory = SettingsManager.GetInstance().GetSaveVideoRootPath(); + if (!DirectoryList.Contains(directory)) + { + ListHelper.InsertUnique(DirectoryList, directory, 0); + } + Directory = directory; + + // 是否使用默认下载目录 + IsDefaultDownloadDirectory = SettingsManager.GetInstance().IsUseSaveVideoRootPath() == AllowStatus.YES; + } + + #region 命令申明 + + // 浏览文件夹事件 + private DelegateCommand browseCommand; + public DelegateCommand BrowseCommand => browseCommand ?? (browseCommand = new DelegateCommand(ExecuteBrowseCommand)); + + /// + /// 浏览文件夹事件 + /// + private void ExecuteBrowseCommand() + { + string directory = SetDirectory(); + + if (directory == null) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("WarningNullDirectory")); + Directory = string.Empty; + } + else + { + ListHelper.InsertUnique(DirectoryList, directory, 0); + Directory = directory; + + if (DirectoryList.Count > maxDirectoryListCount) + { + DirectoryList.RemoveAt(maxDirectoryListCount); + } + } + } + + // 确认下载事件 + private DelegateCommand downloadCommand; + public DelegateCommand DownloadCommand => downloadCommand ?? (downloadCommand = new DelegateCommand(ExecuteDownloadCommand)); + + /// + /// 确认下载事件 + /// + private void ExecuteDownloadCommand() + { + if (Directory == null || Directory == string.Empty) + { + return; + } + + // 设此文件夹为默认下载文件夹 + if (IsDefaultDownloadDirectory) + { + SettingsManager.GetInstance().IsUseSaveVideoRootPath(AllowStatus.YES); + } + else + { + SettingsManager.GetInstance().IsUseSaveVideoRootPath(AllowStatus.NO); + } + + // 将Directory移动到第一项 + // 如果直接在ComboBox中选择的就需要 + // 否则选中项不会在下次出现在第一项 + ListHelper.InsertUnique(DirectoryList, Directory, 0); + + // 将更新后的DirectoryList写入历史中 + SettingsManager.GetInstance().SetSaveVideoRootPath(Directory); + SettingsManager.GetInstance().SetHistoryVideoRootPaths(DirectoryList); + + ButtonResult result = ButtonResult.OK; + IDialogParameters parameters = new DialogParameters + { + { "directory", Directory } + }; + + RaiseRequestClose(new DialogResult(result, parameters)); + } + + #endregion + + /// + /// 设置下载路径 + /// + /// + private string SetDirectory() + { + // 下载目录 + string path; + + // 弹出选择下载目录的窗口 + path = DialogUtils.SetDownloadDirectory(); + if (path == null || path == "") + { + return null; + } + + return path; + } + + } +} diff --git a/DownKyi/ViewModels/Dialogs/ViewParsingSelectorViewModel.cs b/DownKyi/ViewModels/Dialogs/ViewParsingSelectorViewModel.cs new file mode 100644 index 0000000..737c599 --- /dev/null +++ b/DownKyi/ViewModels/Dialogs/ViewParsingSelectorViewModel.cs @@ -0,0 +1,120 @@ +using DownKyi.Core.Settings; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Services.Dialogs; +using System; +using System.Windows; + +namespace DownKyi.ViewModels.Dialogs +{ + public class ViewParsingSelectorViewModel : BaseDialogViewModel + { + public const string Tag = "DialogParsingSelector"; + + #region 页面属性申明 + + private bool isParseDefault; + public bool IsParseDefault + { + get { return isParseDefault; } + set { SetProperty(ref isParseDefault, value); } + } + + #endregion + + public ViewParsingSelectorViewModel() + { + #region 属性初始化 + + Title = DictionaryResource.GetString("ParsingSelector"); + + // 解析范围 + ParseScope parseScope = SettingsManager.GetInstance().GetParseScope(); + IsParseDefault = parseScope != ParseScope.NONE; + + #endregion + + } + + #region 命令申明 + + // 解析当前项事件 + private DelegateCommand parseSelectedItemCommand; + public DelegateCommand ParseSelectedItemCommand => parseSelectedItemCommand ?? (parseSelectedItemCommand = new DelegateCommand(ExecuteParseSelectedItemCommand)); + + /// + /// 解析当前项事件 + /// + private void ExecuteParseSelectedItemCommand() + { + SetParseScopeSetting(ParseScope.SELECTED_ITEM); + + ButtonResult result = ButtonResult.OK; + IDialogParameters parameters = new DialogParameters + { + { "parseScope", ParseScope.SELECTED_ITEM } + }; + + RaiseRequestClose(new DialogResult(result, parameters)); + } + + // 解析当前页视频事件 + private DelegateCommand parseCurrentSectionCommand; + public DelegateCommand ParseCurrentSectionCommand => parseCurrentSectionCommand ?? (parseCurrentSectionCommand = new DelegateCommand(ExecuteParseCurrentSectionCommand)); + + /// + /// 解析当前页视频事件 + /// + private void ExecuteParseCurrentSectionCommand() + { + SetParseScopeSetting(ParseScope.CURRENT_SECTION); + + ButtonResult result = ButtonResult.OK; + IDialogParameters parameters = new DialogParameters + { + { "parseScope", ParseScope.CURRENT_SECTION } + }; + + RaiseRequestClose(new DialogResult(result, parameters)); + } + + // 解析所有视频事件 + private DelegateCommand parseAllCommand; + public DelegateCommand ParseAllCommand => parseAllCommand ?? (parseAllCommand = new DelegateCommand(ExecuteParseAllCommand)); + + /// + /// 解析所有视频事件 + /// + private void ExecuteParseAllCommand() + { + SetParseScopeSetting(ParseScope.ALL); + + ButtonResult result = ButtonResult.OK; + IDialogParameters parameters = new DialogParameters + { + { "parseScope", ParseScope.ALL } + }; + + RaiseRequestClose(new DialogResult(result, parameters)); + } + + #endregion + + /// + /// 写入设置 + /// + /// + private void SetParseScopeSetting(ParseScope parseScope) + { + if (IsParseDefault) + { + SettingsManager.GetInstance().SetParseScope(parseScope); + } + else + { + SettingsManager.GetInstance().SetParseScope(ParseScope.NONE); + } + } + + } +} diff --git a/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs b/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs new file mode 100644 index 0000000..16f97fe --- /dev/null +++ b/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs @@ -0,0 +1,19 @@ +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels.DownloadManager +{ + public class ViewDownloadFinishedViewModel : BaseViewModel + { + public const string Tag = "PageDownloadManagerDownloadFinished"; + + public ViewDownloadFinishedViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + } + } +} diff --git a/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs b/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs new file mode 100644 index 0000000..ba87677 --- /dev/null +++ b/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs @@ -0,0 +1,19 @@ +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels.DownloadManager +{ + public class ViewDownloadingViewModel : BaseViewModel + { + public const string Tag = "PageDownloadManagerDownloading"; + + public ViewDownloadingViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + } + } +} diff --git a/DownKyi/ViewModels/MainWindowViewModel.cs b/DownKyi/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..135f879 --- /dev/null +++ b/DownKyi/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,385 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.Logging; +using DownKyi.Core.Settings; +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Threading; +using System.Windows; +using System.Windows.Threading; + +namespace DownKyi.ViewModels +{ + public class MainWindowViewModel : BindableBase + { + private readonly IEventAggregator eventAggregator; + private ClipboardHooker clipboardHooker; + + #region 页面属性申明 + + private string title; + public string Title + { + get { return title; } + set { SetProperty(ref title, value); } + } + + private WindowState winState; + public WindowState WinState + { + get { return winState; } + set + { + if (value == WindowState.Maximized) + { + ResizeIcon = SystemIcon.Instance().Restore; + } + else + { + ResizeIcon = SystemIcon.Instance().Maximize; + } + SetLeaveStyle(ResizeIcon); + + SetProperty(ref winState, value); + } + } + + private VectorImage minimizeIcon; + public VectorImage MinimizeIcon + { + get { return minimizeIcon; } + set { SetProperty(ref minimizeIcon, value); } + } + + private VectorImage resizeIcon; + public VectorImage ResizeIcon + { + get { return resizeIcon; } + set { SetProperty(ref resizeIcon, value); } + } + + private VectorImage closeIcon; + public VectorImage CloseIcon + { + get { return closeIcon; } + set { SetProperty(ref closeIcon, value); } + } + + private VectorImage skinIcon; + public VectorImage SkinIcon + { + get { return skinIcon; } + set { SetProperty(ref skinIcon, value); } + } + + private Visibility messageVisibility = Visibility.Hidden; + public Visibility MessageVisibility + { + get { return messageVisibility; } + set { SetProperty(ref messageVisibility, value); } + } + + private string message; + public string Message + { + get { return message; } + set { SetProperty(ref message, value); } + } + + #endregion + + public MainWindowViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) + { + this.eventAggregator = eventAggregator; + + #region 属性初始化 + + Window mainWindow = Application.Current.MainWindow; + + WinState = WindowState.Normal; + + MinimizeIcon = SystemIcon.Instance().Minimize; + ResizeIcon = SystemIcon.Instance().Maximize; + CloseIcon = SystemIcon.Instance().Close; + SkinIcon = SystemIcon.Instance().Skin; + + #endregion + + #region 订阅 + + // 订阅导航事件 + eventAggregator.GetEvent().Subscribe((view) => + { + var param = new NavigationParameters + { + { "Parent", view.ParentViewName }, + { "Parameter", view.Parameter } + }; + regionManager.RequestNavigate("ContentRegion", view.ViewName, param); + }); + + // 订阅消息发送事件 + string oldMessage; + eventAggregator.GetEvent().Subscribe((message) => + { + MessageVisibility = Visibility.Visible; + + oldMessage = Message; + Message = message; + int sleep = 2000; + if (oldMessage == Message) { sleep = 1500; } + + Thread.Sleep(sleep); + + MessageVisibility = Visibility.Hidden; + }, ThreadOption.BackgroundThread); + + #endregion + + #region 命令定义 + + // window加载后执行的事件 + LoadedCommand = new DelegateCommand(() => + { + clipboardHooker = new ClipboardHooker(Application.Current.MainWindow); + clipboardHooker.ClipboardUpdated += OnClipboardUpdated; + + var param = new NavigationParameters + { + { "Parent", "" }, + { "Parameter", "start" } + }; + regionManager.RequestNavigate("ContentRegion", ViewIndexViewModel.Tag, param); + }); + + // 顶部caption栏的点击事件,包括双击和拖动 + int times = 0; + DragMoveCommand = new DelegateCommand(() => + { + // caption 双击事件 + times += 1; + DispatcherTimer timer = new DispatcherTimer + { + Interval = new TimeSpan(0, 0, 0, 0, 300) + }; + timer.Tick += (s, e) => { timer.IsEnabled = false; times = 0; }; + timer.IsEnabled = true; + + if (times % 2 == 0) + { + timer.IsEnabled = false; + times = 0; + WinState = WinState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; + } + + // caption 拖动事件 + try + { + mainWindow.DragMove(); + } + catch { } + }); + + // 最小化窗口事件 + MinimizeCommand = new DelegateCommand(() => + { + mainWindow.WindowState = WindowState.Minimized; + }); + MinimizeEnterCommand = new DelegateCommand(() => + { + SetEnterStyle(MinimizeIcon); + }); + MinimizeLeaveCommand = new DelegateCommand(() => + { + SetLeaveStyle(MinimizeIcon); + }); + + // 最大化/还原窗口事件 + ResizeCommand = new DelegateCommand(() => + { + WinState = WinState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; + }); + ResizeEnterCommand = new DelegateCommand(() => + { + SetEnterStyle(ResizeIcon); + }); + ResizeLeaveCommand = new DelegateCommand(() => + { + SetLeaveStyle(ResizeIcon); + }); + + // 关闭窗口事件 + CloseCommand = new DelegateCommand(() => + { + if (clipboardHooker != null) + { + clipboardHooker.ClipboardUpdated -= OnClipboardUpdated; + clipboardHooker.Dispose(); + } + + mainWindow.Close(); + }); + CloseEnterCommand = new DelegateCommand(() => + { + SetEnterStyle(CloseIcon); + }); + CloseLeaveCommand = new DelegateCommand(() => + { + SetLeaveStyle(CloseIcon); + }); + + // 皮肤按钮点击事件 + SkinCommand = new DelegateCommand(() => + { + // 设置主题 + DictionaryResource.LoadTheme("ThemeDiy"); + + // 切换语言 + DictionaryResource.LoadLanguage("en_US"); + }); + SkinEnterCommand = new DelegateCommand(() => + { + SetEnterStyle(SkinIcon); + }); + SkinLeaveCommand = new DelegateCommand(() => + { + SetLeaveStyle(SkinIcon); + }); + + #endregion + + } + + #region 命令申明 + + public DelegateCommand LoadedCommand { get; private set; } + public DelegateCommand DragMoveCommand { get; private set; } + public DelegateCommand MinimizeCommand { get; private set; } + public DelegateCommand MinimizeEnterCommand { get; private set; } + public DelegateCommand MinimizeLeaveCommand { get; private set; } + public DelegateCommand ResizeCommand { get; private set; } + public DelegateCommand ResizeEnterCommand { get; private set; } + public DelegateCommand ResizeLeaveCommand { get; private set; } + public DelegateCommand CloseCommand { get; private set; } + public DelegateCommand CloseEnterCommand { get; private set; } + public DelegateCommand CloseLeaveCommand { get; private set; } + public DelegateCommand SkinCommand { get; private set; } + public DelegateCommand SkinEnterCommand { get; private set; } + public DelegateCommand SkinLeaveCommand { get; private set; } + + #endregion + + /// + /// 鼠标进入系统按钮时的图标样式 + /// + /// 图标 + private void SetEnterStyle(VectorImage icon) + { + icon.Fill = DictionaryResource.GetColor("ColorSystemBtnTint"); + } + + /// + /// 鼠标离开系统按钮时的图标样式 + /// + /// 图标 + private void SetLeaveStyle(VectorImage icon) + { + icon.Fill = DictionaryResource.GetColor("ColorSystemBtnTintDark"); + } + + private void OnClipboardUpdated(object sender, EventArgs e) + { + AllowStatus isListenClipboard = SettingsManager.GetInstance().IsListenClipboard(); + if (isListenClipboard != AllowStatus.YES) + { + return; + } + + string input; + try + { + IDataObject data = Clipboard.GetDataObject(); + string[] fs = data.GetFormats(); + input = data.GetData(fs[0]).ToString(); + } + catch (Exception exc) + { + Console.WriteLine("OnClipboardUpdated()发生异常: {0}", exc); + LogManager.Error("OnClipboardUpdated", exc); + return; + } + + // 视频 + if (ParseEntrance.IsAvId(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.VideoUrl}{input.ToLower()}"); + } + else if (ParseEntrance.IsAvUrl(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, input); + } + else if (ParseEntrance.IsBvId(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.VideoUrl}{input}"); + } + else if (ParseEntrance.IsBvUrl(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, input); + } + // 番剧(电影、电视剧) + else if (ParseEntrance.IsBangumiSeasonId(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.BangumiUrl}{input.ToLower()}"); + } + else if (ParseEntrance.IsBangumiSeasonUrl(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, input); + } + else if (ParseEntrance.IsBangumiEpisodeId(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.BangumiUrl}{input.ToLower()}"); + } + else if (ParseEntrance.IsBangumiEpisodeUrl(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, input); + } + else if (ParseEntrance.IsBangumiMediaId(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.BangumiMediaUrl}{input.ToLower()}"); + } + else if (ParseEntrance.IsBangumiMediaUrl(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, input); + } + // 课程 + else if (ParseEntrance.IsCheeseSeasonUrl(input) || ParseEntrance.IsCheeseEpisodeUrl(input)) + { + NavigationView(ViewVideoDetailViewModel.Tag, input); + } + } + + /// + /// 导航到其他页面 + /// + /// + /// + private void NavigationView(string viewName, string param) + { + LogManager.Debug("OnClipboardUpdated", $"NavigationView: {viewName}, Parameter: {param}"); + + NavigationParam parameter = new NavigationParam + { + ViewName = viewName, + ParentViewName = ViewIndexViewModel.Tag, + Parameter = param + }; + eventAggregator.GetEvent().Publish(parameter); + } + + } +} diff --git a/DownKyi/ViewModels/Settings/ViewAboutViewModel.cs b/DownKyi/ViewModels/Settings/ViewAboutViewModel.cs new file mode 100644 index 0000000..1d3fdb9 --- /dev/null +++ b/DownKyi/ViewModels/Settings/ViewAboutViewModel.cs @@ -0,0 +1,269 @@ +using DownKyi.Core.Settings; +using DownKyi.Events; +using DownKyi.Models; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; + +namespace DownKyi.ViewModels.Settings +{ + public class ViewAboutViewModel : BaseViewModel + { + public const string Tag = "PageSettingsAbout"; + + private bool isOnNavigatedTo; + + #region 页面属性申明 + + private string appName; + public string AppName + { + get { return appName; } + set { SetProperty(ref appName, value); } + } + + private string appVersion; + public string AppVersion + { + get { return appVersion; } + set { SetProperty(ref appVersion, value); } + } + + private bool isReceiveBetaVersion; + public bool IsReceiveBetaVersion + { + get { return isReceiveBetaVersion; } + set { SetProperty(ref isReceiveBetaVersion, value); } + } + + private bool autoUpdateWhenLaunch; + public bool AutoUpdateWhenLaunch + { + get { return autoUpdateWhenLaunch; } + set { SetProperty(ref autoUpdateWhenLaunch, value); } + } + + #endregion + + public ViewAboutViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + #region 属性初始化 + + AppInfo app = new AppInfo(); + AppName = app.Name; + AppVersion = app.VersionName; + + #endregion + + } + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + isOnNavigatedTo = true; + + // 是否接收测试版更新 + var isReceiveBetaVersion = SettingsManager.GetInstance().IsReceiveBetaVersion(); + IsReceiveBetaVersion = isReceiveBetaVersion == AllowStatus.YES; + + // 是否在启动时自动检查更新 + var isAutoUpdateWhenLaunch = SettingsManager.GetInstance().GetAutoUpdateWhenLaunch(); + AutoUpdateWhenLaunch = isAutoUpdateWhenLaunch == AllowStatus.YES; + + isOnNavigatedTo = false; + } + + #region 命令申明 + + // 访问主页事件 + private DelegateCommand appNameCommand; + public DelegateCommand AppNameCommand => appNameCommand ?? (appNameCommand = new DelegateCommand(ExecuteAppNameCommand)); + + /// + /// 访问主页事件 + /// + private void ExecuteAppNameCommand() + { + System.Diagnostics.Process.Start("https://github.com/leiurayer/downkyi"); + } + + // 检查更新事件 + private DelegateCommand checkUpdateCommand; + public DelegateCommand CheckUpdateCommand => checkUpdateCommand ?? (checkUpdateCommand = new DelegateCommand(ExecuteCheckUpdateCommand)); + + /// + /// 检查更新事件 + /// + private void ExecuteCheckUpdateCommand() + { + //eventAggregator.GetEvent().Publish("开始查找更新,请稍后~"); + eventAggregator.GetEvent().Publish("请前往主页下载最新版~"); + } + + // 意见反馈事件 + private DelegateCommand feedbackCommand; + public DelegateCommand FeedbackCommand => feedbackCommand ?? (feedbackCommand = new DelegateCommand(ExecuteFeedbackCommand)); + + /// + /// 意见反馈事件 + /// + private void ExecuteFeedbackCommand() + { + System.Diagnostics.Process.Start("https://github.com/leiurayer/downkyi/issues"); + } + + // 是否接收测试版更新事件 + private DelegateCommand receiveBetaVersionCommand; + public DelegateCommand ReceiveBetaVersionCommand => receiveBetaVersionCommand ?? (receiveBetaVersionCommand = new DelegateCommand(ExecuteReceiveBetaVersionCommand)); + + /// + /// 是否接收测试版更新事件 + /// + private void ExecuteReceiveBetaVersionCommand() + { + AllowStatus isReceiveBetaVersion = IsReceiveBetaVersion ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsReceiveBetaVersion(isReceiveBetaVersion); + PublishTip(isSucceed); + } + + // 是否在启动时自动检查更新事件 + private DelegateCommand autoUpdateWhenLaunchCommand; + public DelegateCommand AutoUpdateWhenLaunchCommand => autoUpdateWhenLaunchCommand ?? (autoUpdateWhenLaunchCommand = new DelegateCommand(ExecuteAutoUpdateWhenLaunchCommand)); + + /// + /// 是否在启动时自动检查更新事件 + /// + private void ExecuteAutoUpdateWhenLaunchCommand() + { + AllowStatus isAutoUpdateWhenLaunch = AutoUpdateWhenLaunch ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().SetAutoUpdateWhenLaunch(isAutoUpdateWhenLaunch); + PublishTip(isSucceed); + } + + // Brotli.NET许可证查看事件 + private DelegateCommand brotliLicenseCommand; + public DelegateCommand BrotliLicenseCommand => brotliLicenseCommand ?? (brotliLicenseCommand = new DelegateCommand(ExecuteBrotliLicenseCommand)); + + /// + /// Brotli.NET许可证查看事件 + /// + private void ExecuteBrotliLicenseCommand() + { + System.Diagnostics.Process.Start("https://licenses.nuget.org/MIT"); + } + + // Google.Protobuf许可证查看事件 + private DelegateCommand protobufLicenseCommand; + public DelegateCommand ProtobufLicenseCommand => protobufLicenseCommand ?? (protobufLicenseCommand = new DelegateCommand(ExecuteProtobufLicenseCommand)); + + /// + /// Google.Protobuf许可证查看事件 + /// + private void ExecuteProtobufLicenseCommand() + { + System.Diagnostics.Process.Start("https://github.com/protocolbuffers/protobuf/blob/master/LICENSE"); + } + + // Newtonsoft.Json许可证查看事件 + private DelegateCommand newtonsoftLicenseCommand; + public DelegateCommand NewtonsoftLicenseCommand => newtonsoftLicenseCommand ?? (newtonsoftLicenseCommand = new DelegateCommand(ExecuteNewtonsoftLicenseCommand)); + + /// + /// Newtonsoft.Json许可证查看事件 + /// + private void ExecuteNewtonsoftLicenseCommand() + { + System.Diagnostics.Process.Start("https://licenses.nuget.org/MIT"); + } + + // Prism.DryIoc许可证查看事件 + private DelegateCommand prismLicenseCommand; + public DelegateCommand PrismLicenseCommand => prismLicenseCommand ?? (prismLicenseCommand = new DelegateCommand(ExecutePrismLicenseCommand)); + + /// + /// Prism.DryIoc许可证查看事件 + /// + private void ExecutePrismLicenseCommand() + { + System.Diagnostics.Process.Start("https://www.nuget.org/packages/Prism.DryIoc/8.1.97/license"); + } + + // QRCoder许可证查看事件 + private DelegateCommand qRCoderLicenseCommand; + public DelegateCommand QRCoderLicenseCommand => qRCoderLicenseCommand ?? (qRCoderLicenseCommand = new DelegateCommand(ExecuteQRCoderLicenseCommand)); + + /// + /// QRCoder许可证查看事件 + /// + private void ExecuteQRCoderLicenseCommand() + { + System.Diagnostics.Process.Start("https://licenses.nuget.org/MIT"); + } + + // System.Data.SQLite.Core许可证查看事件 + private DelegateCommand sQLiteLicenseCommand; + public DelegateCommand SQLiteLicenseCommand => sQLiteLicenseCommand ?? (sQLiteLicenseCommand = new DelegateCommand(ExecuteSQLiteLicenseCommand)); + + /// + /// System.Data.SQLite.Core许可证查看事件 + /// + private void ExecuteSQLiteLicenseCommand() + { + System.Diagnostics.Process.Start("https://www.sqlite.org/copyright.html"); + } + + // Aria2c许可证查看事件 + private DelegateCommand ariaLicenseCommand; + public DelegateCommand AriaLicenseCommand => ariaLicenseCommand ?? (ariaLicenseCommand = new DelegateCommand(ExecuteAriaLicenseCommand)); + + /// + /// Aria2c许可证查看事件 + /// + private void ExecuteAriaLicenseCommand() + { + System.Diagnostics.Process.Start("aria2_COPYING.txt"); + } + + // FFmpeg许可证查看事件 + private DelegateCommand fFmpegLicenseCommand; + public DelegateCommand FFmpegLicenseCommand => fFmpegLicenseCommand ?? (fFmpegLicenseCommand = new DelegateCommand(ExecuteFFmpegLicenseCommand)); + + /// + /// FFmpeg许可证查看事件 + /// + private void ExecuteFFmpegLicenseCommand() + { + System.Diagnostics.Process.Start("FFmpeg_LICENSE.txt"); + } + + #endregion + + /// + /// 发送需要显示的tip + /// + /// + private void PublishTip(bool isSucceed) + { + if (isOnNavigatedTo) { return; } + + if (isSucceed) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingUpdated")); + } + else + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingFailed")); + } + } + + } +} diff --git a/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs b/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs new file mode 100644 index 0000000..032e02e --- /dev/null +++ b/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs @@ -0,0 +1,239 @@ +using DownKyi.Core.Settings; +using DownKyi.Events; +using DownKyi.Models; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels.Settings +{ + public class ViewBasicViewModel : BaseViewModel + { + public const string Tag = "PageSettingsBasic"; + + private bool isOnNavigatedTo; + + #region 页面属性申明 + + private bool none; + public bool None + { + get { return none; } + set { SetProperty(ref none, value); } + } + + private bool closeApp; + public bool CloseApp + { + get { return closeApp; } + set { SetProperty(ref closeApp, value); } + } + + private bool closeSystem; + public bool CloseSystem + { + get { return closeSystem; } + set { SetProperty(ref closeSystem, value); } + } + + private bool listenClipboard; + public bool ListenClipboard + { + get { return listenClipboard; } + set { SetProperty(ref listenClipboard, value); } + } + + private bool autoParseVideo; + public bool AutoParseVideo + { + get { return autoParseVideo; } + set { SetProperty(ref autoParseVideo, value); } + } + + private List parseScopes; + public List ParseScopes + { + get { return parseScopes; } + set { SetProperty(ref parseScopes, value); } + } + + private ParseScopeDisplay selectedParseScope; + public ParseScopeDisplay SelectedParseScope + { + get { return selectedParseScope; } + set { SetProperty(ref selectedParseScope, value); } + } + + #endregion + + public ViewBasicViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + #region 属性初始化 + + // 解析范围 + ParseScopes = new List() + { + new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseNone"),ParseScope=ParseScope.NONE}, + new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseSelectedItem"),ParseScope=ParseScope.SELECTED_ITEM}, + new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseCurrentSection"),ParseScope=ParseScope.CURRENT_SECTION}, + new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseAll"),ParseScope=ParseScope.ALL} + }; + + #endregion + + } + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + isOnNavigatedTo = true; + + // 下载完成后的操作 + AfterDownloadOperation afterDownload = SettingsManager.GetInstance().GetAfterDownloadOperation(); + SetAfterDownloadOperation(afterDownload); + + // 是否监听剪贴板 + AllowStatus isListenClipboard = SettingsManager.GetInstance().IsListenClipboard(); + ListenClipboard = isListenClipboard == AllowStatus.YES; + + // 是否自动解析视频 + AllowStatus isAutoParseVideo = SettingsManager.GetInstance().IsAutoParseVideo(); + AutoParseVideo = isAutoParseVideo == AllowStatus.YES; + + // 解析范围 + ParseScope parseScope = SettingsManager.GetInstance().GetParseScope(); + SelectedParseScope = ParseScopes.FirstOrDefault(t => { return t.ParseScope == parseScope; }); + + isOnNavigatedTo = false; + } + + #region 命令申明 + + // 下载完成后的操作事件 + private DelegateCommand afterDownloadOperationCommand; + public DelegateCommand AfterDownloadOperationCommand => afterDownloadOperationCommand ?? (afterDownloadOperationCommand = new DelegateCommand(ExecuteAfterDownloadOperationCommand)); + + /// + /// 下载完成后的操作事件 + /// + private void ExecuteAfterDownloadOperationCommand(string parameter) + { + AfterDownloadOperation afterDownload; + switch (parameter) + { + case "None": + afterDownload = AfterDownloadOperation.NONE; + break; + case "CloseApp": + afterDownload = AfterDownloadOperation.CLOSE_APP; + break; + case "CloseSystem": + afterDownload = AfterDownloadOperation.CLOSE_SYSTEM; + break; + default: + afterDownload = AfterDownloadOperation.NONE; + break; + } + + bool isSucceed = SettingsManager.GetInstance().SetAfterDownloadOperation(afterDownload); + PublishTip(isSucceed); + } + + // 是否监听剪贴板事件 + private DelegateCommand listenClipboardCommand; + public DelegateCommand ListenClipboardCommand => listenClipboardCommand ?? (listenClipboardCommand = new DelegateCommand(ExecuteListenClipboardCommand)); + + /// + /// 是否监听剪贴板事件 + /// + private void ExecuteListenClipboardCommand() + { + AllowStatus isListenClipboard = ListenClipboard ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsListenClipboard(isListenClipboard); + PublishTip(isSucceed); + } + + private DelegateCommand autoParseVideoCommand; + public DelegateCommand AutoParseVideoCommand => autoParseVideoCommand ?? (autoParseVideoCommand = new DelegateCommand(ExecuteAutoParseVideoCommand)); + + /// + /// 是否自动解析视频 + /// + private void ExecuteAutoParseVideoCommand() + { + AllowStatus isAutoParseVideo = AutoParseVideo ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsAutoParseVideo(isAutoParseVideo); + PublishTip(isSucceed); + } + + // 解析范围事件 + private DelegateCommand parseScopesCommand; + public DelegateCommand ParseScopesCommand => parseScopesCommand ?? (parseScopesCommand = new DelegateCommand(ExecuteParseScopesCommand)); + + /// + /// 解析范围事件 + /// + /// + private void ExecuteParseScopesCommand(object parameter) + { + if (!(parameter is ParseScopeDisplay parseScope)) { return; } + + bool isSucceed = SettingsManager.GetInstance().SetParseScope(parseScope.ParseScope); + PublishTip(isSucceed); + } + + #endregion + + /// + /// 设置下载完成后的操作 + /// + /// + private void SetAfterDownloadOperation(AfterDownloadOperation afterDownload) + { + switch (afterDownload) + { + case AfterDownloadOperation.NONE: + None = true; + break; + case AfterDownloadOperation.OPEN_FOLDER: + break; + case AfterDownloadOperation.CLOSE_APP: + CloseApp = true; + break; + case AfterDownloadOperation.CLOSE_SYSTEM: + CloseSystem = true; + break; + } + } + + /// + /// 发送需要显示的tip + /// + /// + private void PublishTip(bool isSucceed) + { + if (isOnNavigatedTo) { return; } + + if (isSucceed) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingUpdated")); + } + else + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingFailed")); + } + } + + } +} diff --git a/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs b/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs new file mode 100644 index 0000000..c9fda5b --- /dev/null +++ b/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs @@ -0,0 +1,374 @@ +using DownKyi.Core.Settings; +using DownKyi.Core.Utils.Validator; +using DownKyi.Events; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; +using System.Drawing.Text; + +namespace DownKyi.ViewModels.Settings +{ + public class ViewDanmakuViewModel : BaseViewModel + { + public const string Tag = "PageSettingsDanmaku"; + + private bool isOnNavigatedTo; + + #region 页面属性申明 + + private bool topFilter; + public bool TopFilter + { + get { return topFilter; } + set { SetProperty(ref topFilter, value); } + } + + private bool bottomFilter; + public bool BottomFilter + { + get { return bottomFilter; } + set { SetProperty(ref bottomFilter, value); } + } + + private bool scrollFilter; + public bool ScrollFilter + { + get { return scrollFilter; } + set { SetProperty(ref scrollFilter, value); } + } + + private int screenWidth; + public int ScreenWidth + { + get { return screenWidth; } + set { SetProperty(ref screenWidth, value); } + } + + private int screenHeight; + public int ScreenHeight + { + get { return screenHeight; } + set { SetProperty(ref screenHeight, value); } + } + + private List fonts; + public List Fonts + { + get { return fonts; } + set { SetProperty(ref fonts, value); } + } + + private string selectedFont; + public string SelectedFont + { + get { return selectedFont; } + set { SetProperty(ref selectedFont, value); } + } + + private int fontSize; + public int FontSize + { + get { return fontSize; } + set { SetProperty(ref fontSize, value); } + } + + private int lineCount; + public int LineCount + { + get { return lineCount; } + set { SetProperty(ref lineCount, value); } + } + + private bool sync; + public bool Sync + { + get { return sync; } + set { SetProperty(ref sync, value); } + } + + private bool async; + public bool Async + { + get { return async; } + set { SetProperty(ref async, value); } + } + + #endregion + + public ViewDanmakuViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + #region 属性初始化 + + // 弹幕字体 + Fonts = new List(); + var fontCollection = new InstalledFontCollection(); + foreach (var font in fontCollection.Families) + { + Fonts.Add(font.Name); + } + + #endregion + + } + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + isOnNavigatedTo = true; + + // 屏蔽顶部弹幕 + AllowStatus danmakuTopFilter = SettingsManager.GetInstance().GetDanmakuTopFilter(); + TopFilter = danmakuTopFilter == AllowStatus.YES; + + // 屏蔽底部弹幕 + AllowStatus danmakuBottomFilter = SettingsManager.GetInstance().GetDanmakuBottomFilter(); + BottomFilter = danmakuBottomFilter == AllowStatus.YES; + + // 屏蔽滚动弹幕 + AllowStatus danmakuScrollFilter = SettingsManager.GetInstance().GetDanmakuScrollFilter(); + ScrollFilter = danmakuScrollFilter == AllowStatus.YES; + + // 分辨率-宽 + ScreenWidth = SettingsManager.GetInstance().GetDanmakuScreenWidth(); + + // 分辨率-高 + ScreenHeight = SettingsManager.GetInstance().GetDanmakuScreenHeight(); + + // 弹幕字体 + string danmakuFont = SettingsManager.GetInstance().GetDanmakuFontName(); + if (Fonts.Contains(danmakuFont)) + { + // 只有系统中存在当前设置的字体,才能显示 + SelectedFont = danmakuFont; + } + + // 弹幕字体大小 + FontSize = SettingsManager.GetInstance().GetDanmakuFontSize(); + + // 弹幕限制行数 + LineCount = SettingsManager.GetInstance().GetDanmakuLineCount(); + + // 弹幕布局算法 + DanmakuLayoutAlgorithm layoutAlgorithm = SettingsManager.GetInstance().GetDanmakuLayoutAlgorithm(); + SetLayoutAlgorithm(layoutAlgorithm); + + isOnNavigatedTo = false; + } + + #region 命令申明 + + // 屏蔽顶部弹幕事件 + private DelegateCommand topFilterCommand; + public DelegateCommand TopFilterCommand => topFilterCommand ?? (topFilterCommand = new DelegateCommand(ExecuteTopFilterCommand)); + + /// + /// 屏蔽顶部弹幕事件 + /// + private void ExecuteTopFilterCommand() + { + AllowStatus isTopFilter = TopFilter ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuTopFilter(isTopFilter); + PublishTip(isSucceed); + } + + // 屏蔽底部弹幕事件 + private DelegateCommand bottomFilterCommand; + public DelegateCommand BottomFilterCommand => bottomFilterCommand ?? (bottomFilterCommand = new DelegateCommand(ExecuteBottomFilterCommand)); + + /// + /// 屏蔽底部弹幕事件 + /// + private void ExecuteBottomFilterCommand() + { + AllowStatus isBottomFilter = BottomFilter ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuBottomFilter(isBottomFilter); + PublishTip(isSucceed); + } + + // 屏蔽滚动弹幕事件 + private DelegateCommand scrollFilterCommand; + public DelegateCommand ScrollFilterCommand => scrollFilterCommand ?? (scrollFilterCommand = new DelegateCommand(ExecuteScrollFilterCommand)); + + /// + /// 屏蔽滚动弹幕事件 + /// + private void ExecuteScrollFilterCommand() + { + AllowStatus isScrollFilter = ScrollFilter ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuScrollFilter(isScrollFilter); + PublishTip(isSucceed); + } + + // 设置分辨率-宽事件 + private DelegateCommand screenWidthCommand; + public DelegateCommand ScreenWidthCommand => screenWidthCommand ?? (screenWidthCommand = new DelegateCommand(ExecuteScreenWidthCommand)); + + /// + /// 设置分辨率-宽事件 + /// + /// + private void ExecuteScreenWidthCommand(string parameter) + { + int width = (int)Number.GetInt(parameter); + ScreenWidth = width; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuScreenWidth(ScreenWidth); + PublishTip(isSucceed); + } + + // 设置分辨率-高事件 + private DelegateCommand screenHeightCommand; + public DelegateCommand ScreenHeightCommand => screenHeightCommand ?? (screenHeightCommand = new DelegateCommand(ExecuteScreenHeightCommand)); + + /// + /// 设置分辨率-高事件 + /// + /// + private void ExecuteScreenHeightCommand(string parameter) + { + int height = (int)Number.GetInt(parameter); + ScreenHeight = height; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuScreenHeight(ScreenHeight); + PublishTip(isSucceed); + } + + // 弹幕字体选择事件 + private DelegateCommand fontSelectCommand; + public DelegateCommand FontSelectCommand => fontSelectCommand ?? (fontSelectCommand = new DelegateCommand(ExecuteFontSelectCommand)); + + /// + /// 弹幕字体选择事件 + /// + /// + private void ExecuteFontSelectCommand(string parameter) + { + bool isSucceed = SettingsManager.GetInstance().SetDanmakuFontName(parameter); + PublishTip(isSucceed); + } + + // 弹幕字体大小事件 + private DelegateCommand fontSizeCommand; + public DelegateCommand FontSizeCommand => fontSizeCommand ?? (fontSizeCommand = new DelegateCommand(ExecuteFontSizeCommand)); + + /// + /// 弹幕字体大小事件 + /// + /// + private void ExecuteFontSizeCommand(string parameter) + { + int fontSize = (int)Number.GetInt(parameter); + FontSize = fontSize; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuFontSize(FontSize); + PublishTip(isSucceed); + } + + // 弹幕限制行数事件 + private DelegateCommand lineCountCommand; + public DelegateCommand LineCountCommand => lineCountCommand ?? (lineCountCommand = new DelegateCommand(ExecuteLineCountCommand)); + + /// + /// 弹幕限制行数事件 + /// + /// + private void ExecuteLineCountCommand(string parameter) + { + int lineCount = (int)Number.GetInt(parameter); + LineCount = lineCount; + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuLineCount(LineCount); + PublishTip(isSucceed); + } + + // 弹幕布局算法事件 + private DelegateCommand layoutAlgorithmCommand; + public DelegateCommand LayoutAlgorithmCommand => layoutAlgorithmCommand ?? (layoutAlgorithmCommand = new DelegateCommand(ExecuteLayoutAlgorithmCommand)); + + /// + /// 弹幕布局算法事件 + /// + /// + private void ExecuteLayoutAlgorithmCommand(string parameter) + { + DanmakuLayoutAlgorithm layoutAlgorithm; + switch (parameter) + { + case "Sync": + layoutAlgorithm = DanmakuLayoutAlgorithm.SYNC; + break; + case "Async": + layoutAlgorithm = DanmakuLayoutAlgorithm.ASYNC; + break; + default: + layoutAlgorithm = DanmakuLayoutAlgorithm.SYNC; + break; + } + + bool isSucceed = SettingsManager.GetInstance().SetDanmakuLayoutAlgorithm(layoutAlgorithm); + PublishTip(isSucceed); + + if (isSucceed) + { + SetLayoutAlgorithm(layoutAlgorithm); + } + } + + #endregion + + /// + /// 设置弹幕同步算法 + /// + /// + private void SetLayoutAlgorithm(DanmakuLayoutAlgorithm layoutAlgorithm) + { + switch (layoutAlgorithm) + { + case DanmakuLayoutAlgorithm.SYNC: + Sync = true; + Async = false; + break; + case DanmakuLayoutAlgorithm.ASYNC: + Sync = false; + Async = true; + break; + case DanmakuLayoutAlgorithm.NONE: + Sync = false; + Async = false; + break; + default: + break; + } + } + + /// + /// 发送需要显示的tip + /// + /// + private void PublishTip(bool isSucceed) + { + if (isOnNavigatedTo) { return; } + + if (isSucceed) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingUpdated")); + } + else + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingFailed")); + } + } + + } +} diff --git a/DownKyi/ViewModels/Settings/ViewNetworkViewModel.cs b/DownKyi/ViewModels/Settings/ViewNetworkViewModel.cs new file mode 100644 index 0000000..fedbd87 --- /dev/null +++ b/DownKyi/ViewModels/Settings/ViewNetworkViewModel.cs @@ -0,0 +1,422 @@ +using DownKyi.Core.Aria2cNet.Server; +using DownKyi.Core.Settings; +using DownKyi.Core.Utils.Validator; +using DownKyi.Events; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; + +namespace DownKyi.ViewModels.Settings +{ + public class ViewNetworkViewModel : BaseViewModel + { + public const string Tag = "PageSettingsNetwork"; + + private bool isOnNavigatedTo; + + #region 页面属性申明 + + private int ariaListenPort; + public int AriaListenPort + { + get { return ariaListenPort; } + set { SetProperty(ref ariaListenPort, value); } + } + + private List ariaLogLevels; + public List AriaLogLevels + { + get { return ariaLogLevels; } + set { SetProperty(ref ariaLogLevels, value); } + } + + private string selectedAriaLogLevel; + public string SelectedAriaLogLevel + { + get { return selectedAriaLogLevel; } + set { SetProperty(ref selectedAriaLogLevel, value); } + } + + private List ariaMaxConcurrentDownloads; + public List AriaMaxConcurrentDownloads + { + get { return ariaMaxConcurrentDownloads; } + set { SetProperty(ref ariaMaxConcurrentDownloads, value); } + } + + private int selectedAriaMaxConcurrentDownload; + public int SelectedAriaMaxConcurrentDownload + { + get { return selectedAriaMaxConcurrentDownload; } + set { SetProperty(ref selectedAriaMaxConcurrentDownload, value); } + } + + private List ariaSplits; + public List AriaSplits + { + get { return ariaSplits; } + set { SetProperty(ref ariaSplits, value); } + } + + private int selectedAriaSplit; + public int SelectedAriaSplit + { + get { return selectedAriaSplit; } + set { SetProperty(ref selectedAriaSplit, value); } + } + + private int ariaMaxOverallDownloadLimit; + public int AriaMaxOverallDownloadLimit + { + get { return ariaMaxOverallDownloadLimit; } + set { SetProperty(ref ariaMaxOverallDownloadLimit, value); } + } + + private int ariaMaxDownloadLimit; + public int AriaMaxDownloadLimit + { + get { return ariaMaxDownloadLimit; } + set { SetProperty(ref ariaMaxDownloadLimit, value); } + } + + private bool isAriaHttpProxy; + public bool IsAriaHttpProxy + { + get { return isAriaHttpProxy; } + set { SetProperty(ref isAriaHttpProxy, value); } + } + + private string ariaHttpProxy; + public string AriaHttpProxy + { + get { return ariaHttpProxy; } + set { SetProperty(ref ariaHttpProxy, value); } + } + + private int ariaHttpProxyPort; + public int AriaHttpProxyPort + { + get { return ariaHttpProxyPort; } + set { SetProperty(ref ariaHttpProxyPort, value); } + } + + private List ariaFileAllocations; + public List AriaFileAllocations + { + get { return ariaFileAllocations; } + set { SetProperty(ref ariaFileAllocations, value); } + } + + private string selectedAriaFileAllocation; + public string SelectedAriaFileAllocation + { + get { return selectedAriaFileAllocation; } + set { SetProperty(ref selectedAriaFileAllocation, value); } + } + + #endregion + + public ViewNetworkViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + #region 属性初始化 + + // Aria的日志等级 + AriaLogLevels = new List + { + "DEBUG", + "INFO", + "NOTICE", + "WARN", + "ERROR" + }; + + // Aria同时下载数 + AriaMaxConcurrentDownloads = new List(); + for (int i = 1; i <= 10; i++) { AriaMaxConcurrentDownloads.Add(i); } + + // Aria最大线程数 + AriaSplits = new List(); + for (int i = 1; i <= 10; i++) { AriaSplits.Add(i); } + + // Aria文件预分配 + AriaFileAllocations = new List + { + "NONE", + "PREALLOC", + "FALLOC" + }; + + #endregion + + } + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + isOnNavigatedTo = true; + + // Aria服务器端口 + AriaListenPort = SettingsManager.GetInstance().GetAriaListenPort(); + + // Aria的日志等级 + AriaConfigLogLevel ariaLogLevel = SettingsManager.GetInstance().GetAriaLogLevel(); + SelectedAriaLogLevel = ariaLogLevel.ToString("G"); + + // Aria同时下载数 + SelectedAriaMaxConcurrentDownload = SettingsManager.GetInstance().GetAriaMaxConcurrentDownloads(); + + // Aria最大线程数 + SelectedAriaSplit = SettingsManager.GetInstance().GetAriaSplit(); + + // Aria下载速度限制 + AriaMaxOverallDownloadLimit = SettingsManager.GetInstance().GetAriaMaxOverallDownloadLimit(); + + // Aria下载单文件速度限制 + AriaMaxDownloadLimit = SettingsManager.GetInstance().GetAriaMaxDownloadLimit(); + + // 是否开启Aria http代理 + AllowStatus isAriaHttpProxy = SettingsManager.GetInstance().IsAriaHttpProxy(); + IsAriaHttpProxy = isAriaHttpProxy == AllowStatus.YES; + + // Aria的http代理的地址 + AriaHttpProxy = SettingsManager.GetInstance().GetAriaHttpProxy(); + + // Aria的http代理的端口 + AriaHttpProxyPort = SettingsManager.GetInstance().GetAriaHttpProxyListenPort(); + + // Aria文件预分配 + AriaConfigFileAllocation ariaFileAllocation = SettingsManager.GetInstance().GetAriaFileAllocation(); + SelectedAriaFileAllocation = ariaFileAllocation.ToString("G"); + + isOnNavigatedTo = false; + } + + #region 命令申明 + + // Aria服务器端口事件 + private DelegateCommand ariaListenPortCommand; + public DelegateCommand AriaListenPortCommand => ariaListenPortCommand ?? (ariaListenPortCommand = new DelegateCommand(ExecuteAriaListenPortCommand)); + + /// + /// Aria服务器端口事件 + /// + /// + private void ExecuteAriaListenPortCommand(string parameter) + { + int listenPort = (int)Number.GetInt(parameter); + AriaListenPort = listenPort; + + bool isSucceed = SettingsManager.GetInstance().SetAriaListenPort(AriaListenPort); + PublishTip(isSucceed); + } + + // Aria的日志等级事件 + private DelegateCommand ariaLogLevelsCommand; + public DelegateCommand AriaLogLevelsCommand => ariaLogLevelsCommand ?? (ariaLogLevelsCommand = new DelegateCommand(ExecuteAriaLogLevelsCommand)); + + /// + /// Aria的日志等级事件 + /// + /// + private void ExecuteAriaLogLevelsCommand(string parameter) + { + AriaConfigLogLevel ariaLogLevel; + switch (parameter) + { + case "DEBUG": + ariaLogLevel = AriaConfigLogLevel.DEBUG; + break; + case "INFO": + ariaLogLevel = AriaConfigLogLevel.INFO; + break; + case "NOTICE": + ariaLogLevel = AriaConfigLogLevel.NOTICE; + break; + case "WARN": + ariaLogLevel = AriaConfigLogLevel.WARN; + break; + case "ERROR": + ariaLogLevel = AriaConfigLogLevel.ERROR; + break; + default: + ariaLogLevel = AriaConfigLogLevel.INFO; + break; + } + + bool isSucceed = SettingsManager.GetInstance().SetAriaLogLevel(ariaLogLevel); + PublishTip(isSucceed); + } + + // Aria同时下载数事件 + private DelegateCommand ariaMaxConcurrentDownloadsCommand; + public DelegateCommand AriaMaxConcurrentDownloadsCommand => ariaMaxConcurrentDownloadsCommand ?? (ariaMaxConcurrentDownloadsCommand = new DelegateCommand(ExecuteAriaMaxConcurrentDownloadsCommand)); + + /// + /// Aria同时下载数事件 + /// + /// + private void ExecuteAriaMaxConcurrentDownloadsCommand(object parameter) + { + SelectedAriaMaxConcurrentDownload = (int)parameter; + + bool isSucceed = SettingsManager.GetInstance().SetAriaMaxConcurrentDownloads(SelectedAriaMaxConcurrentDownload); + PublishTip(isSucceed); + } + + // Aria最大线程数事件 + private DelegateCommand ariaSplitsCommand; + public DelegateCommand AriaSplitsCommand => ariaSplitsCommand ?? (ariaSplitsCommand = new DelegateCommand(ExecuteAriaSplitsCommand)); + + /// + /// Aria最大线程数事件 + /// + /// + private void ExecuteAriaSplitsCommand(object parameter) + { + SelectedAriaSplit = (int)parameter; + + bool isSucceed = SettingsManager.GetInstance().SetAriaSplit(SelectedAriaSplit); + PublishTip(isSucceed); + } + + // Aria下载速度限制事件 + private DelegateCommand ariaMaxOverallDownloadLimitCommand; + public DelegateCommand AriaMaxOverallDownloadLimitCommand => ariaMaxOverallDownloadLimitCommand ?? (ariaMaxOverallDownloadLimitCommand = new DelegateCommand(ExecuteAriaMaxOverallDownloadLimitCommand)); + + /// + /// Aria下载速度限制事件 + /// + /// + private void ExecuteAriaMaxOverallDownloadLimitCommand(string parameter) + { + int downloadLimit = (int)Number.GetInt(parameter); + AriaMaxOverallDownloadLimit = downloadLimit; + + bool isSucceed = SettingsManager.GetInstance().SetAriaMaxOverallDownloadLimit(AriaMaxOverallDownloadLimit); + PublishTip(isSucceed); + } + + // Aria下载单文件速度限制事件 + private DelegateCommand ariaMaxDownloadLimitCommand; + public DelegateCommand AriaMaxDownloadLimitCommand => ariaMaxDownloadLimitCommand ?? (ariaMaxDownloadLimitCommand = new DelegateCommand(ExecuteAriaMaxDownloadLimitCommand)); + + /// + /// Aria下载单文件速度限制事件 + /// + /// + private void ExecuteAriaMaxDownloadLimitCommand(string parameter) + { + int downloadLimit = (int)Number.GetInt(parameter); + AriaMaxDownloadLimit = downloadLimit; + + bool isSucceed = SettingsManager.GetInstance().SetAriaMaxDownloadLimit(AriaMaxDownloadLimit); + PublishTip(isSucceed); + } + + // 是否开启Aria http代理事件 + private DelegateCommand isAriaHttpProxyCommand; + public DelegateCommand IsAriaHttpProxyCommand => isAriaHttpProxyCommand ?? (isAriaHttpProxyCommand = new DelegateCommand(ExecuteIsAriaHttpProxyCommand)); + + /// + /// 是否开启Aria http代理事件 + /// + private void ExecuteIsAriaHttpProxyCommand() + { + AllowStatus isAriaHttpProxy = IsAriaHttpProxy ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsAriaHttpProxy(isAriaHttpProxy); + PublishTip(isSucceed); + } + + // Aria的http代理的地址事件 + private DelegateCommand ariaHttpProxyCommand; + public DelegateCommand AriaHttpProxyCommand => ariaHttpProxyCommand ?? (ariaHttpProxyCommand = new DelegateCommand(ExecuteAriaHttpProxyCommand)); + + /// + /// Aria的http代理的地址事件 + /// + /// + private void ExecuteAriaHttpProxyCommand(string parameter) + { + bool isSucceed = SettingsManager.GetInstance().SetAriaHttpProxy(parameter); + PublishTip(isSucceed); + } + + // Aria的http代理的端口事件 + private DelegateCommand ariaHttpProxyPortCommand; + public DelegateCommand AriaHttpProxyPortCommand => ariaHttpProxyPortCommand ?? (ariaHttpProxyPortCommand = new DelegateCommand(ExecuteAriaHttpProxyPortCommand)); + + /// + /// Aria的http代理的端口事件 + /// + /// + private void ExecuteAriaHttpProxyPortCommand(string parameter) + { + int httpProxyPort = (int)Number.GetInt(parameter); + AriaHttpProxyPort = httpProxyPort; + + bool isSucceed = SettingsManager.GetInstance().SetAriaHttpProxyListenPort(AriaHttpProxyPort); + PublishTip(isSucceed); + } + + // Aria文件预分配事件 + private DelegateCommand ariaFileAllocationsCommand; + public DelegateCommand AriaFileAllocationsCommand => ariaFileAllocationsCommand ?? (ariaFileAllocationsCommand = new DelegateCommand(ExecuteAriaFileAllocationsCommand)); + + /// + /// Aria文件预分配事件 + /// + /// + private void ExecuteAriaFileAllocationsCommand(string parameter) + { + AriaConfigFileAllocation ariaFileAllocation; + switch (parameter) + { + case "NONE": + ariaFileAllocation = AriaConfigFileAllocation.NONE; + break; + case "PREALLOC": + ariaFileAllocation = AriaConfigFileAllocation.PREALLOC; + break; + case "FALLOC": + ariaFileAllocation = AriaConfigFileAllocation.FALLOC; + break; + default: + ariaFileAllocation = AriaConfigFileAllocation.PREALLOC; + break; + } + + bool isSucceed = SettingsManager.GetInstance().SetAriaFileAllocation(ariaFileAllocation); + PublishTip(isSucceed); + } + + #endregion + + /// + /// 发送需要显示的tip + /// + /// + private void PublishTip(bool isSucceed) + { + if (isOnNavigatedTo) { return; } + + if (isSucceed) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingUpdated")); + } + else + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingFailed")); + } + } + + } +} diff --git a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs new file mode 100644 index 0000000..46f3e62 --- /dev/null +++ b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs @@ -0,0 +1,383 @@ +using DownKyi.Core.Settings; +using DownKyi.Events; +using DownKyi.Models; +using DownKyi.Services; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels.Settings +{ + public class ViewVideoViewModel : BaseViewModel + { + public const string Tag = "PageSettingsVideo"; + + private bool isOnNavigatedTo; + + #region 页面属性申明 + + private List videoCodecs; + public List VideoCodecs + { + get { return videoCodecs; } + set { SetProperty(ref videoCodecs, value); } + } + + private string selectedVideoCodec; + public string SelectedVideoCodec + { + get { return selectedVideoCodec; } + set { SetProperty(ref selectedVideoCodec, value); } + } + + private List videoQualityList; + public List VideoQualityList + { + get { return videoQualityList; } + set { SetProperty(ref videoQualityList, value); } + } + + private Resolution selectedVideoQuality; + public Resolution SelectedVideoQuality + { + get { return selectedVideoQuality; } + set { SetProperty(ref selectedVideoQuality, value); } + } + + private bool isAddVideoOrder; + public bool IsAddVideoOrder + { + get { return isAddVideoOrder; } + set { SetProperty(ref isAddVideoOrder, value); } + } + + private bool isTranscodingFlvToMp4; + public bool IsTranscodingFlvToMp4 + { + get { return isTranscodingFlvToMp4; } + set { SetProperty(ref isTranscodingFlvToMp4, value); } + } + + private bool isUseDefaultDirectory; + public bool IsUseDefaultDirectory + { + get { return isUseDefaultDirectory; } + set { SetProperty(ref isUseDefaultDirectory, value); } + } + + private string saveVideoDirectory; + public string SaveVideoDirectory + { + get { return saveVideoDirectory; } + set { SetProperty(ref saveVideoDirectory, value); } + } + + private bool isCreateFolderForMedia; + public bool IsCreateFolderForMedia + { + get { return isCreateFolderForMedia; } + set { SetProperty(ref isCreateFolderForMedia, value); } + } + + private bool isDownloadDanmaku; + public bool IsDownloadDanmaku + { + get { return isDownloadDanmaku; } + set { SetProperty(ref isDownloadDanmaku, value); } + } + + private bool isDownloadCover; + public bool IsDownloadCover + { + get { return isDownloadCover; } + set { SetProperty(ref isDownloadCover, value); } + } + + #endregion + + public ViewVideoViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + + #region 属性初始化 + + // 优先下载的视频编码 + VideoCodecs = new List + { + "H.264/AVC", + "H.265/HEVC" + }; + + // 优先下载画质 + VideoQualityList = new ResolutionService().GetResolution(); + + #endregion + + } + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + isOnNavigatedTo = true; + + // 优先下载的视频编码 + VideoCodecs videoCodecs = SettingsManager.GetInstance().GetVideoCodecs(); + SelectedVideoCodec = GetVideoCodecsString(videoCodecs); + + // 优先下载画质 + int quality = SettingsManager.GetInstance().GetQuality(); + SelectedVideoQuality = VideoQualityList.FirstOrDefault(t => { return t.Id == quality; }); + + // 是否在下载的视频前增加序号 + AllowStatus isAddOrder = SettingsManager.GetInstance().IsAddOrder(); + IsAddVideoOrder = isAddOrder == AllowStatus.YES; + + // 是否下载flv视频后转码为mp4 + AllowStatus isTranscodingFlvToMp4 = SettingsManager.GetInstance().IsTranscodingFlvToMp4(); + IsTranscodingFlvToMp4 = isTranscodingFlvToMp4 == AllowStatus.YES; + + // 是否使用默认下载目录 + AllowStatus isUseSaveVideoRootPath = SettingsManager.GetInstance().IsUseSaveVideoRootPath(); + IsUseDefaultDirectory = isUseSaveVideoRootPath == AllowStatus.YES; + + // 默认下载目录 + SaveVideoDirectory = SettingsManager.GetInstance().GetSaveVideoRootPath(); + + // 是否为不同视频分别创建文件夹 + AllowStatus isCreateFolderForMedia = SettingsManager.GetInstance().IsCreateFolderForMedia(); + IsCreateFolderForMedia = isCreateFolderForMedia == AllowStatus.YES; + + // 是否在下载视频的同时下载弹幕 + AllowStatus isDownloadDanmaku = SettingsManager.GetInstance().IsDownloadDanmaku(); + IsDownloadDanmaku = isDownloadDanmaku == AllowStatus.YES; + + // 是否在下载视频的同时下载封面 + AllowStatus isDownloadCover = SettingsManager.GetInstance().IsDownloadCover(); + IsDownloadCover = isDownloadCover == AllowStatus.YES; + + isOnNavigatedTo = false; + } + + #region 命令申明 + + // 优先下载的视频编码事件 + private DelegateCommand videoCodecsCommand; + public DelegateCommand VideoCodecsCommand => videoCodecsCommand ?? (videoCodecsCommand = new DelegateCommand(ExecuteVideoCodecsCommand)); + + /// + /// 优先下载的视频编码事件 + /// + /// + private void ExecuteVideoCodecsCommand(string parameter) + { + VideoCodecs videoCodecs = GetVideoCodecs(parameter); + + bool isSucceed = SettingsManager.GetInstance().SetVideoCodecs(videoCodecs); + PublishTip(isSucceed); + } + + // 优先下载画质事件 + private DelegateCommand videoQualityCommand; + public DelegateCommand VideoQualityCommand => videoQualityCommand ?? (videoQualityCommand = new DelegateCommand(ExecuteVideoQualityCommand)); + + /// + /// 优先下载画质事件 + /// + /// + private void ExecuteVideoQualityCommand(object parameter) + { + if (!(parameter is Resolution resolution)) { return; } + + bool isSucceed = SettingsManager.GetInstance().SetQuality(resolution.Id); + PublishTip(isSucceed); + } + + // 是否在下载的视频前增加序号事件 + private DelegateCommand IisAddVideoOrderCommand; + public DelegateCommand IsAddVideoOrderCommand => IisAddVideoOrderCommand ?? (IisAddVideoOrderCommand = new DelegateCommand(ExecuteIsAddVideoOrderCommand)); + + /// + /// 是否在下载的视频前增加序号事件 + /// + private void ExecuteIsAddVideoOrderCommand() + { + AllowStatus isAddOrder = IsAddVideoOrder ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsAddOrder(isAddOrder); + PublishTip(isSucceed); + } + + // 是否下载flv视频后转码为mp4事件 + private DelegateCommand isTranscodingFlvToMp4Command; + public DelegateCommand IsTranscodingFlvToMp4Command => isTranscodingFlvToMp4Command ?? (isTranscodingFlvToMp4Command = new DelegateCommand(ExecuteIsTranscodingFlvToMp4Command)); + + /// + /// 是否下载flv视频后转码为mp4事件 + /// + private void ExecuteIsTranscodingFlvToMp4Command() + { + AllowStatus isTranscodingFlvToMp4 = IsTranscodingFlvToMp4 ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsTranscodingFlvToMp4(isTranscodingFlvToMp4); + PublishTip(isSucceed); + } + + // 是否使用默认下载目录事件 + private DelegateCommand isUseDefaultDirectoryCommand; + public DelegateCommand IsUseDefaultDirectoryCommand => isUseDefaultDirectoryCommand ?? (isUseDefaultDirectoryCommand = new DelegateCommand(ExecuteIsUseDefaultDirectoryCommand)); + + /// + /// 是否使用默认下载目录事件 + /// + private void ExecuteIsUseDefaultDirectoryCommand() + { + AllowStatus isUseDefaultDirectory = IsUseDefaultDirectory ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsUseSaveVideoRootPath(isUseDefaultDirectory); + PublishTip(isSucceed); + } + + // 修改默认下载目录事件 + private DelegateCommand changeSaveVideoDirectoryCommand; + public DelegateCommand ChangeSaveVideoDirectoryCommand => changeSaveVideoDirectoryCommand ?? (changeSaveVideoDirectoryCommand = new DelegateCommand(ExecuteChangeSaveVideoDirectoryCommand)); + + /// + /// 修改默认下载目录事件 + /// + private void ExecuteChangeSaveVideoDirectoryCommand() + { + string directory = DialogUtils.SetDownloadDirectory(); + if (directory == "") { return; } + + bool isSucceed = SettingsManager.GetInstance().SetSaveVideoRootPath(directory); + PublishTip(isSucceed); + + if (isSucceed) + { + SaveVideoDirectory = directory; + } + } + + // 是否为不同视频分别创建文件夹事件 + private DelegateCommand isCreateFolderForMediaCommand; + public DelegateCommand IsCreateFolderForMediaCommand => isCreateFolderForMediaCommand ?? (isCreateFolderForMediaCommand = new DelegateCommand(ExecuteIsCreateFolderForMediaCommand)); + + /// + /// 是否为不同视频分别创建文件夹事件 + /// + private void ExecuteIsCreateFolderForMediaCommand() + { + AllowStatus isCreateFolderForMedia = IsCreateFolderForMedia ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsCreateFolderForMedia(isCreateFolderForMedia); + PublishTip(isSucceed); + } + + // 是否在下载视频的同时下载弹幕事件 + private DelegateCommand isDownloadDanmakuCommand; + public DelegateCommand IsDownloadDanmakuCommand => isDownloadDanmakuCommand ?? (isDownloadDanmakuCommand = new DelegateCommand(ExecuteIsDownloadDanmakuCommand)); + + /// + /// 是否在下载视频的同时下载弹幕事件 + /// + private void ExecuteIsDownloadDanmakuCommand() + { + AllowStatus isDownloadDanmaku = IsDownloadDanmaku ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsDownloadDanmaku(isDownloadDanmaku); + PublishTip(isSucceed); + } + + // 是否在下载视频的同时下载封面事件 + private DelegateCommand isDownloadCoverCommand; + public DelegateCommand IsDownloadCoverCommand => isDownloadCoverCommand ?? (isDownloadCoverCommand = new DelegateCommand(ExecuteIsDownloadCoverCommand)); + + /// + /// 是否在下载视频的同时下载封面事件 + /// + private void ExecuteIsDownloadCoverCommand() + { + AllowStatus isDownloadCover = IsDownloadCover ? AllowStatus.YES : AllowStatus.NO; + + bool isSucceed = SettingsManager.GetInstance().IsDownloadCover(isDownloadCover); + PublishTip(isSucceed); + } + + #endregion + + /// + /// 返回VideoCodecs的字符串 + /// + /// + /// + private string GetVideoCodecsString(VideoCodecs videoCodecs) + { + string codec; + switch (videoCodecs) + { + case Core.Settings.VideoCodecs.NONE: + codec = ""; + break; + case Core.Settings.VideoCodecs.AVC: + codec = "H.264/AVC"; + break; + case Core.Settings.VideoCodecs.HEVC: + codec = "H.265/HEVC"; + break; + default: + codec = ""; + break; + } + return codec; + } + + /// + /// 返回VideoCodecs + /// + /// + /// + private VideoCodecs GetVideoCodecs(string str) + { + VideoCodecs videoCodecs; + switch (str) + { + case "H.264/AVC": + videoCodecs = Core.Settings.VideoCodecs.AVC; + break; + case "H.265/HEVC": + videoCodecs = Core.Settings.VideoCodecs.HEVC; + break; + default: + videoCodecs = Core.Settings.VideoCodecs.NONE; + break; + } + return videoCodecs; + } + + /// + /// 发送需要显示的tip + /// + /// + private void PublishTip(bool isSucceed) + { + if (isOnNavigatedTo) { return; } + + if (isSucceed) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingUpdated")); + } + else + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipSettingFailed")); + } + } + + } +} diff --git a/DownKyi/ViewModels/Toolbox/ViewBiliHelperViewModel.cs b/DownKyi/ViewModels/Toolbox/ViewBiliHelperViewModel.cs new file mode 100644 index 0000000..42348b2 --- /dev/null +++ b/DownKyi/ViewModels/Toolbox/ViewBiliHelperViewModel.cs @@ -0,0 +1,151 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.Logging; +using Prism.Commands; +using Prism.Events; +using System; +using System.Threading.Tasks; + +namespace DownKyi.ViewModels.Toolbox +{ + public class ViewBiliHelperViewModel : BaseViewModel + { + public const string Tag = "PageToolboxBiliHelper"; + + #region 页面属性申明 + + private string avid; + public string Avid + { + get { return avid; } + set { SetProperty(ref avid, value); } + } + + private string bvid; + public string Bvid + { + get { return bvid; } + set { SetProperty(ref bvid, value); } + } + + private string danmakuUserID; + public string DanmakuUserID + { + get { return danmakuUserID; } + set { SetProperty(ref danmakuUserID, value); } + } + + private string userMid; + public string UserMid + { + get { return userMid; } + set { SetProperty(ref userMid, value); } + } + + #endregion + + public ViewBiliHelperViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + #endregion + } + + #region 命令申明 + + // 输入avid事件 + private DelegateCommand avidCommand; + public DelegateCommand AvidCommand => avidCommand ?? (avidCommand = new DelegateCommand(ExecuteAvidCommand)); + + /// + /// 输入avid事件 + /// + private async void ExecuteAvidCommand(string parameter) + { + if (parameter == null) { return; } + if (!ParseEntrance.IsAvId(parameter)) { return; } + + long avid = ParseEntrance.GetAvId(parameter); + if (avid == -1) { return; } + + await Task.Run(() => + { + Bvid = BvId.Av2Bv((ulong)avid); + }); + } + + // 输入bvid事件 + private DelegateCommand bvidCommand; + public DelegateCommand BvidCommand => bvidCommand ?? (bvidCommand = new DelegateCommand(ExecuteBvidCommand)); + + /// + /// 输入bvid事件 + /// + /// + private async void ExecuteBvidCommand(string parameter) + { + if (parameter == null) { return; } + if (!ParseEntrance.IsBvId(parameter)) { return; } + + await Task.Run(() => + { + ulong avid = BvId.Bv2Av(parameter); + Avid = $"av{avid}"; + }); + } + + // 访问网页事件 + private DelegateCommand gotoWebCommand; + public DelegateCommand GotoWebCommand => gotoWebCommand ?? (gotoWebCommand = new DelegateCommand(ExecuteGotoWebCommand)); + + /// + /// 访问网页事件 + /// + private void ExecuteGotoWebCommand() + { + string baseUrl = "https://www.bilibili.com/video/"; + System.Diagnostics.Process.Start(baseUrl + Bvid); + } + + // 查询弹幕发送者事件 + private DelegateCommand findDanmakuSenderCommand; + public DelegateCommand FindDanmakuSenderCommand => findDanmakuSenderCommand ?? (findDanmakuSenderCommand = new DelegateCommand(ExecuteFindDanmakuSenderCommand)); + + /// + /// 查询弹幕发送者事件 + /// + private async void ExecuteFindDanmakuSenderCommand() + { + await Task.Run(() => + { + try + { + UserMid = DanmakuSender.FindDanmakuSender(DanmakuUserID); + } + catch (Exception e) + { + UserMid = null; + + Core.Utils.Debug.Console.PrintLine("FindDanmakuSenderCommand()发生异常: {0}", e); + LogManager.Error(Tag, e); + } + }); + } + + // 访问用户空间事件 + private DelegateCommand visitUserSpaceCommand; + public DelegateCommand VisitUserSpaceCommand => visitUserSpaceCommand ?? (visitUserSpaceCommand = new DelegateCommand(ExecuteVisitUserSpaceCommand)); + + /// + /// 访问用户空间事件 + /// + private void ExecuteVisitUserSpaceCommand() + { + if (UserMid == null) { return; } + + string baseUrl = "https://space.bilibili.com/"; + System.Diagnostics.Process.Start(baseUrl + UserMid); + } + + #endregion + + } +} diff --git a/DownKyi/ViewModels/Toolbox/ViewDelogoViewModel.cs b/DownKyi/ViewModels/Toolbox/ViewDelogoViewModel.cs new file mode 100644 index 0000000..d1dbc89 --- /dev/null +++ b/DownKyi/ViewModels/Toolbox/ViewDelogoViewModel.cs @@ -0,0 +1,195 @@ +using DownKyi.Core.FFmpeg; +using DownKyi.Events; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using System; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace DownKyi.ViewModels.Toolbox +{ + public class ViewDelogoViewModel : BaseViewModel + { + public const string Tag = "PageToolboxDelogo"; + + // 是否正在执行去水印任务 + private bool isDelogo = false; + + #region 页面属性申明 + + private string videoPath; + public string VideoPath + { + get { return videoPath; } + set { SetProperty(ref videoPath, value); } + } + + private int logoWidth; + public int LogoWidth + { + get { return logoWidth; } + set { SetProperty(ref logoWidth, value); } + } + + private int logoHeight; + public int LogoHeight + { + get { return logoHeight; } + set { SetProperty(ref logoHeight, value); } + } + + private int logoX; + public int LogoX + { + get { return logoX; } + set { SetProperty(ref logoX, value); } + } + + private int logoY; + public int LogoY + { + get { return logoY; } + set { SetProperty(ref logoY, value); } + } + + private string status; + public string Status + { + get { return status; } + set { SetProperty(ref status, value); } + } + + #endregion + + public ViewDelogoViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + + VideoPath = string.Empty; + + LogoWidth = -1; + LogoHeight = -1; + LogoX = -1; + LogoY = -1; + + #endregion + } + + #region 命令申明 + + // 选择视频事件 + private DelegateCommand selectVideoCommand; + public DelegateCommand SelectVideoCommand => selectVideoCommand ?? (selectVideoCommand = new DelegateCommand(ExecuteSelectVideoCommand)); + + /// + /// 选择视频事件 + /// + private void ExecuteSelectVideoCommand() + { + if (isDelogo) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipWaitTaskFinished")); + return; + } + + VideoPath = SelectVideoFile(); + } + + // 去水印事件 + private DelegateCommand delogoCommand; + public DelegateCommand DelogoCommand => delogoCommand ?? (delogoCommand = new DelegateCommand(ExecuteDelogoCommand)); + + /// + /// 去水印事件 + /// + private async void ExecuteDelogoCommand() + { + if (isDelogo) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipWaitTaskFinished")); + return; + } + + if (VideoPath == "") + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipNoSeletedVideo")); + return; + } + + if (LogoWidth == -1) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipInputRightLogoWidth")); + return; + } + if (LogoHeight == -1) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipInputRightLogoHeight")); + return; + } + if (LogoX == -1) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipInputRightLogoX")); + return; + } + if (LogoY == -1) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipInputRightLogoY")); + return; + } + + // 新文件名 + string newFileName = VideoPath.Insert(VideoPath.Length - 4, "_delogo"); + Status = string.Empty; + + await Task.Run(() => + { + // 执行去水印程序 + isDelogo = true; + FFmpegHelper.Delogo(VideoPath, newFileName, LogoX, LogoY, LogoWidth, LogoHeight, new Action((output) => + { + Status += output + "\n"; + })); + isDelogo = false; + }); + } + + // Status改变事件 + private DelegateCommand statusCommand; + public DelegateCommand StatusCommand => statusCommand ?? (statusCommand = new DelegateCommand(ExecuteStatusCommand)); + + /// + /// Status改变事件 + /// + /// + private void ExecuteStatusCommand(object parameter) + { + if (!(parameter is TextBox output)) { return; } + + // TextBox滚动到底部 + output.ScrollToEnd(); + } + + #endregion + + /// + /// 选择视频dialog + /// + /// + private string SelectVideoFile() + { + // 选择文件 + var dialog = new Microsoft.Win32.OpenFileDialog + { + Filter = "mp4 (*.mp4)|*.mp4" + }; + var showDialog = dialog.ShowDialog(); + if (showDialog == true) + { + return dialog.FileName; + } + else { return ""; } + } + + } +} diff --git a/DownKyi/ViewModels/Toolbox/ViewExtractMediaViewModel.cs b/DownKyi/ViewModels/Toolbox/ViewExtractMediaViewModel.cs new file mode 100644 index 0000000..286d558 --- /dev/null +++ b/DownKyi/ViewModels/Toolbox/ViewExtractMediaViewModel.cs @@ -0,0 +1,178 @@ +using DownKyi.Core.FFmpeg; +using DownKyi.Events; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using System; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace DownKyi.ViewModels.Toolbox +{ + public class ViewExtractMediaViewModel : BaseViewModel + { + public const string Tag = "PageToolboxExtractMedia"; + + // 是否正在执行任务 + private bool isExtracting = false; + + #region 页面属性申明 + + private string videoPath; + public string VideoPath + { + get { return videoPath; } + set { SetProperty(ref videoPath, value); } + } + + private string status; + public string Status + { + get { return status; } + set { SetProperty(ref status, value); } + } + + #endregion + + public ViewExtractMediaViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + + VideoPath = string.Empty; + + #endregion + } + + #region 命令申明 + + // 选择视频事件 + private DelegateCommand selectVideoCommand; + public DelegateCommand SelectVideoCommand => selectVideoCommand ?? (selectVideoCommand = new DelegateCommand(ExecuteSelectVideoCommand)); + + /// + /// 选择视频事件 + /// + private void ExecuteSelectVideoCommand() + { + if (isExtracting) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipWaitTaskFinished")); + return; + } + + VideoPath = SelectVideoFile(); + } + + // 提取音频事件 + private DelegateCommand extractAudioCommand; + public DelegateCommand ExtractAudioCommand => extractAudioCommand ?? (extractAudioCommand = new DelegateCommand(ExecuteExtractAudioCommand)); + + /// + /// 提取音频事件 + /// + private async void ExecuteExtractAudioCommand() + { + if (isExtracting) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipWaitTaskFinished")); + return; + } + + if (VideoPath == "") + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipNoSeletedVideo")); + return; + } + + // 音频文件名 + string audioFileName = VideoPath.Remove(VideoPath.Length - 4, 4) + ".aac"; + Status = string.Empty; + + await Task.Run(() => + { + // 执行提取音频程序 + isExtracting = true; + FFmpegHelper.ExtractAudio(VideoPath, audioFileName, new Action((output) => + { + Status += output + "\n"; + })); + isExtracting = false; + }); + } + + // 提取视频事件 + private DelegateCommand extractVideoCommand; + public DelegateCommand ExtractVideoCommand => extractVideoCommand ?? (extractVideoCommand = new DelegateCommand(ExecuteExtractVideoCommand)); + + /// + /// 提取视频事件 + /// + private async void ExecuteExtractVideoCommand() + { + if (isExtracting) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipWaitTaskFinished")); + return; + } + + if (VideoPath == "") + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipNoSeletedVideo")); + return; + } + + // 视频文件名 + string videoFileName = VideoPath.Remove(VideoPath.Length - 4, 4) + "_onlyVideo.mp4"; + Status = string.Empty; + + await Task.Run(() => + { + // 执行提取视频程序 + isExtracting = true; + FFmpegHelper.ExtractVideo(VideoPath, videoFileName, new Action((output) => + { + Status += output + "\n"; + })); + isExtracting = false; + }); + } + + // Status改变事件 + private DelegateCommand statusCommand; + public DelegateCommand StatusCommand => statusCommand ?? (statusCommand = new DelegateCommand(ExecuteStatusCommand)); + + /// + /// Status改变事件 + /// + /// + private void ExecuteStatusCommand(object parameter) + { + if (!(parameter is TextBox output)) { return; } + + // TextBox滚动到底部 + output.ScrollToEnd(); + } + + #endregion + + /// + /// 选择视频dialog + /// + /// + private string SelectVideoFile() + { + // 选择文件 + var dialog = new Microsoft.Win32.OpenFileDialog + { + Filter = "mp4 (*.mp4)|*.mp4" + }; + var showDialog = dialog.ShowDialog(); + if (showDialog == true) + { + return dialog.FileName; + } + else { return ""; } + } + + } +} diff --git a/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs b/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs new file mode 100644 index 0000000..7125753 --- /dev/null +++ b/DownKyi/ViewModels/ViewDownloadManagerViewModel.cs @@ -0,0 +1,125 @@ +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Models; +using DownKyi.Utils; +using DownKyi.ViewModels.DownloadManager; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; + +namespace DownKyi.ViewModels +{ + public class ViewDownloadManagerViewModel : BaseViewModel + { + public const string Tag = "PageDownloadManager"; + + private readonly IRegionManager regionManager; + + #region 页面属性申明 + + private VectorImage arrowBack; + public VectorImage ArrowBack + { + get { return arrowBack; } + set { SetProperty(ref arrowBack, value); } + } + + private List tabHeaders; + public List TabHeaders + { + get { return tabHeaders; } + set { SetProperty(ref tabHeaders, value); } + } + + private int selectTabId; + public int SelectTabId + { + get { return selectTabId; } + set { SetProperty(ref selectTabId, value); } + } + + #endregion + + public ViewDownloadManagerViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) : base(eventAggregator) + { + this.regionManager = regionManager; + + #region 属性初始化 + + ArrowBack = NavigationIcon.Instance().ArrowBack; + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + + TabHeaders = new List + { + new TabHeader { Id = 0, Image = NormalIcon.Instance().Downloading, Title = DictionaryResource.GetString("Downloading") }, + new TabHeader { Id = 1, Image = NormalIcon.Instance().DownloadFinished, Title = DictionaryResource.GetString("DownloadFinished") } + }; + + #endregion + } + + #region 命令申明 + + // 返回事件 + private DelegateCommand backSpaceCommand; + public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); + + /// + /// 返回事件 + /// + private void ExecuteBackSpace() + { + NavigationParam parameter = new NavigationParam + { + ViewName = ParentView, + ParentViewName = null, + Parameter = null + }; + eventAggregator.GetEvent().Publish(parameter); + } + + // 左侧tab点击事件 + private DelegateCommand leftTabHeadersCommand; + public DelegateCommand LeftTabHeadersCommand => leftTabHeadersCommand ?? (leftTabHeadersCommand = new DelegateCommand(ExecuteLeftTabHeadersCommand)); + + /// + /// 左侧tab点击事件 + /// + /// + private void ExecuteLeftTabHeadersCommand(object parameter) + { + if (!(parameter is TabHeader tabHeader)) { return; } + + NavigationParameters param = new NavigationParameters(); + + switch (tabHeader.Id) + { + case 0: + regionManager.RequestNavigate("DownloadManagerContentRegion", ViewDownloadingViewModel.Tag, param); + break; + case 1: + regionManager.RequestNavigate("DownloadManagerContentRegion", ViewDownloadFinishedViewModel.Tag, param); + break; + default: + break; + } + } + + #endregion + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + //// 进入设置页面时显示的设置项 + SelectTabId = 0; + regionManager.RequestNavigate("DownloadManagerContentRegion", ViewDownloadingViewModel.Tag, new NavigationParameters()); + } + + } +} diff --git a/DownKyi/ViewModels/ViewIndexViewModel.cs b/DownKyi/ViewModels/ViewIndexViewModel.cs new file mode 100644 index 0000000..f687d87 --- /dev/null +++ b/DownKyi/ViewModels/ViewIndexViewModel.cs @@ -0,0 +1,439 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.BiliApi.Login; +using DownKyi.Core.Logging; +using DownKyi.Core.Settings; +using DownKyi.Core.Settings.Models; +using DownKyi.Core.Storage; +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media.Imaging; + +namespace DownKyi.ViewModels +{ + public class ViewIndexViewModel : BaseViewModel + { + public const string Tag = "PageIndex"; + + #region 页面属性申明 + + private Visibility loginPanelVisibility; + public Visibility LoginPanelVisibility + { + get { return loginPanelVisibility; } + set { SetProperty(ref loginPanelVisibility, value); } + } + + private string userName; + public string UserName + { + get { return userName; } + set { SetProperty(ref userName, value); } + } + + private BitmapImage header; + public BitmapImage Header + { + get { return header; } + set { SetProperty(ref header, value); } + } + + private VectorImage textLogo; + public VectorImage TextLogo + { + get { return textLogo; } + set { SetProperty(ref textLogo, value); } + } + + private string inputText; + public string InputText + { + get { return inputText; } + set { SetProperty(ref inputText, value); } + } + + private VectorImage generalSearch; + public VectorImage GeneralSearch + { + get { return generalSearch; } + set { SetProperty(ref generalSearch, value); } + } + + private VectorImage settings; + public VectorImage Settings + { + get { return settings; } + set { SetProperty(ref settings, value); } + } + + private VectorImage downloadManager; + public VectorImage DownloadManager + { + get { return downloadManager; } + set { SetProperty(ref downloadManager, value); } + } + + private VectorImage toolbox; + public VectorImage Toolbox + { + get { return toolbox; } + set { SetProperty(ref toolbox, value); } + } + + #endregion + + + public ViewIndexViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + + Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg")); + + TextLogo = LogoIcon.Instance().TextLogo; + TextLogo.Fill = DictionaryResource.GetColor("ColorPrimary"); + + GeneralSearch = ButtonIcon.Instance().GeneralSearch; + GeneralSearch.Fill = DictionaryResource.GetColor("ColorPrimary"); + + Settings = ButtonIcon.Instance().Settings; + Settings.Fill = DictionaryResource.GetColor("ColorPrimary"); + + DownloadManager = ButtonIcon.Instance().DownloadManage; + DownloadManager.Fill = DictionaryResource.GetColor("ColorPrimary"); + + Toolbox = ButtonIcon.Instance().Toolbox; + Toolbox.Fill = DictionaryResource.GetColor("ColorPrimary"); + + #endregion + + } + + #region 命令申明 + + // View加载后执行的事件 + public DelegateCommand loadedCommand; + public DelegateCommand LoadedCommand => loadedCommand ?? (loadedCommand = new DelegateCommand(ExecuteViewLoaded)); + + /// + /// View加载后执行 + /// + private void ExecuteViewLoaded() { } + + // 输入确认事件 + public DelegateCommand inputCommand; + public DelegateCommand InputCommand => inputCommand ?? (inputCommand = new DelegateCommand(ExecuteInput)); + + /// + /// 处理输入事件 + /// + private void ExecuteInput() + { + EnterBili(); + } + + // 登录事件 + private DelegateCommand loginCommand; + public DelegateCommand LoginCommand => loginCommand ?? (loginCommand = new DelegateCommand(ExecuteLogin)); + + /// + /// 进入登录页面 + /// + private void ExecuteLogin() + { + if (UserName == null) + { + NavigationView(ViewLoginViewModel.Tag, null); + } + else + { + // 进入用户空间 + var userInfo = SettingsManager.GetInstance().GetUserInfo(); + if (userInfo != null && userInfo.Mid != -1) + { + NavigationView(ViewMySpaceViewModel.Tag, userInfo.Mid); + } + } + } + + // 进入设置页面 + private DelegateCommand settingsCommand; + public DelegateCommand SettingsCommand => settingsCommand ?? (settingsCommand = new DelegateCommand(ExecuteSettingsCommand)); + + /// + /// 进入设置页面 + /// + private void ExecuteSettingsCommand() + { + NavigationView(ViewSettingsViewModel.Tag, null); + } + + // 进入下载管理页面 + private DelegateCommand downloadManagerCommand; + public DelegateCommand DownloadManagerCommand => downloadManagerCommand ?? (downloadManagerCommand = new DelegateCommand(ExecuteDownloadManagerCommand)); + + /// + /// 进入下载管理页面 + /// + private void ExecuteDownloadManagerCommand() + { + NavigationView(ViewDownloadManagerViewModel.Tag, null); + } + + // 进入工具箱页面 + private DelegateCommand toolboxCommand; + public DelegateCommand ToolboxCommand => toolboxCommand ?? (toolboxCommand = new DelegateCommand(ExecuteToolboxCommand)); + + /// + /// 进入工具箱页面 + /// + private void ExecuteToolboxCommand() + { + NavigationView(ViewToolboxViewModel.Tag, null); + } + + #endregion + + + #region 业务逻辑 + + /// + /// 进入B站链接的处理逻辑, + /// 只负责处理输入,并跳转到视频详情页。 + /// 不是支持的格式,则进入搜索页面。 + /// 支持的格式有: + /// av号:av170001, AV170001, https://www.bilibili.com/video/av170001 + /// BV号:BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC + /// 番剧(电影、电视剧)ss号:ss32982, SS32982, https://www.bilibili.com/bangumi/play/ss32982 + /// 番剧(电影、电视剧)ep号:ep317925, EP317925, https://www.bilibili.com/bangumi/play/ep317925 + /// 番剧(电影、电视剧)md号:md28228367, MD28228367, https://www.bilibili.com/bangumi/media/md28228367 + /// 课程ss号:https://www.bilibili.com/cheese/play/ss205 + /// 课程ep号:https://www.bilibili.com/cheese/play/ep3489 + /// 收藏夹:ml1329019876, ML1329019876, https://www.bilibili.com/medialist/detail/ml1329019876 + /// 用户空间:uid928123, UID928123, uid:928123, UID:928123, https://space.bilibili.com/928123 + /// + private void EnterBili() + { + if (InputText == null || InputText == string.Empty) { return; } + + LogManager.Debug(Tag, $"InputText: {InputText}"); + + // 视频 + if (ParseEntrance.IsAvId(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.VideoUrl}{InputText.ToLower()}"); + } + else if (ParseEntrance.IsAvUrl(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, InputText); + } + else if (ParseEntrance.IsBvId(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.VideoUrl}{InputText}"); + } + else if (ParseEntrance.IsBvUrl(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, InputText); + } + // 番剧(电影、电视剧) + else if (ParseEntrance.IsBangumiSeasonId(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.BangumiUrl}{InputText.ToLower()}"); + } + else if (ParseEntrance.IsBangumiSeasonUrl(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, InputText); + } + else if (ParseEntrance.IsBangumiEpisodeId(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.BangumiUrl}{InputText.ToLower()}"); + } + else if (ParseEntrance.IsBangumiEpisodeUrl(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, InputText); + } + else if (ParseEntrance.IsBangumiMediaId(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, $"{ParseEntrance.BangumiMediaUrl}{InputText.ToLower()}"); + } + else if (ParseEntrance.IsBangumiMediaUrl(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, InputText); + } + // 课程 + else if (ParseEntrance.IsCheeseSeasonUrl(InputText) || ParseEntrance.IsCheeseEpisodeUrl(InputText)) + { + NavigationView(ViewVideoDetailViewModel.Tag, InputText); + } + // 用户(参数传入mid) + else if (ParseEntrance.IsUserId(InputText)) + { + NavigateToViewUserSpace(ParseEntrance.GetUserId(InputText)); + } + else if (ParseEntrance.IsUserUrl(InputText)) + { + NavigateToViewUserSpace(ParseEntrance.GetUserId(InputText)); + } + // 收藏夹 + else if (ParseEntrance.IsFavoritesId(InputText)) + { + NavigationView(ViewPublicFavoritesViewModel.Tag, ParseEntrance.GetFavoritesId(InputText)); + } + else if (ParseEntrance.IsFavoritesUrl(InputText)) + { + NavigationView(ViewPublicFavoritesViewModel.Tag, ParseEntrance.GetFavoritesId(InputText)); + } + // TODO 关键词搜索 + else + { + } + + InputText = string.Empty; + } + + /// + /// 导航到用户空间, + /// 如果传入的mid与本地登录的mid一致, + /// 则进入我的用户空间。 + /// + /// + private void NavigateToViewUserSpace(long mid) + { + var userInfo = SettingsManager.GetInstance().GetUserInfo(); + if (userInfo != null && userInfo.Mid == mid) + { + NavigationView(ViewMySpaceViewModel.Tag, mid); + } + else + { + NavigationView(ViewUserSpaceViewModel.Tag, mid); + } + } + + /// + /// 导航到其他页面 + /// + /// + /// + private void NavigationView(string viewName, object param) + { + LogManager.Debug(Tag, $"NavigationView: {viewName}, Parameter: {param}"); + + NavigationParam parameter = new NavigationParam + { + ViewName = viewName, + ParentViewName = Tag, + Parameter = param + }; + eventAggregator.GetEvent().Publish(parameter); + } + + /// + /// 更新用户登录信息 + /// + private async void UpdateUserInfo() + { + LoginPanelVisibility = Visibility.Hidden; + + // 检查本地是否存在login文件,没有则说明未登录 + if (!File.Exists(StorageManager.GetLogin())) + { + LoginPanelVisibility = Visibility.Visible; + Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg")); + UserName = null; + return; + } + + await Task.Run(new Action(() => + { + // 获取用户信息 + var userInfo = LoginInfo.GetUserInfoForNavigation(); + if (userInfo != null) + { + SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings + { + Mid = userInfo.Mid, + Name = userInfo.Name, + IsLogin = userInfo.IsLogin, + IsVip = userInfo.VipStatus == 1 + }); + } + else + { + SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings + { + Mid = -1, + Name = "", + IsLogin = false, + IsVip = false + }); + } + + PropertyChangeAsync(new Action(() => + { + LoginPanelVisibility = Visibility.Visible; + + if (userInfo != null) + { + if (userInfo.Face != null) + { + Header = new StorageHeader().GetHeaderThumbnail(userInfo.Mid, userInfo.Name, userInfo.Face, 36, 36); + } + else + { + Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg")); + } + UserName = userInfo.Name; + } + else + { + Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg")); + UserName = null; + } + })); + })); + } + + #endregion + + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + DownloadManager = ButtonIcon.Instance().DownloadManage; + DownloadManager.Height = 27; + DownloadManager.Width = 32; + DownloadManager.Fill = DictionaryResource.GetColor("ColorPrimary"); + + // 根据传入参数不同执行不同任务 + string parameter = navigationContext.Parameters.GetValue("Parameter"); + if (parameter == null) + { + return; + } + // 启动 + if (parameter == "start") + { + UpdateUserInfo(); + } + // 从登录页面返回 + if (parameter == "login") + { + UpdateUserInfo(); + } + // 注销 + if (parameter == "logout") + { + UpdateUserInfo(); + } + + } + + } +} diff --git a/DownKyi/ViewModels/ViewLoginViewModel.cs b/DownKyi/ViewModels/ViewLoginViewModel.cs new file mode 100644 index 0000000..86965d6 --- /dev/null +++ b/DownKyi/ViewModels/ViewLoginViewModel.cs @@ -0,0 +1,251 @@ +using DownKyi.Core.BiliApi.Login; +using DownKyi.Core.Logging; +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Utils; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media.Imaging; + +namespace DownKyi.ViewModels +{ + public class ViewLoginViewModel : BaseViewModel + { + public const string Tag = "PageLogin"; + + private CancellationTokenSource tokenSource; + + #region 页面属性申明 + + private VectorImage arrowBack; + public VectorImage ArrowBack + { + get { return arrowBack; } + set { SetProperty(ref arrowBack, value); } + } + + private BitmapImage loginQRCode; + public BitmapImage LoginQRCode + { + get { return loginQRCode; } + set { SetProperty(ref loginQRCode, value); } + } + + private double loginQRCodeOpacity; + public double LoginQRCodeOpacity + { + get { return loginQRCodeOpacity; } + set { SetProperty(ref loginQRCodeOpacity, value); } + } + + private Visibility loginQRCodeStatus; + public Visibility LoginQRCodeStatus + { + get { return loginQRCodeStatus; } + set { SetProperty(ref loginQRCodeStatus, value); } + } + + #endregion + + + public ViewLoginViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + + ArrowBack = NavigationIcon.Instance().ArrowBack; + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + + #endregion + } + + + #region 命令申明 + + // 返回 + private DelegateCommand backSpaceCommand; + public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); + + /// + /// 返回 + /// + private void ExecuteBackSpace() + { + // 初始化状态 + InitStatus(); + + // 结束任务 + tokenSource.Cancel(); + + NavigationParam parameter = new NavigationParam + { + ViewName = ParentView, + ParentViewName = null, + Parameter = "login" + }; + eventAggregator.GetEvent().Publish(parameter); + } + + #endregion + + + #region 业务逻辑 + + /// + /// 登录 + /// + private void Login() + { + var loginUrl = LoginQR.GetLoginUrl(); + if (loginUrl == null) { return; } + + if (loginUrl.Status != true) + { + ExecuteBackSpace(); + return; + } + + if (loginUrl.Data == null || loginUrl.Data.Url == null) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("GetLoginUrlFailed")); + return; + } + + PropertyChangeAsync(new Action(() => { LoginQRCode = LoginQR.GetLoginQRCode(loginUrl.Data.Url); })); + Core.Utils.Debug.Console.PrintLine(loginUrl.Data.Url + "\n"); + LogManager.Debug(Tag, loginUrl.Data.Url); + + GetLoginStatus(loginUrl.Data.OauthKey); + } + + /// + /// 循环查询登录状态 + /// + /// + private void GetLoginStatus(string oauthKey) + { + CancellationToken cancellationToken = tokenSource.Token; + while (true) + { + Thread.Sleep(1000); + var loginStatus = LoginQR.GetLoginStatus(oauthKey); + if (loginStatus == null) { continue; } + + Core.Utils.Debug.Console.PrintLine(loginStatus.Code + "\n" + loginStatus.Message + "\n" + loginStatus.Url + "\n"); + + switch (loginStatus.Code) + { + case -1: + // 没有这个oauthKey + + // 发送通知 + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("LoginKeyError")); + LogManager.Info(Tag, DictionaryResource.GetString("LoginKeyError")); + + // 取消任务 + tokenSource.Cancel(); + + // 创建新任务 + PropertyChangeAsync(new Action(() => { Task.Run(Login, (tokenSource = new CancellationTokenSource()).Token); })); + break; + case -2: + // 不匹配的oauthKey,超时或已确认的oauthKey + + // 发送通知 + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("LoginTimeOut")); + LogManager.Info(Tag, DictionaryResource.GetString("LoginTimeOut")); + + // 取消任务 + tokenSource.Cancel(); + + // 创建新任务 + PropertyChangeAsync(new Action(() => { Task.Run(Login, (tokenSource = new CancellationTokenSource()).Token); })); + break; + case -4: + // 未扫码 + break; + case -5: + // 已扫码,未确认 + PropertyChangeAsync(new Action(() => + { + LoginQRCodeStatus = Visibility.Visible; + LoginQRCodeOpacity = 0.3; + })); + break; + case 0: + // 确认登录 + + // 发送通知 + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("LoginSuccessful")); + LogManager.Info(Tag, DictionaryResource.GetString("LoginSuccessful")); + + // 保存登录信息 + try + { + bool isSucceed = LoginHelper.SaveLoginInfoCookies(loginStatus.Url); + if (!isSucceed) + { + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("LoginFailed")); + LogManager.Error(Tag, DictionaryResource.GetString("LoginFailed")); + } + } + catch (Exception e) + { + Core.Utils.Debug.Console.PrintLine("PageLogin 保存登录信息发生异常: {0}", e); + LogManager.Error(e); + eventAggregator.GetEvent().Publish(DictionaryResource.GetString("LoginFailed")); + } + + // TODO 其他操作 + + + // 取消任务 + Thread.Sleep(3000); + PropertyChangeAsync(new Action(() => { ExecuteBackSpace(); })); + break; + } + + // 判断是否该结束线程,若为true,跳出while循环 + if (cancellationToken.IsCancellationRequested) + { + Core.Utils.Debug.Console.PrintLine("停止Login线程,跳出while循环"); + LogManager.Debug(Tag, "登录操作结束"); + break; + } + } + } + + /// + /// 初始化状态 + /// + private void InitStatus() + { + LoginQRCode = null; + LoginQRCodeOpacity = 1; + LoginQRCodeStatus = Visibility.Hidden; + } + + #endregion + + /// + /// 导航到Login页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + // 初始化状态 + InitStatus(); + + Task.Run(Login, (tokenSource = new CancellationTokenSource()).Token); + //await loginTask; + } + + + } +} diff --git a/DownKyi/ViewModels/ViewMySpaceViewModel.cs b/DownKyi/ViewModels/ViewMySpaceViewModel.cs new file mode 100644 index 0000000..8348413 --- /dev/null +++ b/DownKyi/ViewModels/ViewMySpaceViewModel.cs @@ -0,0 +1,40 @@ +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels +{ + public class ViewMySpaceViewModel : BaseViewModel + { + public const string Tag = "PageMySpace"; + + // mid + private long mid; + + public ViewMySpaceViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + } + + /// + /// 接收mid参数 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + // 根据传入参数不同执行不同任务 + long parameter = navigationContext.Parameters.GetValue("Parameter"); + if (parameter == 0) + { + return; + } + mid = parameter; + } + + } +} diff --git a/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs b/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs new file mode 100644 index 0000000..20b8cc4 --- /dev/null +++ b/DownKyi/ViewModels/ViewPublicFavoritesViewModel.cs @@ -0,0 +1,39 @@ +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels +{ + public class ViewPublicFavoritesViewModel : BaseViewModel + { + public const string Tag = "PagePublicFavorites"; + + // 收藏夹id + private long favoritesId; + + public ViewPublicFavoritesViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + } + + /// + /// 接收收藏夹id参数 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + // 根据传入参数不同执行不同任务 + long parameter = navigationContext.Parameters.GetValue("Parameter"); + if (parameter == 0) + { + return; + } + favoritesId = parameter; + } + } +} diff --git a/DownKyi/ViewModels/ViewSettingsViewModel.cs b/DownKyi/ViewModels/ViewSettingsViewModel.cs new file mode 100644 index 0000000..6518b94 --- /dev/null +++ b/DownKyi/ViewModels/ViewSettingsViewModel.cs @@ -0,0 +1,137 @@ +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Models; +using DownKyi.Utils; +using DownKyi.ViewModels.Settings; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; + +namespace DownKyi.ViewModels +{ + public class ViewSettingsViewModel : BaseViewModel + { + public const string Tag = "PageSettings"; + + private readonly IRegionManager regionManager; + + #region 页面属性申明 + + private VectorImage arrowBack; + public VectorImage ArrowBack + { + get { return arrowBack; } + set { SetProperty(ref arrowBack, value); } + } + + private List tabHeaders; + public List TabHeaders + { + get { return tabHeaders; } + set { SetProperty(ref tabHeaders, value); } + } + + private int selectTabId; + public int SelectTabId + { + get { return selectTabId; } + set { SetProperty(ref selectTabId, value); } + } + + #endregion + + + public ViewSettingsViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) : base(eventAggregator) + { + this.regionManager = regionManager; + + #region 属性初始化 + + ArrowBack = NavigationIcon.Instance().ArrowBack; + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + + TabHeaders = new List + { + new TabHeader { Id = 0, Title = DictionaryResource.GetString("Basic") }, + new TabHeader { Id = 1, Title = DictionaryResource.GetString("Network") }, + new TabHeader { Id = 2, Title = DictionaryResource.GetString("Video") }, + new TabHeader { Id = 3, Title = DictionaryResource.GetString("SettingDanmaku") }, + new TabHeader { Id = 4, Title = DictionaryResource.GetString("About") } + }; + + #endregion + + } + + #region 命令申明 + + // 返回事件 + private DelegateCommand backSpaceCommand; + public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); + + /// + /// 返回事件 + /// + private void ExecuteBackSpace() + { + NavigationParam parameter = new NavigationParam + { + ViewName = ParentView, + ParentViewName = null, + Parameter = null + }; + eventAggregator.GetEvent().Publish(parameter); + } + + // 左侧tab点击事件 + private DelegateCommand leftTabHeadersCommand; + public DelegateCommand LeftTabHeadersCommand => leftTabHeadersCommand ?? (leftTabHeadersCommand = new DelegateCommand(ExecuteLeftTabHeadersCommand)); + + /// + /// 左侧tab点击事件 + /// + /// + private void ExecuteLeftTabHeadersCommand(object parameter) + { + if (!(parameter is TabHeader tabHeader)) { return; } + + NavigationParameters param = new NavigationParameters(); + + switch (tabHeader.Id) + { + case 0: + regionManager.RequestNavigate("SettingsContentRegion", ViewBasicViewModel.Tag, param); + break; + case 1: + regionManager.RequestNavigate("SettingsContentRegion", ViewNetworkViewModel.Tag, param); + break; + case 2: + regionManager.RequestNavigate("SettingsContentRegion", ViewVideoViewModel.Tag, param); + break; + case 3: + regionManager.RequestNavigate("SettingsContentRegion", ViewDanmakuViewModel.Tag, param); + break; + case 4: + regionManager.RequestNavigate("SettingsContentRegion", ViewAboutViewModel.Tag, param); + break; + } + } + + #endregion + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + // 进入设置页面时显示的设置项 + SelectTabId = 0; + regionManager.RequestNavigate("SettingsContentRegion", ViewBasicViewModel.Tag, new NavigationParameters()); + } + + } +} diff --git a/DownKyi/ViewModels/ViewToolboxViewModel.cs b/DownKyi/ViewModels/ViewToolboxViewModel.cs new file mode 100644 index 0000000..e476c17 --- /dev/null +++ b/DownKyi/ViewModels/ViewToolboxViewModel.cs @@ -0,0 +1,128 @@ +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Models; +using DownKyi.Utils; +using DownKyi.ViewModels.Toolbox; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; + +namespace DownKyi.ViewModels +{ + public class ViewToolboxViewModel : BaseViewModel + { + public const string Tag = "PageToolbox"; + + private readonly IRegionManager regionManager; + + #region 页面属性申明 + + private VectorImage arrowBack; + public VectorImage ArrowBack + { + get { return arrowBack; } + set { SetProperty(ref arrowBack, value); } + } + + private List tabHeaders; + public List TabHeaders + { + get { return tabHeaders; } + set { SetProperty(ref tabHeaders, value); } + } + + private int selectTabId; + public int SelectTabId + { + get { return selectTabId; } + set { SetProperty(ref selectTabId, value); } + } + + #endregion + + public ViewToolboxViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) : base(eventAggregator) + { + this.regionManager = regionManager; + + #region 属性初始化 + + ArrowBack = NavigationIcon.Instance().ArrowBack; + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + + TabHeaders = new List + { + new TabHeader { Id = 0, Title = DictionaryResource.GetString("BiliHelper") }, + new TabHeader { Id = 1, Title = DictionaryResource.GetString("Delogo") }, + new TabHeader { Id = 2, Title = DictionaryResource.GetString("ExtractMedia") } + }; + + #endregion + + } + + #region 命令申明 + + // 返回事件 + private DelegateCommand backSpaceCommand; + public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); + + /// + /// 返回事件 + /// + private void ExecuteBackSpace() + { + NavigationParam parameter = new NavigationParam + { + ViewName = ParentView, + ParentViewName = null, + Parameter = null + }; + eventAggregator.GetEvent().Publish(parameter); + } + + // 左侧tab点击事件 + private DelegateCommand leftTabHeadersCommand; + public DelegateCommand LeftTabHeadersCommand => leftTabHeadersCommand ?? (leftTabHeadersCommand = new DelegateCommand(ExecuteLeftTabHeadersCommand)); + + /// + /// 左侧tab点击事件 + /// + /// + private void ExecuteLeftTabHeadersCommand(object parameter) + { + if (!(parameter is TabHeader tabHeader)) { return; } + + NavigationParameters param = new NavigationParameters(); + + switch (tabHeader.Id) + { + case 0: + regionManager.RequestNavigate("ToolboxContentRegion", ViewBiliHelperViewModel.Tag, param); + break; + case 1: + regionManager.RequestNavigate("ToolboxContentRegion", ViewDelogoViewModel.Tag, param); + break; + case 2: + regionManager.RequestNavigate("ToolboxContentRegion", ViewExtractMediaViewModel.Tag, param); + break; + } + } + + #endregion + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + // 进入设置页面时显示的设置项 + SelectTabId = 0; + regionManager.RequestNavigate("ToolboxContentRegion", ViewBiliHelperViewModel.Tag, new NavigationParameters()); + } + + } +} diff --git a/DownKyi/ViewModels/ViewUserSpaceViewModel.cs b/DownKyi/ViewModels/ViewUserSpaceViewModel.cs new file mode 100644 index 0000000..627d0f2 --- /dev/null +++ b/DownKyi/ViewModels/ViewUserSpaceViewModel.cs @@ -0,0 +1,40 @@ +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using Prism.Regions; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DownKyi.ViewModels +{ + public class ViewUserSpaceViewModel : BaseViewModel + { + public const string Tag = "PageUserSpace"; + + // mid + private long mid; + + public ViewUserSpaceViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + } + + /// + /// 接收mid参数 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + // 根据传入参数不同执行不同任务 + long parameter = navigationContext.Parameters.GetValue("Parameter"); + if (parameter == 0) + { + return; + } + mid = parameter; + } + + } +} diff --git a/DownKyi/ViewModels/ViewVideoDetailViewModel.cs b/DownKyi/ViewModels/ViewVideoDetailViewModel.cs new file mode 100644 index 0000000..b7d4940 --- /dev/null +++ b/DownKyi/ViewModels/ViewVideoDetailViewModel.cs @@ -0,0 +1,664 @@ +using DownKyi.Core.BiliApi.BiliUtils; +using DownKyi.Core.Logging; +using DownKyi.Core.Settings; +using DownKyi.CustomControl; +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Models; +using DownKyi.Services; +using DownKyi.Utils; +using DownKyi.ViewModels.Dialogs; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; +using Prism.Services.Dialogs; +using System; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace DownKyi.ViewModels +{ + public class ViewVideoDetailViewModel : BaseViewModel + { + public const string Tag = "PageVideoDetail"; + + private readonly IDialogService dialogService; + + #region 页面属性申明 + + private VectorImage arrowBack; + public VectorImage ArrowBack + { + get { return arrowBack; } + set { SetProperty(ref arrowBack, value); } + } + + private string inputText; + public string InputText + { + get { return inputText; } + set { SetProperty(ref inputText, value); } + } + + private GifImage loading; + public GifImage Loading + { + get { return loading; } + set { SetProperty(ref loading, value); } + } + + private Visibility loadingVisibility; + public Visibility LoadingVisibility + { + get { return loadingVisibility; } + set { SetProperty(ref loadingVisibility, value); } + } + + private VectorImage downloadManage; + public VectorImage DownloadManage + { + get { return downloadManage; } + set { SetProperty(ref downloadManage, value); } + } + + private VideoInfoView videoInfoView; + public VideoInfoView VideoInfoView + { + get { return videoInfoView; } + set { SetProperty(ref videoInfoView, value); } + } + + private ObservableCollection videoSections; + public ObservableCollection VideoSections + { + get { return videoSections; } + set { SetProperty(ref videoSections, value); } + } + + private bool isSelectAll; + public bool IsSelectAll + { + get { return isSelectAll; } + set { SetProperty(ref isSelectAll, value); } + } + + private Visibility contentVisibility; + public Visibility ContentVisibility + { + get { return contentVisibility; } + set { SetProperty(ref contentVisibility, value); } + } + + private Visibility noDataVisibility; + public Visibility NoDataVisibility + { + get { return noDataVisibility; } + set { SetProperty(ref noDataVisibility, value); } + } + + #endregion + + + public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator) + { + this.dialogService = dialogService; + + #region 属性初始化 + + Loading = new GifImage(Properties.Resources.loading); + Loading.StartAnimate(); + LoadingVisibility = Visibility.Collapsed; + + ArrowBack = NavigationIcon.Instance().ArrowBack; + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + + DownloadManage = ButtonIcon.Instance().DownloadManage; + DownloadManage.Height = 24; + DownloadManage.Width = 24; + DownloadManage.Fill = DictionaryResource.GetColor("ColorPrimary"); + + VideoSections = new ObservableCollection(); + + #endregion + } + + + #region 命令申明 + + // 返回 + private DelegateCommand backSpaceCommand; + public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); + + /// + /// 返回 + /// + private void ExecuteBackSpace() + { + InitView(); + + NavigationParam parameter = new NavigationParam + { + ViewName = ParentView, + ParentViewName = null, + Parameter = null + }; + eventAggregator.GetEvent().Publish(parameter); + } + + // 前往下载管理页面 + private DelegateCommand downloadManagerCommand; + public DelegateCommand DownloadManagerCommand => downloadManagerCommand ?? (downloadManagerCommand = new DelegateCommand(ExecuteDownloadManagerCommand)); + + /// + /// 前往下载管理页面 + /// + private void ExecuteDownloadManagerCommand() + { + NavigationParam parameter = new NavigationParam + { + ViewName = ViewDownloadManagerViewModel.Tag, + ParentViewName = Tag, + Parameter = null + }; + eventAggregator.GetEvent().Publish(parameter); + } + + // 输入确认事件 + private DelegateCommand inputCommand; + public DelegateCommand InputCommand => inputCommand ?? (inputCommand = new DelegateCommand(ExecuteInputCommand, CanExecuteInputCommand)); + + /// + /// 处理输入事件 + /// + private async void ExecuteInputCommand() + { + InitView(); + try + { + await Task.Run(() => + { + if (InputText == null || InputText == string.Empty) { return; } + + LogManager.Debug(Tag, $"InputText: {InputText}"); + + // 更新页面 + UnityUpdateView(UpdateView, InputText, null); + + // 是否自动解析视频 + if (SettingsManager.GetInstance().IsAutoParseVideo() == AllowStatus.YES) + { + PropertyChangeAsync(ExecuteParseAllVideoCommand); + } + }); + } + catch (Exception e) + { + Core.Utils.Debug.Console.PrintLine("InputCommand()发生异常: {0}", e); + LogManager.Error(Tag, e); + + LoadingVisibility = Visibility.Collapsed; + ContentVisibility = Visibility.Collapsed; + NoDataVisibility = Visibility.Visible; + } + } + + /// + /// 输入事件是否允许执行 + /// + /// + private bool CanExecuteInputCommand() + { + return LoadingVisibility != Visibility.Visible; + } + + // 复制封面事件 + private DelegateCommand copyCoverCommand; + public DelegateCommand CopyCoverCommand => copyCoverCommand ?? (copyCoverCommand = new DelegateCommand(ExecuteCopyCoverCommand)); + + /// + /// 复制封面事件 + /// + private void ExecuteCopyCoverCommand() + { + // 复制封面图片到剪贴板 + Clipboard.SetImage(VideoInfoView.Cover); + LogManager.Info(Tag, "复制封面图片到剪贴板"); + } + + // 复制封面URL事件 + private DelegateCommand copyCoverUrlCommand; + public DelegateCommand CopyCoverUrlCommand => copyCoverUrlCommand ?? (copyCoverUrlCommand = new DelegateCommand(ExecuteCopyCoverUrlCommand)); + + /// + /// 复制封面URL事件 + /// + private void ExecuteCopyCoverUrlCommand() + { + // 复制封面url到剪贴板 + Clipboard.SetText(VideoInfoView.CoverUrl); + LogManager.Info(Tag, "复制封面url到剪贴板"); + } + + // 视频章节选择事件 + private DelegateCommand videoSectionsCommand; + public DelegateCommand VideoSectionsCommand => videoSectionsCommand ?? (videoSectionsCommand = new DelegateCommand(ExecuteVideoSectionsCommand)); + + /// + /// 视频章节选择事件 + /// + /// + private void ExecuteVideoSectionsCommand(object parameter) + { + if (!(parameter is VideoSection section)) { return; } + + bool isSelectAll = true; + foreach (var page in section.VideoPages) + { + if (!page.IsSelected) + { + isSelectAll = false; + break; + } + } + + IsSelectAll = section.VideoPages.Count != 0 && isSelectAll; + } + + // 视频page选择事件 + private DelegateCommand videoPagesCommand; + public DelegateCommand VideoPagesCommand => videoPagesCommand ?? (videoPagesCommand = new DelegateCommand(ExecuteVideoPagesCommand)); + + /// + /// 视频page选择事件 + /// + /// + private void ExecuteVideoPagesCommand(object parameter) + { + if (!(parameter is ObservableCollection videoPages)) { return; } + + VideoSection section = VideoSections.FirstOrDefault(item => item.IsSelected); + if (section == null) { return; } + IsSelectAll = section.VideoPages.Count == videoPages.Count && section.VideoPages.Count != 0; + } + + // Ctrl+A 全选事件 + private DelegateCommand keySelectAllCommand; + public DelegateCommand KeySelectAllCommand => keySelectAllCommand ?? (keySelectAllCommand = new DelegateCommand(ExecuteKeySelectAllCommand)); + + /// + /// Ctrl+A 全选事件 + /// + private void ExecuteKeySelectAllCommand(object parameter) + { + if (!(parameter is VideoSection section)) { return; } + foreach (var page in section.VideoPages) + { + page.IsSelected = true; + } + } + + // 全选事件 + private DelegateCommand selectAllCommand; + public DelegateCommand SelectAllCommand => selectAllCommand ?? (selectAllCommand = new DelegateCommand(ExecuteSelectAllCommand)); + + /// + /// 全选事件 + /// + /// + private void ExecuteSelectAllCommand(object parameter) + { + if (!(parameter is VideoSection section)) { return; } + if (IsSelectAll) + { + foreach (var page in section.VideoPages) + { + page.IsSelected = true; + } + } + else + { + foreach (var page in section.VideoPages) + { + page.IsSelected = false; + } + } + } + + // 解析视频流事件 + private DelegateCommand parseCommand; + public DelegateCommand ParseCommand => parseCommand ?? (parseCommand = new DelegateCommand(ExecuteParseCommand, CanExecuteParseCommand)); + + /// + /// 解析视频流事件 + /// + /// + private async void ExecuteParseCommand(object parameter) + { + if (!(parameter is VideoPage videoPage)) + { + return; + } + + LoadingVisibility = Visibility.Visible; + + try + { + await Task.Run(() => + { + LogManager.Debug(Tag, $"Video Page: {videoPage.Cid}"); + + UnityUpdateView(ParseVideo, null, videoPage); + }); + } + catch (Exception e) + { + Core.Utils.Debug.Console.PrintLine("ParseCommand()发生异常: {0}", e); + LogManager.Error(Tag, e); + + LoadingVisibility = Visibility.Collapsed; + } + + LoadingVisibility = Visibility.Collapsed; + } + + /// + /// 解析视频流事件是否允许执行 + /// + /// + /// + private bool CanExecuteParseCommand(object parameter) + { + return LoadingVisibility != Visibility.Visible; + } + + // 解析所有视频流事件 + private DelegateCommand parseAllVideoCommand; + public DelegateCommand ParseAllVideoCommand => parseAllVideoCommand ?? (parseAllVideoCommand = new DelegateCommand(ExecuteParseAllVideoCommand, CanExecuteParseAllVideoCommand)); + + /// + /// 解析所有视频流事件 + /// + private async void ExecuteParseAllVideoCommand() + { + LoadingVisibility = Visibility.Visible; + + // 解析范围 + ParseScope parseScope = SettingsManager.GetInstance().GetParseScope(); + + // 是否选择了解析范围 + if (parseScope == ParseScope.NONE) + { + // 打开解析选择器 + dialogService.ShowDialog(ViewParsingSelectorViewModel.Tag, null, result => + { + if (result.Result == ButtonResult.OK) + { + // 选择的解析范围 + parseScope = result.Parameters.GetValue("parseScope"); + } + }); + } + LogManager.Debug(Tag, $"ParseScope: {parseScope:G}"); + + try + { + await Task.Run(() => + { + LogManager.Debug(Tag, "Parse video"); + + switch (parseScope) + { + case ParseScope.NONE: + break; + case ParseScope.SELECTED_ITEM: + foreach (var section in VideoSections) + { + foreach (var page in section.VideoPages) + { + var videoPage = section.VideoPages.FirstOrDefault(t => t == page); + + if (videoPage.IsSelected) + { + // 执行解析任务 + UnityUpdateView(ParseVideo, null, videoPage); + } + } + } + break; + case ParseScope.CURRENT_SECTION: + foreach (var section in VideoSections) + { + if (section.IsSelected) + { + foreach (var page in section.VideoPages) + { + var videoPage = section.VideoPages.FirstOrDefault(t => t == page); + + // 执行解析任务 + UnityUpdateView(ParseVideo, null, videoPage); + } + } + } + break; + case ParseScope.ALL: + foreach (var section in VideoSections) + { + foreach (var page in section.VideoPages) + { + var videoPage = section.VideoPages.FirstOrDefault(t => t == page); + + // 执行解析任务 + UnityUpdateView(ParseVideo, null, videoPage); + } + } + break; + default: + break; + } + }); + } + catch (Exception e) + { + Core.Utils.Debug.Console.PrintLine("ParseCommand()发生异常: {0}", e); + LogManager.Error(Tag, e); + + LoadingVisibility = Visibility.Collapsed; + } + + LoadingVisibility = Visibility.Collapsed; + } + + /// + /// 解析所有视频流事件是否允许执行 + /// + /// + private bool CanExecuteParseAllVideoCommand() + { + return LoadingVisibility != Visibility.Visible; + } + + // 添加到下载列表事件 + private DelegateCommand addToDownloadCommand; + public DelegateCommand AddToDownloadCommand => addToDownloadCommand ?? (addToDownloadCommand = new DelegateCommand(ExecuteAddToDownloadCommand, CanExecuteAddToDownloadCommand)); + + /// + /// 添加到下载列表事件 + /// + private void ExecuteAddToDownloadCommand() + { + // 选择的下载文件夹 + string directory = string.Empty; + + // 是否使用默认下载目录 + if (SettingsManager.GetInstance().IsUseSaveVideoRootPath() == AllowStatus.YES) + { + directory = SettingsManager.GetInstance().GetSaveVideoRootPath(); + } + else + { + // 打开文件夹选择器 + dialogService.ShowDialog(ViewDirectorySelectorViewModel.Tag, null, result => + { + if (result.Result == ButtonResult.OK) + { + // 选择的下载文件夹 + directory = result.Parameters.GetValue("directory"); + + // 文件夹不存在则创建 + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + // 添加到下载 + eventAggregator.GetEvent().Publish(directory); + } + }); + } + } + + /// + /// 添加到下载列表事件是否允许执行 + /// + /// + private bool CanExecuteAddToDownloadCommand() + { + return LoadingVisibility != Visibility.Visible; + } + + #endregion + + + #region 业务逻辑 + + /// + /// 初始化页面元素 + /// + private void InitView() + { + LogManager.Debug(Tag, "初始化页面元素"); + + LoadingVisibility = Visibility.Visible; + ContentVisibility = Visibility.Collapsed; + NoDataVisibility = Visibility.Collapsed; + + VideoSections.Clear(); + } + + /// + /// 更新页面的统一方法 + /// + /// + /// + /// + private void UnityUpdateView(Action action, string input, VideoPage page) + { + // 视频 + if (ParseEntrance.IsAvUrl(InputText) || ParseEntrance.IsBvUrl(InputText)) + { + action(new VideoInfoService(input), page); + } + + // 番剧(电影、电视剧) + if (ParseEntrance.IsBangumiSeasonUrl(InputText) || ParseEntrance.IsBangumiEpisodeUrl(InputText) || ParseEntrance.IsBangumiMediaUrl(InputText)) + { + action(new BangumiInfoService(input), page); + } + + // 课程 + if (ParseEntrance.IsCheeseSeasonUrl(InputText) || ParseEntrance.IsCheeseEpisodeUrl(InputText)) + { + action(new CheeseInfoService(input), page); + } + } + + /// + /// 更新页面 + /// + /// + private void UpdateView(IInfoService videoInfoService, VideoPage param) + { + VideoInfoView = videoInfoService.GetVideoView(); + if (VideoInfoView == null) + { + LogManager.Debug(Tag, "VideoInfoView is null."); + + LoadingVisibility = Visibility.Collapsed; + ContentVisibility = Visibility.Collapsed; + NoDataVisibility = Visibility.Visible; + return; + } + else + { + LoadingVisibility = Visibility.Collapsed; + ContentVisibility = Visibility.Visible; + } + + var videoSections = videoInfoService.GetVideoSections(); + if (videoSections == null) + { + LogManager.Debug(Tag, "videoSections is not exist."); + + var pages = videoInfoService.GetVideoPages(); + + PropertyChangeAsync(new Action(() => + { + VideoSections.Add(new VideoSection + { + Id = 0, + Title = "default", + IsSelected = true, + VideoPages = pages + }); + })); + } + else + { + PropertyChangeAsync(new Action(() => + { + VideoSections.AddRange(videoSections); + })); + } + } + + /// + /// 解析视频流 + /// + /// + private void ParseVideo(IInfoService videoInfoService, VideoPage videoPage) + { + videoInfoService.GetVideoStream(videoPage); + } + + #endregion + + /// + /// 导航到VideoDetail页面时执行 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + DownloadManage = ButtonIcon.Instance().DownloadManage; + DownloadManage.Height = 24; + DownloadManage.Width = 24; + DownloadManage.Fill = DictionaryResource.GetColor("ColorPrimary"); + + // Parent参数为null时,表示是从下一个页面返回到本页面,不需要执行任务 + if (navigationContext.Parameters.GetValue("Parent") != null) + { + // 正在执行任务时不开启新任务 + if (LoadingVisibility != Visibility.Visible) + { + InputText = navigationContext.Parameters.GetValue("Parameter"); + PropertyChangeAsync(ExecuteInputCommand); + } + } + } + + } +} diff --git a/DownKyi/Views/Dialogs/ViewDirectorySelector.xaml b/DownKyi/Views/Dialogs/ViewDirectorySelector.xaml new file mode 100644 index 0000000..d02e900 --- /dev/null +++ b/DownKyi/Views/Dialogs/ViewDirectorySelector.xaml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/MainWindow.xaml.cs b/DownKyi/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..414eabd --- /dev/null +++ b/DownKyi/Views/MainWindow.xaml.cs @@ -0,0 +1,16 @@ +using System.Windows; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + + } +} \ No newline at end of file diff --git a/DownKyi/Views/Settings/ViewAbout.xaml b/DownKyi/Views/Settings/ViewAbout.xaml new file mode 100644 index 0000000..896e8d9 --- /dev/null +++ b/DownKyi/Views/Settings/ViewAbout.xaml @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/ViewDownloadManager.xaml.cs b/DownKyi/Views/ViewDownloadManager.xaml.cs new file mode 100644 index 0000000..23e31e9 --- /dev/null +++ b/DownKyi/Views/ViewDownloadManager.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewDownloadManager + /// + public partial class ViewDownloadManager : UserControl + { + public ViewDownloadManager() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewIndex.xaml b/DownKyi/Views/ViewIndex.xaml new file mode 100644 index 0000000..ed0e9a9 --- /dev/null +++ b/DownKyi/Views/ViewIndex.xaml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/ViewIndex.xaml.cs b/DownKyi/Views/ViewIndex.xaml.cs new file mode 100644 index 0000000..48f47ec --- /dev/null +++ b/DownKyi/Views/ViewIndex.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewIndex + /// + public partial class ViewIndex : UserControl + { + public ViewIndex() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewLogin.xaml b/DownKyi/Views/ViewLogin.xaml new file mode 100644 index 0000000..fc83397 --- /dev/null +++ b/DownKyi/Views/ViewLogin.xaml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/ViewLogin.xaml.cs b/DownKyi/Views/ViewLogin.xaml.cs new file mode 100644 index 0000000..fa0f2eb --- /dev/null +++ b/DownKyi/Views/ViewLogin.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewLogin + /// + public partial class ViewLogin : UserControl + { + public ViewLogin() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewMySpace.xaml b/DownKyi/Views/ViewMySpace.xaml new file mode 100644 index 0000000..6f40d3f --- /dev/null +++ b/DownKyi/Views/ViewMySpace.xaml @@ -0,0 +1,10 @@ + + + 我的用户空间 + + diff --git a/DownKyi/Views/ViewMySpace.xaml.cs b/DownKyi/Views/ViewMySpace.xaml.cs new file mode 100644 index 0000000..f9b726a --- /dev/null +++ b/DownKyi/Views/ViewMySpace.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewMySpace + /// + public partial class ViewMySpace : UserControl + { + public ViewMySpace() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewPublicFavorites.xaml b/DownKyi/Views/ViewPublicFavorites.xaml new file mode 100644 index 0000000..c06d6e9 --- /dev/null +++ b/DownKyi/Views/ViewPublicFavorites.xaml @@ -0,0 +1,10 @@ + + + 公开访问的收藏夹 + + diff --git a/DownKyi/Views/ViewPublicFavorites.xaml.cs b/DownKyi/Views/ViewPublicFavorites.xaml.cs new file mode 100644 index 0000000..91c1fb2 --- /dev/null +++ b/DownKyi/Views/ViewPublicFavorites.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewPublicFavorites + /// + public partial class ViewPublicFavorites : UserControl + { + public ViewPublicFavorites() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewSettings.xaml b/DownKyi/Views/ViewSettings.xaml new file mode 100644 index 0000000..fcdd224 --- /dev/null +++ b/DownKyi/Views/ViewSettings.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/ViewSettings.xaml.cs b/DownKyi/Views/ViewSettings.xaml.cs new file mode 100644 index 0000000..99646f3 --- /dev/null +++ b/DownKyi/Views/ViewSettings.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewSettings + /// + public partial class ViewSettings : UserControl + { + public ViewSettings() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewToolbox.xaml b/DownKyi/Views/ViewToolbox.xaml new file mode 100644 index 0000000..5e174ac --- /dev/null +++ b/DownKyi/Views/ViewToolbox.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/ViewToolbox.xaml.cs b/DownKyi/Views/ViewToolbox.xaml.cs new file mode 100644 index 0000000..11fa7eb --- /dev/null +++ b/DownKyi/Views/ViewToolbox.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewTools + /// + public partial class ViewToolbox : UserControl + { + public ViewToolbox() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewUserSpace.xaml b/DownKyi/Views/ViewUserSpace.xaml new file mode 100644 index 0000000..7b6477c --- /dev/null +++ b/DownKyi/Views/ViewUserSpace.xaml @@ -0,0 +1,10 @@ + + + 用户空间 + + diff --git a/DownKyi/Views/ViewUserSpace.xaml.cs b/DownKyi/Views/ViewUserSpace.xaml.cs new file mode 100644 index 0000000..92dcb15 --- /dev/null +++ b/DownKyi/Views/ViewUserSpace.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace DownKyi.Views +{ + /// + /// Interaction logic for ViewUserSpace + /// + public partial class ViewUserSpace : UserControl + { + public ViewUserSpace() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewVideoDetail.xaml b/DownKyi/Views/ViewVideoDetail.xaml new file mode 100644 index 0000000..5b036b5 --- /dev/null +++ b/DownKyi/Views/ViewVideoDetail.xaml @@ -0,0 +1,730 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +