From 1ca966f617ad10ab8afc11aa54868d000bb10eb5 Mon Sep 17 00:00:00 2001 From: leiurayer <1432593898@qq.com> Date: Thu, 1 Aug 2024 22:27:36 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E5=87=BA=E5=87=A0=E4=B8=AA?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Avalonia.Gif/Avalonia.Gif.csproj | 13 - src/Avalonia.Gif/BgWorkerCommand.cs | 10 - src/Avalonia.Gif/BgWorkerState.cs | 12 - src/Avalonia.Gif/Decoding/BlockTypes.cs | 10 - src/Avalonia.Gif/Decoding/ExtensionType.cs | 8 - src/Avalonia.Gif/Decoding/FrameDisposal.cs | 10 - src/Avalonia.Gif/Decoding/GifColor.cs | 36 - src/Avalonia.Gif/Decoding/GifDecoder.cs | 657 ---- src/Avalonia.Gif/Decoding/GifFrame.cs | 17 - src/Avalonia.Gif/Decoding/GifHeader.cs | 19 - src/Avalonia.Gif/Decoding/GifRect.cs | 45 - .../Decoding/GifRepeatBehavior.cs | 8 - .../Decoding/InvalidGifStreamException.cs | 28 - .../Decoding/LzwDecompressionException.cs | 28 - .../Extensions/StreamExtensions.cs | 82 - src/Avalonia.Gif/GifImage.cs | 276 -- src/Avalonia.Gif/GifInstance.cs | 140 - src/Avalonia.Gif/InvalidGifStreamException.cs | 25 - .../Api/Login/TestLoginInfo.cs | 35 - .../Api/Login/TestLoginNotice.cs | 16 - .../Api/Login/TestLoginQR.cs | 23 - .../Api/Sign/TestWbiSign.cs | 87 - .../Api/User/TestNickname.cs | 25 - .../Api/User/TestUserInfo.cs | 70 - .../Api/Video/TestVideoInfo.cs | 28 - .../BiliSharp.UnitTest.csproj | 29 - src/BiliSharp.UnitTest/Cookies.cs | 43 - src/BiliSharp.UnitTest/Usings.cs | 1 - src/BiliSharp/Api/Login/LoginInfo.cs | 40 - src/BiliSharp/Api/Login/LoginNotice.cs | 18 - src/BiliSharp/Api/Login/LoginQR.cs | 30 - .../Api/Models/Login/LoginInfoStat.cs | 58 - src/BiliSharp/Api/Models/Login/LoginNotice.cs | 76 - src/BiliSharp/Api/Models/Login/LoginQRCode.cs | 52 - .../Api/Models/Login/LoginQRCodePoll.cs | 70 - src/BiliSharp/Api/Models/Login/MyCoin.cs | 40 - .../Api/Models/Login/NavigationLoginInfo.cs | 556 --- src/BiliSharp/Api/Models/User/MyInfo.cs | 652 ---- src/BiliSharp/Api/Models/User/Nickname.cs | 22 - src/BiliSharp/Api/Models/User/UserCard.cs | 599 --- src/BiliSharp/Api/Models/User/UserCards.cs | 443 --- .../Api/Models/User/UserSpaceInfo.cs | 827 ----- src/BiliSharp/Api/Models/Video/VideoView.cs | 3257 ----------------- src/BiliSharp/Api/Sign/WbiSign.cs | 133 - src/BiliSharp/Api/User/Nickname.cs | 19 - src/BiliSharp/Api/User/UserInfo.cs | 66 - src/BiliSharp/Api/Video/VideoInfo.cs | 35 - src/BiliSharp/BiliManager.cs | 53 - src/BiliSharp/BiliSharp.csproj | 11 - src/BiliSharp/Utils.cs | 29 - src/BiliSharp/WebClient.cs | 121 - src/Downkyi.sln | 18 - third_party/Avalonia.GIF-11rc1.zip | Bin 8964111 -> 0 bytes third_party/Avalonia.Gif.1.0.0.nupkg | Bin 0 -> 31252 bytes third_party/Downkyi.BiliSharp.0.0.2.nupkg | Bin 0 -> 112134 bytes 55 files changed, 9006 deletions(-) delete mode 100644 src/Avalonia.Gif/Avalonia.Gif.csproj delete mode 100644 src/Avalonia.Gif/BgWorkerCommand.cs delete mode 100644 src/Avalonia.Gif/BgWorkerState.cs delete mode 100644 src/Avalonia.Gif/Decoding/BlockTypes.cs delete mode 100644 src/Avalonia.Gif/Decoding/ExtensionType.cs delete mode 100644 src/Avalonia.Gif/Decoding/FrameDisposal.cs delete mode 100644 src/Avalonia.Gif/Decoding/GifColor.cs delete mode 100644 src/Avalonia.Gif/Decoding/GifDecoder.cs delete mode 100644 src/Avalonia.Gif/Decoding/GifFrame.cs delete mode 100644 src/Avalonia.Gif/Decoding/GifHeader.cs delete mode 100644 src/Avalonia.Gif/Decoding/GifRect.cs delete mode 100644 src/Avalonia.Gif/Decoding/GifRepeatBehavior.cs delete mode 100644 src/Avalonia.Gif/Decoding/InvalidGifStreamException.cs delete mode 100644 src/Avalonia.Gif/Decoding/LzwDecompressionException.cs delete mode 100644 src/Avalonia.Gif/Extensions/StreamExtensions.cs delete mode 100644 src/Avalonia.Gif/GifImage.cs delete mode 100644 src/Avalonia.Gif/GifInstance.cs delete mode 100644 src/Avalonia.Gif/InvalidGifStreamException.cs delete mode 100644 src/BiliSharp.UnitTest/Api/Login/TestLoginInfo.cs delete mode 100644 src/BiliSharp.UnitTest/Api/Login/TestLoginNotice.cs delete mode 100644 src/BiliSharp.UnitTest/Api/Login/TestLoginQR.cs delete mode 100644 src/BiliSharp.UnitTest/Api/Sign/TestWbiSign.cs delete mode 100644 src/BiliSharp.UnitTest/Api/User/TestNickname.cs delete mode 100644 src/BiliSharp.UnitTest/Api/User/TestUserInfo.cs delete mode 100644 src/BiliSharp.UnitTest/Api/Video/TestVideoInfo.cs delete mode 100644 src/BiliSharp.UnitTest/BiliSharp.UnitTest.csproj delete mode 100644 src/BiliSharp.UnitTest/Cookies.cs delete mode 100644 src/BiliSharp.UnitTest/Usings.cs delete mode 100644 src/BiliSharp/Api/Login/LoginInfo.cs delete mode 100644 src/BiliSharp/Api/Login/LoginNotice.cs delete mode 100644 src/BiliSharp/Api/Login/LoginQR.cs delete mode 100644 src/BiliSharp/Api/Models/Login/LoginInfoStat.cs delete mode 100644 src/BiliSharp/Api/Models/Login/LoginNotice.cs delete mode 100644 src/BiliSharp/Api/Models/Login/LoginQRCode.cs delete mode 100644 src/BiliSharp/Api/Models/Login/LoginQRCodePoll.cs delete mode 100644 src/BiliSharp/Api/Models/Login/MyCoin.cs delete mode 100644 src/BiliSharp/Api/Models/Login/NavigationLoginInfo.cs delete mode 100644 src/BiliSharp/Api/Models/User/MyInfo.cs delete mode 100644 src/BiliSharp/Api/Models/User/Nickname.cs delete mode 100644 src/BiliSharp/Api/Models/User/UserCard.cs delete mode 100644 src/BiliSharp/Api/Models/User/UserCards.cs delete mode 100644 src/BiliSharp/Api/Models/User/UserSpaceInfo.cs delete mode 100644 src/BiliSharp/Api/Models/Video/VideoView.cs delete mode 100644 src/BiliSharp/Api/Sign/WbiSign.cs delete mode 100644 src/BiliSharp/Api/User/Nickname.cs delete mode 100644 src/BiliSharp/Api/User/UserInfo.cs delete mode 100644 src/BiliSharp/Api/Video/VideoInfo.cs delete mode 100644 src/BiliSharp/BiliManager.cs delete mode 100644 src/BiliSharp/BiliSharp.csproj delete mode 100644 src/BiliSharp/Utils.cs delete mode 100644 src/BiliSharp/WebClient.cs delete mode 100644 third_party/Avalonia.GIF-11rc1.zip create mode 100644 third_party/Avalonia.Gif.1.0.0.nupkg create mode 100644 third_party/Downkyi.BiliSharp.0.0.2.nupkg diff --git a/src/Avalonia.Gif/Avalonia.Gif.csproj b/src/Avalonia.Gif/Avalonia.Gif.csproj deleted file mode 100644 index b83b9fb..0000000 --- a/src/Avalonia.Gif/Avalonia.Gif.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - net7.0 - latest - true - enable - - - - - - - diff --git a/src/Avalonia.Gif/BgWorkerCommand.cs b/src/Avalonia.Gif/BgWorkerCommand.cs deleted file mode 100644 index d561685..0000000 --- a/src/Avalonia.Gif/BgWorkerCommand.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Avalonia.Gif -{ - internal enum BgWorkerCommand - { - Null, - Play, - Pause, - Dispose - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/BgWorkerState.cs b/src/Avalonia.Gif/BgWorkerState.cs deleted file mode 100644 index ab3bc38..0000000 --- a/src/Avalonia.Gif/BgWorkerState.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Avalonia.Gif -{ - internal enum BgWorkerState - { - Null, - Start, - Running, - Paused, - Complete, - Dispose - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/BlockTypes.cs b/src/Avalonia.Gif/Decoding/BlockTypes.cs deleted file mode 100644 index ca2cc7a..0000000 --- a/src/Avalonia.Gif/Decoding/BlockTypes.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Avalonia.Gif.Decoding -{ - internal enum BlockTypes - { - Empty = 0, - Extension = 0x21, - ImageDescriptor = 0x2C, - Trailer = 0x3B, - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/ExtensionType.cs b/src/Avalonia.Gif/Decoding/ExtensionType.cs deleted file mode 100644 index ad7878b..0000000 --- a/src/Avalonia.Gif/Decoding/ExtensionType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Avalonia.Gif.Decoding -{ - internal enum ExtensionType - { - GraphicsControl = 0xF9, - Application = 0xFF - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/FrameDisposal.cs b/src/Avalonia.Gif/Decoding/FrameDisposal.cs deleted file mode 100644 index 178a3c5..0000000 --- a/src/Avalonia.Gif/Decoding/FrameDisposal.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Avalonia.Gif.Decoding -{ - public enum FrameDisposal - { - Unknown = 0, - Leave = 1, - Background = 2, - Restore = 3 - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/GifColor.cs b/src/Avalonia.Gif/Decoding/GifColor.cs deleted file mode 100644 index 7534cc1..0000000 --- a/src/Avalonia.Gif/Decoding/GifColor.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Avalonia.Gif -{ - [StructLayout(LayoutKind.Explicit)] - public readonly struct GifColor - { - [FieldOffset(3)] - public readonly byte A; - - [FieldOffset(2)] - public readonly byte R; - - [FieldOffset(1)] - public readonly byte G; - - [FieldOffset(0)] - public readonly byte B; - - /// - /// A struct that represents a ARGB color and is aligned as - /// a BGRA bytefield in memory. - /// - /// Red - /// Green - /// Blue - /// Alpha - public GifColor(byte r, byte g, byte b, byte a = byte.MaxValue) - { - A = a; - R = r; - G = g; - B = b; - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/GifDecoder.cs b/src/Avalonia.Gif/Decoding/GifDecoder.cs deleted file mode 100644 index 4a31742..0000000 --- a/src/Avalonia.Gif/Decoding/GifDecoder.cs +++ /dev/null @@ -1,657 +0,0 @@ -// This source file's Lempel-Ziv-Welch algorithm is derived from Chromium's Android GifPlayer -// as seen here (https://github.com/chromium/chromium/blob/master/third_party/gif_player/src/jp/tomorrowkey/android/gifplayer) -// Licensed under the Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0) -// Copyright (C) 2015 The Gifplayer Authors. All Rights Reserved. - -// The rest of the source file is licensed under MIT License. -// Copyright (C) 2018 Jumar A. Macato, All Rights Reserved. - -using Avalonia.Media.Imaging; -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using static Avalonia.Gif.Extensions.StreamExtensions; - -namespace Avalonia.Gif.Decoding -{ - public sealed class GifDecoder : IDisposable - { - private static readonly ReadOnlyMemory G87AMagic - = "GIF87a"u8.ToArray().AsMemory(); - - private static readonly ReadOnlyMemory G89AMagic - = "GIF89a"u8.ToArray().AsMemory(); - - private static readonly ReadOnlyMemory NetscapeMagic - = "NETSCAPE2.0"u8.ToArray().AsMemory(); - - private static readonly TimeSpan FrameDelayThreshold = TimeSpan.FromMilliseconds(10); - private static readonly TimeSpan FrameDelayDefault = TimeSpan.FromMilliseconds(100); - private static readonly GifColor TransparentColor = new(0, 0, 0, 0); - private static readonly int MaxTempBuf = 768; - private static readonly int MaxStackSize = 4096; - private static readonly int MaxBits = 4097; - - private readonly Stream _fileStream; - private readonly CancellationToken _currentCtsToken; - private readonly bool _hasFrameBackups; - - private int _gctSize, _bgIndex, _prevFrame = -1, _backupFrame = -1; - private bool _gctUsed; - - private GifRect _gifDimensions; - - // private ulong _globalColorTable; - private readonly int _backBufferBytes; - private GifColor[] _bitmapBackBuffer; - - private short[] _prefixBuf; - private byte[] _suffixBuf; - private byte[] _pixelStack; - private byte[] _indexBuf; - private byte[] _backupFrameIndexBuf; - private volatile bool _hasNewFrame; - - public GifHeader Header { get; private set; } - - public readonly List Frames = new(); - - public PixelSize Size => new PixelSize(Header.Dimensions.Width, Header.Dimensions.Height); - - public GifDecoder(Stream fileStream, CancellationToken currentCtsToken) - { - _fileStream = fileStream; - _currentCtsToken = currentCtsToken; - - ProcessHeaderData(); - ProcessFrameData(); - - Header.IterationCount = Header.Iterations switch - { - -1 => new GifRepeatBehavior { Count = 1 }, - 0 => new GifRepeatBehavior { LoopForever = true }, - > 0 => new GifRepeatBehavior { Count = Header.Iterations }, - _ => Header.IterationCount - }; - - var pixelCount = _gifDimensions.TotalPixels; - - _hasFrameBackups = Frames - .Any(f => f.FrameDisposalMethod == FrameDisposal.Restore); - - _bitmapBackBuffer = new GifColor[pixelCount]; - _indexBuf = new byte[pixelCount]; - - if (_hasFrameBackups) - _backupFrameIndexBuf = new byte[pixelCount]; - - _prefixBuf = new short[MaxStackSize]; - _suffixBuf = new byte[MaxStackSize]; - _pixelStack = new byte[MaxStackSize + 1]; - - _backBufferBytes = pixelCount * Marshal.SizeOf(typeof(GifColor)); - } - - public void Dispose() - { - Frames.Clear(); - - _bitmapBackBuffer = null; - _prefixBuf = null; - _suffixBuf = null; - _pixelStack = null; - _indexBuf = null; - _backupFrameIndexBuf = null; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int PixCoord(int x, int y) => x + y * _gifDimensions.Width; - - static readonly (int Start, int Step)[] Pass = - { - (0, 8), - (4, 8), - (2, 4), - (1, 2) - }; - - private void ClearImage() - { - Array.Fill(_bitmapBackBuffer, TransparentColor); - //ClearArea(_gifDimensions); - - _prevFrame = -1; - _backupFrame = -1; - } - - public void RenderFrame(int fIndex, WriteableBitmap writeableBitmap, bool forceClear = false) - { - if (_currentCtsToken.IsCancellationRequested) - return; - - if (fIndex < 0 | fIndex >= Frames.Count) - return; - - if (_prevFrame == fIndex) - return; - - if (fIndex == 0 || forceClear || fIndex < _prevFrame) - ClearImage(); - - DisposePreviousFrame(); - - _prevFrame++; - - // render intermediate frame - for (int idx = _prevFrame; idx < fIndex; ++idx) - { - var prevFrame = Frames[idx]; - - if (prevFrame.FrameDisposalMethod == FrameDisposal.Restore) - continue; - - if (prevFrame.FrameDisposalMethod == FrameDisposal.Background) - { - ClearArea(prevFrame.Dimensions); - continue; - } - - RenderFrameAt(idx, writeableBitmap); - } - - RenderFrameAt(fIndex, writeableBitmap); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void RenderFrameAt(int idx, WriteableBitmap writeableBitmap) - { - var tmpB = ArrayPool.Shared.Rent(MaxTempBuf); - - var curFrame = Frames[idx]; - DecompressFrameToIndexBuffer(curFrame, _indexBuf, tmpB); - - if (_hasFrameBackups & curFrame.ShouldBackup) - { - Buffer.BlockCopy(_indexBuf, 0, _backupFrameIndexBuf, 0, curFrame.Dimensions.TotalPixels); - _backupFrame = idx; - } - - DrawFrame(curFrame, _indexBuf); - - _prevFrame = idx; - _hasNewFrame = true; - - using var lockedBitmap = writeableBitmap.Lock(); - WriteBackBufToFb(lockedBitmap.Address); - - ArrayPool.Shared.Return(tmpB); - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void DrawFrame(GifFrame curFrame, Memory frameIndexSpan) - { - var activeColorTable = - curFrame.IsLocalColorTableUsed ? curFrame.LocalColorTable : Header.GlobarColorTable; - - var cX = curFrame.Dimensions.X; - var cY = curFrame.Dimensions.Y; - var cH = curFrame.Dimensions.Height; - var cW = curFrame.Dimensions.Width; - var tC = curFrame.TransparentColorIndex; - var hT = curFrame.HasTransparency; - - if (curFrame.IsInterlaced) - { - for (var i = 0; i < 4; i++) - { - var curPass = Pass[i]; - var y = curPass.Start; - while (y < cH) - { - DrawRow(y); - y += curPass.Step; - } - } - } - else - { - for (var i = 0; i < cH; i++) - DrawRow(i); - } - - //for (var row = 0; row < cH; row++) - void DrawRow(int row) - { - // Get the starting point of the current row on frame's index stream. - var indexOffset = row * cW; - - // Get the target backbuffer offset from the frames coords. - var targetOffset = PixCoord(cX, row + cY); - var len = _bitmapBackBuffer.Length; - - for (var i = 0; i < cW; i++) - { - var indexColor = frameIndexSpan.Span[indexOffset + i]; - - if (activeColorTable == null || targetOffset >= len || - indexColor > activeColorTable.Length) return; - - if (!(hT & indexColor == tC)) - _bitmapBackBuffer[targetOffset] = activeColorTable[indexColor]; - - targetOffset++; - } - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void DisposePreviousFrame() - { - if (_prevFrame == -1) - return; - - var prevFrame = Frames[_prevFrame]; - - switch (prevFrame.FrameDisposalMethod) - { - case FrameDisposal.Background: - ClearArea(prevFrame.Dimensions); - break; - case FrameDisposal.Restore: - if (_hasFrameBackups && _backupFrame != -1) - DrawFrame(Frames[_backupFrame], _backupFrameIndexBuf); - else - ClearArea(prevFrame.Dimensions); - break; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ClearArea(GifRect area) - { - for (var y = 0; y < area.Height; y++) - { - var targetOffset = PixCoord(area.X, y + area.Y); - for (var x = 0; x < area.Width; x++) - _bitmapBackBuffer[targetOffset + x] = TransparentColor; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void DecompressFrameToIndexBuffer(GifFrame curFrame, Span indexSpan, byte[] tempBuf) - { - _fileStream.Position = curFrame.LzwStreamPosition; - var totalPixels = curFrame.Dimensions.TotalPixels; - - // Initialize GIF data stream decoder. - var dataSize = curFrame.LzwMinCodeSize; - var clear = 1 << dataSize; - var endOfInformation = clear + 1; - var available = clear + 2; - var oldCode = -1; - var codeSize = dataSize + 1; - var codeMask = (1 << codeSize) - 1; - - for (var code = 0; code < clear; code++) - { - _prefixBuf[code] = 0; - _suffixBuf[code] = (byte)code; - } - - // Decode GIF pixel stream. - int bits, first, top, pixelIndex; - var datum = bits = first = top = pixelIndex = 0; - - while (pixelIndex < totalPixels) - { - var blockSize = _fileStream.ReadBlock(tempBuf); - - if (blockSize == 0) - break; - - var blockPos = 0; - - while (blockPos < blockSize) - { - datum += tempBuf[blockPos] << bits; - blockPos++; - - bits += 8; - - while (bits >= codeSize) - { - // Get the next code. - var code = datum & codeMask; - datum >>= codeSize; - bits -= codeSize; - - // Interpret the code - if (code == clear) - { - // Reset decoder. - codeSize = dataSize + 1; - codeMask = (1 << codeSize) - 1; - available = clear + 2; - oldCode = -1; - continue; - } - - // Check for explicit end-of-stream - if (code == endOfInformation) - return; - - if (oldCode == -1) - { - indexSpan[pixelIndex++] = _suffixBuf[code]; - oldCode = code; - first = code; - continue; - } - - var inCode = code; - if (code >= available) - { - _pixelStack[top++] = (byte)first; - code = oldCode; - - if (top == MaxBits) - ThrowException(); - } - - while (code >= clear) - { - if (code >= MaxBits || code == _prefixBuf[code]) - ThrowException(); - - _pixelStack[top++] = _suffixBuf[code]; - code = _prefixBuf[code]; - - if (top == MaxBits) - ThrowException(); - } - - first = _suffixBuf[code]; - _pixelStack[top++] = (byte)first; - - // Add new code to the dictionary - if (available < MaxStackSize) - { - _prefixBuf[available] = (short)oldCode; - _suffixBuf[available] = (byte)first; - available++; - - if ((available & codeMask) == 0 && available < MaxStackSize) - { - codeSize++; - codeMask += available; - } - } - - oldCode = inCode; - - // Drain the pixel stack. - do - { - indexSpan[pixelIndex++] = _pixelStack[--top]; - } while (top > 0); - } - } - } - - while (pixelIndex < totalPixels) - indexSpan[pixelIndex++] = 0; // clear missing pixels - - void ThrowException() => throw new LzwDecompressionException(); - } - - /// - /// Directly copies the struct array to a bitmap IntPtr. - /// - private void WriteBackBufToFb(IntPtr targetPointer) - { - if (_currentCtsToken.IsCancellationRequested) - return; - - if (!(_hasNewFrame & _bitmapBackBuffer != null)) return; - - unsafe - { - fixed (void* src = &_bitmapBackBuffer[0]) - Buffer.MemoryCopy(src, targetPointer.ToPointer(), (uint)_backBufferBytes, - (uint)_backBufferBytes); - _hasNewFrame = false; - } - } - - /// - /// Processes GIF Header. - /// - private void ProcessHeaderData() - { - var str = _fileStream; - var tmpB = ArrayPool.Shared.Rent(MaxTempBuf); - var tempBuf = tmpB.AsSpan(); - - var _ = str.Read(tmpB, 0, 6); - - if (!tempBuf[..3].SequenceEqual(G87AMagic[..3].Span)) - throw new InvalidGifStreamException("Not a GIF stream."); - - if (!(tempBuf[..6].SequenceEqual(G87AMagic.Span) | - tempBuf[..6].SequenceEqual(G89AMagic.Span))) - throw new InvalidGifStreamException("Unsupported GIF Version: " + - Encoding.ASCII.GetString(tempBuf[..6].ToArray())); - - ProcessScreenDescriptor(tmpB); - - Header = new GifHeader - { - Dimensions = _gifDimensions, - HasGlobalColorTable = _gctUsed, - // GlobalColorTableCacheID = _globalColorTable, - GlobarColorTable = ProcessColorTable(ref str, tmpB, _gctSize), - GlobalColorTableSize = _gctSize, - BackgroundColorIndex = _bgIndex, - HeaderSize = _fileStream.Position - }; - - ArrayPool.Shared.Return(tmpB); - } - - /// - /// Parses colors from file stream to target color table. - /// - private static GifColor[] ProcessColorTable(ref Stream stream, byte[] rawBufSpan, int nColors) - { - var nBytes = 3 * nColors; - var target = new GifColor[nColors]; - - var n = stream.Read(rawBufSpan, 0, nBytes); - - if (n < nBytes) - throw new InvalidOperationException("Wrong color table bytes."); - - int i = 0, j = 0; - - while (i < nColors) - { - var r = rawBufSpan[j++]; - var g = rawBufSpan[j++]; - var b = rawBufSpan[j++]; - target[i++] = new GifColor(r, g, b); - } - - return target; - } - - /// - /// Parses screen and other GIF descriptors. - /// - private void ProcessScreenDescriptor(byte[] tempBuf) - { - var width = _fileStream.ReadUShortS(tempBuf); - var height = _fileStream.ReadUShortS(tempBuf); - - var packed = _fileStream.ReadByteS(tempBuf); - - _gctUsed = (packed & 0x80) != 0; - _gctSize = 2 << (packed & 7); - _bgIndex = _fileStream.ReadByteS(tempBuf); - - _gifDimensions = new GifRect(0, 0, width, height); - _fileStream.Skip(1); - } - - /// - /// Parses all frame data. - /// - private void ProcessFrameData() - { - _fileStream.Position = Header.HeaderSize; - - var tempBuf = ArrayPool.Shared.Rent(MaxTempBuf); - - var terminate = false; - var curFrame = 0; - - Frames.Add(new GifFrame()); - - do - { - var blockType = (BlockTypes)_fileStream.ReadByteS(tempBuf); - - switch (blockType) - { - case BlockTypes.Empty: - break; - - case BlockTypes.Extension: - ProcessExtensions(ref curFrame, tempBuf); - break; - - case BlockTypes.ImageDescriptor: - ProcessImageDescriptor(ref curFrame, tempBuf); - _fileStream.SkipBlocks(tempBuf); - break; - - case BlockTypes.Trailer: - Frames.RemoveAt(Frames.Count - 1); - terminate = true; - break; - - default: - _fileStream.SkipBlocks(tempBuf); - break; - } - - // Break the loop when the stream is not valid anymore. - if (_fileStream.Position >= _fileStream.Length & terminate == false) - throw new InvalidProgramException("Reach the end of the filestream without trailer block."); - } while (!terminate); - - ArrayPool.Shared.Return(tempBuf); - } - - /// - /// Parses GIF Image Descriptor Block. - /// - private void ProcessImageDescriptor(ref int curFrame, byte[] tempBuf) - { - var str = _fileStream; - var currentFrame = Frames[curFrame]; - - // Parse frame dimensions. - var frameX = str.ReadUShortS(tempBuf); - var frameY = str.ReadUShortS(tempBuf); - var frameW = str.ReadUShortS(tempBuf); - var frameH = str.ReadUShortS(tempBuf); - - frameW = (ushort)Math.Min(frameW, _gifDimensions.Width - frameX); - frameH = (ushort)Math.Min(frameH, _gifDimensions.Height - frameY); - - currentFrame.Dimensions = new GifRect(frameX, frameY, frameW, frameH); - - // Unpack interlace and lct info. - var packed = str.ReadByteS(tempBuf); - currentFrame.IsInterlaced = (packed & 0x40) != 0; - currentFrame.IsLocalColorTableUsed = (packed & 0x80) != 0; - currentFrame.LocalColorTableSize = (int)Math.Pow(2, (packed & 0x07) + 1); - - if (currentFrame.IsLocalColorTableUsed) - currentFrame.LocalColorTable = - ProcessColorTable(ref str, tempBuf, currentFrame.LocalColorTableSize); - - currentFrame.LzwMinCodeSize = str.ReadByteS(tempBuf); - currentFrame.LzwStreamPosition = str.Position; - - curFrame += 1; - Frames.Add(new GifFrame()); - } - - /// - /// Parses GIF Extension Blocks. - /// - private void ProcessExtensions(ref int curFrame, byte[] tempBuf) - { - var extType = (ExtensionType)_fileStream.ReadByteS(tempBuf); - - switch (extType) - { - case ExtensionType.GraphicsControl: - - _fileStream.ReadBlock(tempBuf); - var currentFrame = Frames[curFrame]; - var packed = tempBuf[0]; - - currentFrame.FrameDisposalMethod = (FrameDisposal)((packed & 0x1c) >> 2); - - if (currentFrame.FrameDisposalMethod != FrameDisposal.Restore - && currentFrame.FrameDisposalMethod != FrameDisposal.Background) - currentFrame.ShouldBackup = true; - - currentFrame.HasTransparency = (packed & 1) != 0; - - currentFrame.FrameDelay = - TimeSpan.FromMilliseconds(SpanToShort(tempBuf.AsSpan(1)) * 10); - - if (currentFrame.FrameDelay <= FrameDelayThreshold) - currentFrame.FrameDelay = FrameDelayDefault; - - currentFrame.TransparentColorIndex = tempBuf[3]; - break; - - case ExtensionType.Application: - var blockLen = _fileStream.ReadBlock(tempBuf); - var _ = tempBuf.AsSpan(0, blockLen); - var blockHeader = tempBuf.AsSpan(0, NetscapeMagic.Length); - - if (blockHeader.SequenceEqual(NetscapeMagic.Span)) - { - var count = 1; - - while (count > 0) - count = _fileStream.ReadBlock(tempBuf); - - var iterationCount = SpanToShort(tempBuf.AsSpan(1)); - - Header.Iterations = iterationCount; - } - else - _fileStream.SkipBlocks(tempBuf); - - break; - - default: - _fileStream.SkipBlocks(tempBuf); - break; - } - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/GifFrame.cs b/src/Avalonia.Gif/Decoding/GifFrame.cs deleted file mode 100644 index e15a201..0000000 --- a/src/Avalonia.Gif/Decoding/GifFrame.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Avalonia.Gif.Decoding -{ - public class GifFrame - { - public bool HasTransparency, IsInterlaced, IsLocalColorTableUsed; - public byte TransparentColorIndex; - public int LzwMinCodeSize, LocalColorTableSize; - public long LzwStreamPosition; - public TimeSpan FrameDelay; - public FrameDisposal FrameDisposalMethod; - public bool ShouldBackup; - public GifRect Dimensions; - public GifColor[] LocalColorTable; - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/GifHeader.cs b/src/Avalonia.Gif/Decoding/GifHeader.cs deleted file mode 100644 index d02dbc9..0000000 --- a/src/Avalonia.Gif/Decoding/GifHeader.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed under the MIT License. -// Copyright (C) 2018 Jumar A. Macato, All Rights Reserved. - -namespace Avalonia.Gif.Decoding -{ - public class GifHeader - { - public bool HasGlobalColorTable; - public int GlobalColorTableSize; - public ulong GlobalColorTableCacheId; - public int BackgroundColorIndex; - public long HeaderSize; - internal int Iterations = -1; - public GifRepeatBehavior IterationCount; - public GifRect Dimensions; - private GifColor[] _globarColorTable; - public GifColor[] GlobarColorTable; - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/GifRect.cs b/src/Avalonia.Gif/Decoding/GifRect.cs deleted file mode 100644 index 0ed9308..0000000 --- a/src/Avalonia.Gif/Decoding/GifRect.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Avalonia.Gif.Decoding -{ - public readonly struct GifRect - { - public int X { get; } - public int Y { get; } - public int Width { get; } - public int Height { get; } - public int TotalPixels { get; } - - public GifRect(int x, int y, int width, int height) - { - X = x; - Y = y; - Width = width; - Height = height; - TotalPixels = width * height; - } - - public static bool operator ==(GifRect a, GifRect b) - { - return a.X == b.X && - a.Y == b.Y && - a.Width == b.Width && - a.Height == b.Height; - } - public static bool operator !=(GifRect a, GifRect b) - { - return !(a == b); - } - - public override bool Equals(object obj) - { - if (obj == null || GetType() != obj.GetType()) - return false; - - return this == (GifRect)obj; - } - - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() | Width.GetHashCode() ^ Height.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/GifRepeatBehavior.cs b/src/Avalonia.Gif/Decoding/GifRepeatBehavior.cs deleted file mode 100644 index 4b27a7b..0000000 --- a/src/Avalonia.Gif/Decoding/GifRepeatBehavior.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Avalonia.Gif.Decoding -{ - public class GifRepeatBehavior - { - public bool LoopForever { get; set; } - public int? Count { get; set; } - } -} diff --git a/src/Avalonia.Gif/Decoding/InvalidGifStreamException.cs b/src/Avalonia.Gif/Decoding/InvalidGifStreamException.cs deleted file mode 100644 index 73c3124..0000000 --- a/src/Avalonia.Gif/Decoding/InvalidGifStreamException.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed under the MIT License. -// Copyright (C) 2018 Jumar A. Macato, All Rights Reserved. - -using System; -using System.Runtime.Serialization; - -namespace Avalonia.Gif.Decoding -{ - [Serializable] - public class InvalidGifStreamException : Exception - { - public InvalidGifStreamException() - { - } - - public InvalidGifStreamException(string message) : base(message) - { - } - - public InvalidGifStreamException(string message, Exception innerException) : base(message, innerException) - { - } - - protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Decoding/LzwDecompressionException.cs b/src/Avalonia.Gif/Decoding/LzwDecompressionException.cs deleted file mode 100644 index 2e74aaf..0000000 --- a/src/Avalonia.Gif/Decoding/LzwDecompressionException.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed under the MIT License. -// Copyright (C) 2018 Jumar A. Macato, All Rights Reserved. - -using System; -using System.Runtime.Serialization; - -namespace Avalonia.Gif.Decoding -{ - [Serializable] - public class LzwDecompressionException : Exception - { - public LzwDecompressionException() - { - } - - public LzwDecompressionException(string message) : base(message) - { - } - - public LzwDecompressionException(string message, Exception innerException) : base(message, innerException) - { - } - - protected LzwDecompressionException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/Extensions/StreamExtensions.cs b/src/Avalonia.Gif/Extensions/StreamExtensions.cs deleted file mode 100644 index d05bc63..0000000 --- a/src/Avalonia.Gif/Extensions/StreamExtensions.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; - -namespace Avalonia.Gif.Extensions -{ - [DebuggerStepThrough] - internal static class StreamExtensions - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort SpanToShort(Span b) => (ushort)(b[0] | (b[1] << 8)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Skip(this Stream stream, long count) - { - stream.Position += count; - } - - /// - /// Read a Gif block from stream while advancing the position. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ReadBlock(this Stream stream, byte[] tempBuf) - { - stream.Read(tempBuf, 0, 1); - - var blockLength = (int)tempBuf[0]; - - if (blockLength > 0) - stream.Read(tempBuf, 0, blockLength); - - // Guard against infinite loop. - if (stream.Position >= stream.Length) - throw new InvalidGifStreamException("Reach the end of the filestream without trailer block."); - - return blockLength; - } - - /// - /// Skips GIF blocks until it encounters an empty block. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SkipBlocks(this Stream stream, byte[] tempBuf) - { - int blockLength; - do - { - stream.Read(tempBuf, 0, 1); - - blockLength = tempBuf[0]; - stream.Position += blockLength; - - // Guard against infinite loop. - if (stream.Position >= stream.Length) - throw new InvalidGifStreamException("Reach the end of the filestream without trailer block."); - - } while (blockLength > 0); - } - - /// - /// Read a from stream by providing a temporary buffer. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort ReadUShortS(this Stream stream, byte[] tempBuf) - { - stream.Read(tempBuf, 0, 2); - return SpanToShort(tempBuf); - } - - /// - /// Read a from stream by providing a temporary buffer. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte ReadByteS(this Stream stream, byte[] tempBuf) - { - stream.Read(tempBuf, 0, 1); - var finalVal = tempBuf[0]; - return finalVal; - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/GifImage.cs b/src/Avalonia.Gif/GifImage.cs deleted file mode 100644 index 26c96a9..0000000 --- a/src/Avalonia.Gif/GifImage.cs +++ /dev/null @@ -1,276 +0,0 @@ -using Avalonia.Animation; -using Avalonia.Controls; -using Avalonia.Logging; -using Avalonia.Media; -using Avalonia.Rendering.Composition; -using Avalonia.VisualTree; -using System; -using System.IO; -using System.Numerics; - -namespace Avalonia.Gif -{ - public class GifImage : Control - { - public static readonly StyledProperty SourceUriRawProperty = - AvaloniaProperty.Register("SourceUriRaw"); - - public static readonly StyledProperty SourceUriProperty = - AvaloniaProperty.Register("SourceUri"); - - public static readonly StyledProperty SourceStreamProperty = - AvaloniaProperty.Register("SourceStream"); - - public static readonly StyledProperty IterationCountProperty = - AvaloniaProperty.Register("IterationCount", IterationCount.Infinite); - - private GifInstance? _gifInstance; - - public static readonly StyledProperty StretchDirectionProperty = - AvaloniaProperty.Register("StretchDirection"); - - public static readonly StyledProperty StretchProperty = - AvaloniaProperty.Register("Stretch"); - - private CompositionCustomVisual? _customVisual; - - private object? _initialSource = null; - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - switch (change.Property.Name) - { - case nameof(SourceUriRaw): - case nameof(SourceUri): - case nameof(SourceStream): - SourceChanged(change); - break; - case nameof(Stretch): - case nameof(StretchDirection): - InvalidateArrange(); - InvalidateMeasure(); - Update(); - break; - case nameof(IterationCount): - IterationCountChanged(change); - break; - case nameof(Bounds): - Update(); - break; - } - - base.OnPropertyChanged(change); - } - - public string SourceUriRaw - { - get => GetValue(SourceUriRawProperty); - set => SetValue(SourceUriRawProperty, value); - } - - public Uri SourceUri - { - get => GetValue(SourceUriProperty); - set => SetValue(SourceUriProperty, value); - } - - public Stream SourceStream - { - get => GetValue(SourceStreamProperty); - set => SetValue(SourceStreamProperty, value); - } - - public IterationCount IterationCount - { - get => GetValue(IterationCountProperty); - set => SetValue(IterationCountProperty, value); - } - - public StretchDirection StretchDirection - { - get => GetValue(StretchDirectionProperty); - set => SetValue(StretchDirectionProperty, value); - } - - public Stretch Stretch - { - get => GetValue(StretchProperty); - set => SetValue(StretchProperty, value); - } - - private static void IterationCountChanged(AvaloniaPropertyChangedEventArgs e) - { - var image = e.Sender as GifImage; - if (image is null || e.NewValue is not IterationCount iterationCount) - return; - - image.IterationCount = iterationCount; - } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - var compositor = ElementComposition.GetElementVisual(this)?.Compositor; - if (compositor == null || _customVisual?.Compositor == compositor) - return; - _customVisual = compositor.CreateCustomVisual(new CustomVisualHandler()); - ElementComposition.SetElementChildVisual(this, _customVisual); - _customVisual.SendHandlerMessage(CustomVisualHandler.StartMessage); - - if (_initialSource is not null) - { - UpdateGifInstance(_initialSource); - _initialSource = null; - } - - Update(); - base.OnAttachedToVisualTree(e); - } - - - private void Update() - { - if (_customVisual is null || _gifInstance is null) - return; - - var dpi = this.GetVisualRoot()?.RenderScaling ?? 1.0; - var sourceSize = _gifInstance.GifPixelSize.ToSize(dpi); - var viewPort = new Rect(Bounds.Size); - - var scale = Stretch.CalculateScaling(Bounds.Size, sourceSize, StretchDirection); - var scaledSize = sourceSize * scale; - var destRect = viewPort - .CenterRect(new Rect(scaledSize)) - .Intersect(viewPort); - - if (Stretch == Stretch.None) - { - _customVisual.Size = new Vector2((float)sourceSize.Width, (float)sourceSize.Height); - } - else - { - _customVisual.Size = new Vector2((float)destRect.Size.Width, (float)destRect.Size.Height); - } - - _customVisual.Offset = new Vector3((float)destRect.Position.X, (float)destRect.Position.Y, 0); - } - - private class CustomVisualHandler : CompositionCustomVisualHandler - { - private TimeSpan _animationElapsed; - private TimeSpan? _lastServerTime; - private GifInstance? _currentInstance; - private bool _running; - - public static readonly object StopMessage = new(), StartMessage = new(); - - public override void OnMessage(object message) - { - if (message == StartMessage) - { - _running = true; - _lastServerTime = null; - RegisterForNextAnimationFrameUpdate(); - } - else if (message == StopMessage) - { - _running = false; - } - else if (message is GifInstance instance) - { - _currentInstance?.Dispose(); - _currentInstance = instance; - } - } - - public override void OnAnimationFrameUpdate() - { - if (!_running) return; - Invalidate(); - RegisterForNextAnimationFrameUpdate(); - } - - public override void OnRender(ImmediateDrawingContext drawingContext) - { - if (_running) - { - if (_lastServerTime.HasValue) _animationElapsed += (CompositionNow - _lastServerTime.Value); - _lastServerTime = CompositionNow; - } - - try - { - if (_currentInstance is null || _currentInstance.IsDisposed) return; - - var bitmap = _currentInstance.ProcessFrameTime(_animationElapsed); - if (bitmap is not null) - { - drawingContext.DrawBitmap(bitmap, new Rect(_currentInstance.GifPixelSize.ToSize(1)), - GetRenderBounds()); - } - } - catch (Exception e) - { - Logger.Sink?.Log(LogEventLevel.Error, "GifImage Renderer ", this, e.ToString()); - - } - } - } - - /// - /// Measures the control. - /// - /// The available size. - /// The desired size of the control. - protected override Size MeasureOverride(Size availableSize) - { - var result = new Size(); - var scaling = this.GetVisualRoot()?.RenderScaling ?? 1.0; - if (_gifInstance != null) - { - result = Stretch.CalculateSize(availableSize, _gifInstance.GifPixelSize.ToSize(scaling), - StretchDirection); - } - - return result; - } - - /// - protected override Size ArrangeOverride(Size finalSize) - { - if (_gifInstance is null) return new Size(); - var scaling = this.GetVisualRoot()?.RenderScaling ?? 1.0; - var sourceSize = _gifInstance.GifPixelSize.ToSize(scaling); - var result = Stretch.CalculateSize(finalSize, sourceSize); - return result; - } - - - private void SourceChanged(AvaloniaPropertyChangedEventArgs e) - { - if (e.NewValue is null || (e.NewValue is string value && !Uri.IsWellFormedUriString(value, UriKind.Absolute))) - { - return; - } - - if (_customVisual is null) - { - _initialSource = e.NewValue; - return; - } - - UpdateGifInstance(e.NewValue); - - InvalidateArrange(); - InvalidateMeasure(); - Update(); - } - - private void UpdateGifInstance(object source) - { - _gifInstance?.Dispose(); - _gifInstance = new GifInstance(source); - _gifInstance.IterationCount = IterationCount; - _customVisual?.SendHandlerMessage(_gifInstance); - } - } -} diff --git a/src/Avalonia.Gif/GifInstance.cs b/src/Avalonia.Gif/GifInstance.cs deleted file mode 100644 index c582453..0000000 --- a/src/Avalonia.Gif/GifInstance.cs +++ /dev/null @@ -1,140 +0,0 @@ -using Avalonia.Animation; -using Avalonia.Gif.Decoding; -using Avalonia.Media.Imaging; -using Avalonia.Platform; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; - -namespace Avalonia.Gif -{ - public class GifInstance : IDisposable - { - public IterationCount IterationCount { get; set; } - public bool AutoStart { get; private set; } = true; - private readonly GifDecoder _gifDecoder; - private readonly WriteableBitmap? _targetBitmap; - private TimeSpan _totalTime; - private readonly List _frameTimes; - private uint _iterationCount; - private int _currentFrameIndex; - private readonly List _colorTableIdList; - - public CancellationTokenSource CurrentCts { get; } - - internal GifInstance(object newValue) : this(newValue switch - { - Stream s => s, - Uri u => GetStreamFromUri(u), - string str => GetStreamFromString(str), - _ => throw new InvalidDataException("Unsupported source object") - }) - { } - - public GifInstance(string uri) : this(GetStreamFromString(uri)) - { } - - public GifInstance(Uri uri) : this(GetStreamFromUri(uri)) - { } - - public GifInstance(Stream currentStream) - { - if (!currentStream.CanSeek) - throw new InvalidDataException("The provided stream is not seekable."); - - if (!currentStream.CanRead) - throw new InvalidOperationException("Can't read the stream provided."); - - currentStream.Seek(0, SeekOrigin.Begin); - - CurrentCts = new CancellationTokenSource(); - - _gifDecoder = new GifDecoder(currentStream, CurrentCts.Token); - var pixSize = new PixelSize(_gifDecoder.Header.Dimensions.Width, _gifDecoder.Header.Dimensions.Height); - - _targetBitmap = new WriteableBitmap(pixSize, new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Opaque); - GifPixelSize = pixSize; - - _totalTime = TimeSpan.Zero; - - _frameTimes = _gifDecoder.Frames.Select(frame => - { - _totalTime = _totalTime.Add(frame.FrameDelay); - return _totalTime; - }).ToList(); - - _gifDecoder.RenderFrame(0, _targetBitmap); - } - - private static Stream GetStreamFromString(string str) - { - if (!Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out var res)) - { - throw new InvalidCastException("The string provided can't be converted to URI."); - } - - return GetStreamFromUri(res); - } - - private static Stream GetStreamFromUri(Uri uri) - { - var uriString = uri.OriginalString.Trim(); - - if (!uriString.StartsWith("resm") && !uriString.StartsWith("avares")) - throw new InvalidDataException( - "The URI provided is not currently supported."); - - return AssetLoader.Open(uri); - } - - public int GifFrameCount => _frameTimes.Count; - - public PixelSize GifPixelSize { get; } - - public void Dispose() - { - IsDisposed = true; - CurrentCts.Cancel(); - _targetBitmap?.Dispose(); - } - - public bool IsDisposed { get; private set; } - - - public WriteableBitmap? ProcessFrameTime(TimeSpan stopwatchElapsed) - { - if (!IterationCount.IsInfinite && _iterationCount > IterationCount.Value) - { - return null; - } - - if (CurrentCts.IsCancellationRequested || _targetBitmap is null) - { - return null; - } - - var elapsedTicks = stopwatchElapsed.Ticks; - var timeModulus = TimeSpan.FromTicks(elapsedTicks % _totalTime.Ticks); - var targetFrame = _frameTimes.FirstOrDefault(x => timeModulus < x); - var currentFrame = _frameTimes.IndexOf(targetFrame); - if (currentFrame == -1) currentFrame = 0; - - if (_currentFrameIndex == currentFrame) - return _targetBitmap; - - _iterationCount = (uint)(elapsedTicks / _totalTime.Ticks); - - return ProcessFrameIndex(currentFrame); - } - - internal WriteableBitmap ProcessFrameIndex(int frameIndex) - { - _gifDecoder.RenderFrame(frameIndex, _targetBitmap); - _currentFrameIndex = frameIndex; - - return _targetBitmap; - } - } -} \ No newline at end of file diff --git a/src/Avalonia.Gif/InvalidGifStreamException.cs b/src/Avalonia.Gif/InvalidGifStreamException.cs deleted file mode 100644 index dc10557..0000000 --- a/src/Avalonia.Gif/InvalidGifStreamException.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace Avalonia.Gif -{ - [Serializable] - internal class InvalidGifStreamException : Exception - { - public InvalidGifStreamException() - { - } - - public InvalidGifStreamException(string message) : base(message) - { - } - - public InvalidGifStreamException(string message, Exception innerException) : base(message, innerException) - { - } - - protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/Login/TestLoginInfo.cs b/src/BiliSharp.UnitTest/Api/Login/TestLoginInfo.cs deleted file mode 100644 index 84c50d0..0000000 --- a/src/BiliSharp.UnitTest/Api/Login/TestLoginInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using BiliSharp.Api.Login; - -namespace BiliSharp.UnitTest.Api.Login; - -public class TestLoginInfo -{ - [Fact] - public void TestGetNavigationInfo_Default() - { - Cookies.GetMyCookies(); - - long mid = 42018135; - var info = LoginInfo.GetNavigationInfo(); - Assert.Equal(mid, info.Data.Mid); - } - - [Fact] - public void TestGetLoginInfoStat_Default() - { - Cookies.GetMyCookies(); - - var stat = LoginInfo.GetLoginInfoStat(); - Assert.NotNull(stat); - } - - [Fact] - public void TestGetMyCoin_Default() - { - Cookies.GetMyCookies(); - - var coin = LoginInfo.GetMyCoin(); - Assert.NotNull(coin); - } - -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/Login/TestLoginNotice.cs b/src/BiliSharp.UnitTest/Api/Login/TestLoginNotice.cs deleted file mode 100644 index 1130ec4..0000000 --- a/src/BiliSharp.UnitTest/Api/Login/TestLoginNotice.cs +++ /dev/null @@ -1,16 +0,0 @@ -using BiliSharp.Api.Login; - -namespace BiliSharp.UnitTest.Api.Login; - -public class TestLoginNotice -{ - [Fact] - public void TestGetLoginNotice_Default() - { - Cookies.GetMyCookies(); - - long mid = 42018135; - var notice = LoginNotice.GetLoginNotice(mid); - Assert.Equal(mid, notice.Data.Mid); - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/Login/TestLoginQR.cs b/src/BiliSharp.UnitTest/Api/Login/TestLoginQR.cs deleted file mode 100644 index 4c21328..0000000 --- a/src/BiliSharp.UnitTest/Api/Login/TestLoginQR.cs +++ /dev/null @@ -1,23 +0,0 @@ -using BiliSharp.Api.Login; - -namespace BiliSharp.UnitTest.Api.Login; - -public class TestLoginQR -{ - [Fact] - public void TestGenerateQRCode_Default() - { - var qrcode = LoginQR.GenerateQRCode(); - Assert.NotNull(qrcode.Data); - } - - [Fact] - public void TestPollQRCode_Default() - { - var qrcode = LoginQR.GenerateQRCode(); - Assert.NotNull(qrcode.Data); - - var poll = LoginQR.PollQRCode(qrcode.Data.QrcodeKey); - Assert.NotNull(poll.Data); - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/Sign/TestWbiSign.cs b/src/BiliSharp.UnitTest/Api/Sign/TestWbiSign.cs deleted file mode 100644 index 93231b8..0000000 --- a/src/BiliSharp.UnitTest/Api/Sign/TestWbiSign.cs +++ /dev/null @@ -1,87 +0,0 @@ -using BiliSharp.Api.Sign; - -namespace BiliSharp.UnitTest.Api.Sign -{ - public class TestWbiSign - { - [Fact] - public void TestParametersToQuery_Default() - { - var parameters = new Dictionary - { - { "fourk", 1 }, - { "fnver", 0 }, - { "fnval", 4048 }, - { "cid", 405595939 }, - { "qn", 120 }, - { "bvid", "BV1Sg411F7cb" }, - { "aid", 505421421 } - }; - string expected = "fourk=1&fnver=0&fnval=4048&cid=405595939&qn=120&bvid=BV1Sg411F7cb&aid=505421421"; - - string query = WbiSign.ParametersToQuery(parameters); - Assert.Equal(expected, query); - } - - [Fact] - public void TestParametersToQuery_Empty() - { - var parameters = new Dictionary(); - string query = WbiSign.ParametersToQuery(parameters); - Assert.Equal("", query); - } - - [Fact] - public void TestKeys_Default() - { - var key1 = WbiSign.GetKey(); - Assert.NotNull(key1); - - string imgKey = "34478ba821254d9d93542680e3b86100"; - string subKey = "7e16a90d190a4355a78fd00b32a38de6"; - var keys = new Tuple(imgKey, subKey); - WbiSign.SetKey(keys); - - var key2 = WbiSign.GetKey(); - Assert.Equal(imgKey, key2.Item1); - Assert.Equal(subKey, key2.Item2); - } - - [Fact] - public void TestEncodeWbi_Default() - { - var parameters = new Dictionary - { - { "fourk", 1 }, - { "fnver", 0 }, - { "fnval", 4048 }, - { "cid", 405595939 }, - { "qn", 120 }, - { "bvid", "BV1Sg411F7cb" }, - { "aid", 505421421 } - }; - - var wbi = WbiSign.EncodeWbi(parameters); - Assert.NotNull(wbi["w_rid"]); - } - - [Fact] - public void TestEncodeWbi_Default2() - { - var parameters = new Dictionary - { - { "fourk", 1 }, - { "fnver", 0 }, - { "fnval", 4048 }, - { "cid", 405595939 }, - { "qn", 120 }, - { "bvid", "BV1Sg411F7cb" }, - { "aid", 505421421 } - }; - - var wbi = WbiSign.EncodeWbi(parameters, "653657f524a547ac981ded72ea172057", "6e4909c702f846728e64f6007736a338"); - Assert.NotNull(wbi["w_rid"]); - } - - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/User/TestNickname.cs b/src/BiliSharp.UnitTest/Api/User/TestNickname.cs deleted file mode 100644 index 9712b06..0000000 --- a/src/BiliSharp.UnitTest/Api/User/TestNickname.cs +++ /dev/null @@ -1,25 +0,0 @@ -using BiliSharp.Api.User; - -namespace BiliSharp.UnitTest.Api.User -{ - public class TestNickname - { - [Fact] - public void TestCheckNickname_Default() - { - Equal("downkyi", 0); - Equal("maozedong", 40002); - Equal("//", 40004); - Equal("test0000000000000", 40005); - Equal("0", 40006); - Equal("test", 40014); - } - - private static void Equal(string nickname, int code) - { - var response = Nickname.CheckNickname(nickname); - Assert.Equal(code, response.Code); - } - - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/User/TestUserInfo.cs b/src/BiliSharp.UnitTest/Api/User/TestUserInfo.cs deleted file mode 100644 index 5b65f53..0000000 --- a/src/BiliSharp.UnitTest/Api/User/TestUserInfo.cs +++ /dev/null @@ -1,70 +0,0 @@ -using BiliSharp.Api.Login; -using BiliSharp.Api.Sign; -using BiliSharp.Api.User; - -namespace BiliSharp.UnitTest.Api.User -{ - public class TestUserInfo - { - [Fact] - public void TestGetUserInfo_Default() - { - Cookies.GetMyCookies(); - - // 设置wbi keys - var info = LoginInfo.GetNavigationInfo(); - var imgKey = info.Data.WbiImg.ImgUrl.Split('/').ToList().Last().Split('.')[0]; - var subKey = info.Data.WbiImg.SubUrl.Split('/').ToList().Last().Split('.')[0]; - var keys = new Tuple(imgKey, subKey); - WbiSign.SetKey(keys); - - long mid = 42018135; - var userInfo = UserInfo.GetUserInfo(mid); - - Assert.Equal(mid, userInfo.Data.Mid); - } - - [Fact] - public void TestGetUserCard_Default() - { - Cookies.GetMyCookies(); - - long mid = 42018135; - var userCard = UserInfo.GetUserCard(mid); - - Assert.Equal(mid.ToString(), userCard.Data.Card.Mid); - } - - [Fact] - public void TestGetMyInfo_Default() - { - Cookies.GetMyCookies(); - - long mid = 42018135; - var myInfo = UserInfo.GetMyInfo(); - - Assert.Equal(mid, myInfo.Data.Mid); - } - - [Fact] - public void TestGetUserCards_Default() - { - Cookies.GetMyCookies(); - - // https://api.vc.bilibili.com/account/v1/user/cards?uids=314521322,206840230,49246269 - List ids = new() - { - 314521322, - 206840230, - 49246269 - }; - var users = UserInfo.GetUserCards(ids); - - foreach (var user in users.Data) - { - Assert.Contains(user.Mid, ids); - } - } - - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/Api/Video/TestVideoInfo.cs b/src/BiliSharp.UnitTest/Api/Video/TestVideoInfo.cs deleted file mode 100644 index 2ff7549..0000000 --- a/src/BiliSharp.UnitTest/Api/Video/TestVideoInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using BiliSharp.Api.Login; -using BiliSharp.Api.Sign; -using BiliSharp.Api.Video; - -namespace BiliSharp.UnitTest.Api.Video -{ - public class TestVideoInfo - { - [Fact] - public void TestGetVideoViewInfo_Default() - { - // 设置wbi keys - var info = LoginInfo.GetNavigationInfo(); - var imgKey = info.Data.WbiImg.ImgUrl.Split('/').ToList().Last().Split('.')[0]; - var subKey = info.Data.WbiImg.SubUrl.Split('/').ToList().Last().Split('.')[0]; - var keys = new Tuple(imgKey, subKey); - WbiSign.SetKey(keys); - - string bvid = "BV1Pu4y1y7FA"; - long aid = 915570400; - var videoInfo = VideoInfo.GetVideoViewInfo(bvid, aid); - - Assert.Equal(bvid, videoInfo.Data.View.Bvid); - Assert.Equal(aid, videoInfo.Data.View.Aid); - } - - } -} \ No newline at end of file diff --git a/src/BiliSharp.UnitTest/BiliSharp.UnitTest.csproj b/src/BiliSharp.UnitTest/BiliSharp.UnitTest.csproj deleted file mode 100644 index 93c83b6..0000000 --- a/src/BiliSharp.UnitTest/BiliSharp.UnitTest.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net7.0 - enable - enable - - false - true - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - diff --git a/src/BiliSharp.UnitTest/Cookies.cs b/src/BiliSharp.UnitTest/Cookies.cs deleted file mode 100644 index f437dda..0000000 --- a/src/BiliSharp.UnitTest/Cookies.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Net; - -namespace BiliSharp.UnitTest; - -public static class Cookies -{ - /// - /// 解析从浏览器获取的cookies,用于设置cookie - /// - /// - /// - public static CookieContainer ParseCookieByString(string str) - { - var cookieContainer = new CookieContainer(); - - var cookies = str.Replace(" ", "").Split(";"); - foreach (var cookie in cookies) - { - DateTime dateTime = DateTime.Now; - dateTime = dateTime.AddMonths(12); - - var temp = cookie.Split("="); - var name = temp[0]; - var value = temp[1]; - - // 添加cookie - cookieContainer.Add(new Cookie(name, value, "/", ".bilibili.com") { Expires = dateTime }); - } - return cookieContainer; - } - - public static void GetMyCookies() - { - string cookiesStr = "DedeUserID=42018135; " + - "DedeUserID__ckMd5=44e22fa30fe34ac4; " + - "SESSDATA=32c16297%2C1700815953%2Cb11cd%2A51; " + - "bili_jct=98dbd091dc07d8f9b69ba3845974e7c8; " + - "sid=6vomjg3u"; - var cookies = ParseCookieByString(cookiesStr); - BiliManager.Instance().SetCookies(cookies); - } - -} diff --git a/src/BiliSharp.UnitTest/Usings.cs b/src/BiliSharp.UnitTest/Usings.cs deleted file mode 100644 index 8c927eb..0000000 --- a/src/BiliSharp.UnitTest/Usings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; \ No newline at end of file diff --git a/src/BiliSharp/Api/Login/LoginInfo.cs b/src/BiliSharp/Api/Login/LoginInfo.cs deleted file mode 100644 index 6f204c2..0000000 --- a/src/BiliSharp/Api/Login/LoginInfo.cs +++ /dev/null @@ -1,40 +0,0 @@ -using BiliSharp.Api.Models.Login; - -namespace BiliSharp.Api.Login -{ - /// - /// 登录基本信息 - /// - public static class LoginInfo - { - /// - /// 导航栏用户信息 - /// - /// - public static NavigationLoginInfo GetNavigationInfo() - { - string url = "https://api.bilibili.com/x/web-interface/nav"; - return Utils.GetData(url); - } - - /// - /// 登录用户状态数(双端) - /// - /// - public static LoginInfoStat GetLoginInfoStat() - { - string url = "https://api.bilibili.com/x/web-interface/nav/stat"; - return Utils.GetData(url); - } - - /// - /// 获取硬币数 - /// - /// - public static MyCoin GetMyCoin() - { - string url = "https://account.bilibili.com/site/getCoin"; - return Utils.GetData(url); - } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Login/LoginNotice.cs b/src/BiliSharp/Api/Login/LoginNotice.cs deleted file mode 100644 index c896248..0000000 --- a/src/BiliSharp/Api/Login/LoginNotice.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace BiliSharp.Api.Login -{ - /// - /// 登录记录 - /// - public static class LoginNotice - { - /// - /// 查询登录记录 - /// - /// - public static Models.Login.LoginNotice GetLoginNotice(long mid) - { - string url = $"https://api.bilibili.com/x/safecenter/login_notice?mid={mid}"; - return Utils.GetData(url); - } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Login/LoginQR.cs b/src/BiliSharp/Api/Login/LoginQR.cs deleted file mode 100644 index e5fc29b..0000000 --- a/src/BiliSharp/Api/Login/LoginQR.cs +++ /dev/null @@ -1,30 +0,0 @@ -using BiliSharp.Api.Models.Login; - -namespace BiliSharp.Api.Login -{ - /// - /// 二维码登录 - /// - public static class LoginQR - { - /// - /// 申请二维码(web端) - /// - /// - public static LoginQRCode GenerateQRCode() - { - string url = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate"; - return Utils.GetData(url); - } - - /// - /// 扫码登录(web端) - /// - /// - public static LoginQRCodePoll PollQRCode(string qrcodeKey) - { - string url = $"https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qrcodeKey}"; - return Utils.GetData(url); - } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Login/LoginInfoStat.cs b/src/BiliSharp/Api/Models/Login/LoginInfoStat.cs deleted file mode 100644 index eaa79cc..0000000 --- a/src/BiliSharp/Api/Models/Login/LoginInfoStat.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Login -{ - /// - /// https://api.bilibili.com/x/web-interface/nav/stat - /// - public class LoginInfoStat - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public LoginInfoStatData Data { get; set; } - } - - /// - /// - /// - public class LoginInfoStatData - { - /// - /// - /// - [JsonPropertyName("following")] - public int Following { get; set; } - - /// - /// - /// - [JsonPropertyName("follower")] - public int Follower { get; set; } - - /// - /// - /// - [JsonPropertyName("dynamic_count")] - public int DynamicCount { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Login/LoginNotice.cs b/src/BiliSharp/Api/Models/Login/LoginNotice.cs deleted file mode 100644 index 453c1bf..0000000 --- a/src/BiliSharp/Api/Models/Login/LoginNotice.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Login -{ - /// - /// https://api.bilibili.com/x/safecenter/login_notice?mid= - /// - public class LoginNotice - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public LoginNoticeData Data { get; set; } - } - - /// - /// - /// - public class LoginNoticeData - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("device_name")] - public string DeviceName { get; set; } - - /// - /// - /// - [JsonPropertyName("login_type")] - public string LoginType { get; set; } - - /// - /// - /// - [JsonPropertyName("login_time")] - public string LoginTime { get; set; } - - /// - /// - /// - [JsonPropertyName("location")] - public string Location { get; set; } - - /// - /// - /// - [JsonPropertyName("ip")] - public string Ip { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Login/LoginQRCode.cs b/src/BiliSharp/Api/Models/Login/LoginQRCode.cs deleted file mode 100644 index 40921fb..0000000 --- a/src/BiliSharp/Api/Models/Login/LoginQRCode.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Login -{ - /// - /// https://passport.bilibili.com/x/passport-login/web/qrcode/generate - /// - public class LoginQRCode - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public LoginQRCodeData Data { get; set; } - } - - /// - /// - /// - public class LoginQRCodeData - { - /// - /// - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// - /// - [JsonPropertyName("qrcode_key")] - public string QrcodeKey { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Login/LoginQRCodePoll.cs b/src/BiliSharp/Api/Models/Login/LoginQRCodePoll.cs deleted file mode 100644 index e183d69..0000000 --- a/src/BiliSharp/Api/Models/Login/LoginQRCodePoll.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Login -{ - /// - /// https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key= - /// - public class LoginQRCodePoll - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public LoginQRCodePollData Data { get; set; } - } - - /// - /// - /// - public class LoginQRCodePollData - { - /// - /// - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// - /// - [JsonPropertyName("refresh_token")] - public string RefreshToken { get; set; } - - /// - /// - /// - [JsonPropertyName("timestamp")] - public long Timestamp { get; set; } - - /// - /// - /// - [JsonPropertyName("code")] - public long Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Login/MyCoin.cs b/src/BiliSharp/Api/Models/Login/MyCoin.cs deleted file mode 100644 index b7a9d7a..0000000 --- a/src/BiliSharp/Api/Models/Login/MyCoin.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Login -{ - /// - /// https://account.bilibili.com/site/getCoin - /// - public class MyCoin - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public bool Status { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public MyCoinData Data { get; set; } - } - - /// - /// - /// - public class MyCoinData - { - /// - /// - /// - [JsonPropertyName("money")] - public int Money { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Login/NavigationLoginInfo.cs b/src/BiliSharp/Api/Models/Login/NavigationLoginInfo.cs deleted file mode 100644 index 6475320..0000000 --- a/src/BiliSharp/Api/Models/Login/NavigationLoginInfo.cs +++ /dev/null @@ -1,556 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Login -{ - /// - /// https://api.bilibili.com/x/web-interface/nav - /// - public class NavigationLoginInfo - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public NavigationLoginInfoData Data { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoData - { - /// - /// - /// - [JsonPropertyName("isLogin")] - public bool Islogin { get; set; } - - /// - /// - /// - [JsonPropertyName("email_verified")] - public int EmailVerified { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft")] - public int FaceNft { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft_type")] - public int FaceNftType { get; set; } - - /// - /// - /// - [JsonPropertyName("level_info")] - public NavigationLoginInfoDataLevelInfo LevelInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("mobile_verified")] - public int MobileVerified { get; set; } - - /// - /// - /// - [JsonPropertyName("money")] - public int Money { get; set; } - - /// - /// - /// - [JsonPropertyName("moral")] - public int Moral { get; set; } - - /// - /// - /// - [JsonPropertyName("official")] - public NavigationLoginInfoDataOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("officialVerify")] - public NavigationLoginInfoDataOfficialverify Officialverify { get; set; } - - /// - /// - /// - [JsonPropertyName("pendant")] - public NavigationLoginInfoDataPendant Pendant { get; set; } - - /// - /// - /// - [JsonPropertyName("scores")] - public int Scores { get; set; } - - /// - /// - /// - [JsonPropertyName("uname")] - public string Uname { get; set; } - - /// - /// - /// - [JsonPropertyName("vipDueDate")] - public long Vipduedate { get; set; } - - /// - /// - /// - [JsonPropertyName("vipStatus")] - public int Vipstatus { get; set; } - - /// - /// - /// - [JsonPropertyName("vipType")] - public int Viptype { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_theme_type")] - public int VipThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_label")] - public NavigationLoginInfoDataVipLabel VipLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_avatar_subscript")] - public int VipAvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_nickname_color")] - public string VipNicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public NavigationLoginInfoDataVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("wallet")] - public NavigationLoginInfoDataWallet Wallet { get; set; } - - /// - /// - /// - [JsonPropertyName("has_shop")] - public bool HasShop { get; set; } - - /// - /// - /// - [JsonPropertyName("shop_url")] - public string ShopUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("allowance_count")] - public int AllowanceCount { get; set; } - - /// - /// - /// - [JsonPropertyName("answer_status")] - public int AnswerStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("is_senior_member")] - public int IsSeniorMember { get; set; } - - /// - /// - /// - [JsonPropertyName("wbi_img")] - public NavigationLoginInfoDataWbiImg WbiImg { get; set; } - - /// - /// - /// - [JsonPropertyName("is_jury")] - public bool IsJury { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataLevelInfo - { - /// - /// - /// - [JsonPropertyName("current_level")] - public int CurrentLevel { get; set; } - - /// - /// - /// - [JsonPropertyName("current_min")] - public int CurrentMin { get; set; } - - /// - /// - /// - [JsonPropertyName("current_exp")] - public int CurrentExp { get; set; } - - /// - /// - /// - [JsonPropertyName("next_exp")] - public object NextExp { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataOfficialverify - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataPendant - { - /// - /// - /// - [JsonPropertyName("pid")] - public int Pid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("expire")] - public int Expire { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance")] - public string ImageEnhance { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance_frame")] - public string ImageEnhanceFrame { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public long DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public NavigationLoginInfoDataVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataWallet - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("bcoin_balance")] - public int BcoinBalance { get; set; } - - /// - /// - /// - [JsonPropertyName("coupon_balance")] - public int CouponBalance { get; set; } - - /// - /// - /// - [JsonPropertyName("coupon_due_time")] - public int CouponDueTime { get; set; } - } - - /// - /// - /// - public class NavigationLoginInfoDataWbiImg - { - /// - /// - /// - [JsonPropertyName("img_url")] - public string ImgUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("sub_url")] - public string SubUrl { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/User/MyInfo.cs b/src/BiliSharp/Api/Models/User/MyInfo.cs deleted file mode 100644 index cfb71cd..0000000 --- a/src/BiliSharp/Api/Models/User/MyInfo.cs +++ /dev/null @@ -1,652 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.User -{ - /// - /// https://api.bilibili.com/x/space/myinfo - /// - public class MyInfo - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public MyInfoData Data { get; set; } - } - - /// - /// - /// - public class MyInfoData - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("sex")] - public string Sex { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("sign")] - public string Sign { get; set; } - - /// - /// - /// - [JsonPropertyName("rank")] - public int Rank { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public int Level { get; set; } - - /// - /// - /// - [JsonPropertyName("jointime")] - public int Jointime { get; set; } - - /// - /// - /// - [JsonPropertyName("moral")] - public int Moral { get; set; } - - /// - /// - /// - [JsonPropertyName("silence")] - public int Silence { get; set; } - - /// - /// - /// - [JsonPropertyName("email_status")] - public int EmailStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tel_status")] - public int TelStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("identification")] - public int Identification { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public MyInfoDataVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("pendant")] - public MyInfoDataPendant Pendant { get; set; } - - /// - /// - /// - [JsonPropertyName("nameplate")] - public MyInfoDataNameplate Nameplate { get; set; } - - /// - /// - /// - [JsonPropertyName("official")] - public MyInfoDataOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("birthday")] - public long Birthday { get; set; } - - /// - /// - /// - [JsonPropertyName("is_tourist")] - public int IsTourist { get; set; } - - /// - /// - /// - [JsonPropertyName("is_fake_account")] - public int IsFakeAccount { get; set; } - - /// - /// - /// - [JsonPropertyName("pin_prompting")] - public int PinPrompting { get; set; } - - /// - /// - /// - [JsonPropertyName("is_deleted")] - public int IsDeleted { get; set; } - - /// - /// - /// - [JsonPropertyName("in_reg_audit")] - public int InRegAudit { get; set; } - - /// - /// - /// - [JsonPropertyName("is_rip_user")] - public bool IsRipUser { get; set; } - - /// - /// - /// - [JsonPropertyName("profession")] - public MyInfoDataProfession Profession { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft")] - public int FaceNft { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft_new")] - public int FaceNftNew { get; set; } - - /// - /// - /// - [JsonPropertyName("is_senior_member")] - public int IsSeniorMember { get; set; } - - /// - /// - /// - [JsonPropertyName("honours")] - public MyInfoDataHonours Honours { get; set; } - - /// - /// - /// - [JsonPropertyName("digital_id")] - public string DigitalId { get; set; } - - /// - /// - /// - [JsonPropertyName("digital_type")] - public int DigitalType { get; set; } - - /// - /// - /// - [JsonPropertyName("level_exp")] - public MyInfoDataLevelExp LevelExp { get; set; } - - /// - /// - /// - [JsonPropertyName("coins")] - public int Coins { get; set; } - - /// - /// - /// - [JsonPropertyName("following")] - public int Following { get; set; } - - /// - /// - /// - [JsonPropertyName("follower")] - public int Follower { get; set; } - } - - /// - /// - /// - public class MyInfoDataVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public long DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public MyInfoDataVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - } - - /// - /// - /// - public class MyInfoDataVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class MyInfoDataPendant - { - /// - /// - /// - [JsonPropertyName("pid")] - public int Pid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("expire")] - public int Expire { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance")] - public string ImageEnhance { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance_frame")] - public string ImageEnhanceFrame { get; set; } - } - - /// - /// - /// - public class MyInfoDataNameplate - { - /// - /// - /// - [JsonPropertyName("nid")] - public int Nid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("image_small")] - public string ImageSmall { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public string Level { get; set; } - - /// - /// - /// - [JsonPropertyName("condition")] - public string Condition { get; set; } - } - - /// - /// - /// - public class MyInfoDataOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class MyInfoDataProfession - { - /// - /// - /// - [JsonPropertyName("id")] - public int Id { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("show_name")] - public string ShowName { get; set; } - - /// - /// - /// - [JsonPropertyName("is_show")] - public int IsShow { get; set; } - - /// - /// - /// - [JsonPropertyName("category_one")] - public string CategoryOne { get; set; } - - /// - /// - /// - [JsonPropertyName("realname")] - public string Realname { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("department")] - public string Department { get; set; } - } - - /// - /// - /// - public class MyInfoDataHonours - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("colour")] - public MyInfoDataHonoursColour Colour { get; set; } - - /// - /// - /// - [JsonPropertyName("tags")] - public object Tags { get; set; } - } - - /// - /// - /// - public class MyInfoDataHonoursColour - { - /// - /// - /// - [JsonPropertyName("dark")] - public string Dark { get; set; } - - /// - /// - /// - [JsonPropertyName("normal")] - public string Normal { get; set; } - } - - /// - /// - /// - public class MyInfoDataLevelExp - { - /// - /// - /// - [JsonPropertyName("current_level")] - public int CurrentLevel { get; set; } - - /// - /// - /// - [JsonPropertyName("current_min")] - public int CurrentMin { get; set; } - - /// - /// - /// - [JsonPropertyName("current_exp")] - public int CurrentExp { get; set; } - - /// - /// - /// - [JsonPropertyName("next_exp")] - public int NextExp { get; set; } - - /// - /// - /// - [JsonPropertyName("level_up")] - public long LevelUp { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/User/Nickname.cs b/src/BiliSharp/Api/Models/User/Nickname.cs deleted file mode 100644 index 8c08569..0000000 --- a/src/BiliSharp/Api/Models/User/Nickname.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.User -{ - /// - /// https://passport.bilibili.com/web/generic/check/nickname?nickName=hahaha - /// - public class Nickname - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/User/UserCard.cs b/src/BiliSharp/Api/Models/User/UserCard.cs deleted file mode 100644 index 090b0c3..0000000 --- a/src/BiliSharp/Api/Models/User/UserCard.cs +++ /dev/null @@ -1,599 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.User -{ - /// - /// https://api.bilibili.com/x/web-interface/card?mid=314521322&photo=true - /// - public class UserCard - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public UserCardData Data { get; set; } - } - - /// - /// - /// - public class UserCardData - { - /// - /// - /// - [JsonPropertyName("card")] - public UserCardDataCard Card { get; set; } - - /// - /// - /// - [JsonPropertyName("space")] - public UserCardDataSpace Space { get; set; } - - /// - /// - /// - [JsonPropertyName("following")] - public bool Following { get; set; } - - /// - /// - /// - [JsonPropertyName("archive_count")] - public int ArchiveCount { get; set; } - - /// - /// - /// - [JsonPropertyName("article_count")] - public int ArticleCount { get; set; } - - /// - /// - /// - [JsonPropertyName("follower")] - public long Follower { get; set; } - - /// - /// - /// - [JsonPropertyName("like_num")] - public long LikeNum { get; set; } - } - - /// - /// - /// - public class UserCardDataCard - { - /// - /// - /// - [JsonPropertyName("mid")] - public string Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("approve")] - public bool Approve { get; set; } - - /// - /// - /// - [JsonPropertyName("sex")] - public string Sex { get; set; } - - /// - /// - /// - [JsonPropertyName("rank")] - public string Rank { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft")] - public int FaceNft { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft_type")] - public int FaceNftType { get; set; } - - /// - /// - /// - [JsonPropertyName("DisplayRank")] - public string Displayrank { get; set; } - - /// - /// - /// - [JsonPropertyName("regtime")] - public int Regtime { get; set; } - - /// - /// - /// - [JsonPropertyName("spacesta")] - public int Spacesta { get; set; } - - /// - /// - /// - [JsonPropertyName("birthday")] - public string Birthday { get; set; } - - /// - /// - /// - [JsonPropertyName("place")] - public string Place { get; set; } - - /// - /// - /// - [JsonPropertyName("description")] - public string Description { get; set; } - - /// - /// - /// - [JsonPropertyName("article")] - public int Article { get; set; } - - /// - /// - /// - [JsonPropertyName("attentions")] - public List Attentions { get; set; } - - /// - /// - /// - [JsonPropertyName("fans")] - public long Fans { get; set; } - - /// - /// - /// - [JsonPropertyName("friend")] - public int Friend { get; set; } - - /// - /// - /// - [JsonPropertyName("attention")] - public int Attention { get; set; } - - /// - /// - /// - [JsonPropertyName("sign")] - public string Sign { get; set; } - - /// - /// - /// - [JsonPropertyName("level_info")] - public UserCardDataCardLevelInfo LevelInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("pendant")] - public UserCardDataCardPendant Pendant { get; set; } - - /// - /// - /// - [JsonPropertyName("nameplate")] - public UserCardDataCardNameplate Nameplate { get; set; } - - /// - /// - /// - [JsonPropertyName("Official")] - public UserCardDataCardOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("official_verify")] - public UserCardDataCardOfficialVerify OfficialVerify { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public UserCardDataCardVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("is_senior_member")] - public int IsSeniorMember { get; set; } - } - - /// - /// - /// - public class UserCardDataCardLevelInfo - { - /// - /// - /// - [JsonPropertyName("current_level")] - public int CurrentLevel { get; set; } - - /// - /// - /// - [JsonPropertyName("current_min")] - public int CurrentMin { get; set; } - - /// - /// - /// - [JsonPropertyName("current_exp")] - public int CurrentExp { get; set; } - - /// - /// - /// - [JsonPropertyName("next_exp")] - public int NextExp { get; set; } - } - - /// - /// - /// - public class UserCardDataCardPendant - { - /// - /// - /// - [JsonPropertyName("pid")] - public int Pid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("expire")] - public int Expire { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance")] - public string ImageEnhance { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance_frame")] - public string ImageEnhanceFrame { get; set; } - } - - /// - /// - /// - public class UserCardDataCardNameplate - { - /// - /// - /// - [JsonPropertyName("nid")] - public int Nid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("image_small")] - public string ImageSmall { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public string Level { get; set; } - - /// - /// - /// - [JsonPropertyName("condition")] - public string Condition { get; set; } - } - - /// - /// - /// - public class UserCardDataCardOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class UserCardDataCardOfficialVerify - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - } - - /// - /// - /// - public class UserCardDataCardVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public long DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public UserCardDataCardVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("vipType")] - public int Viptype { get; set; } - - /// - /// - /// - [JsonPropertyName("vipStatus")] - public int Vipstatus { get; set; } - } - - /// - /// - /// - public class UserCardDataCardVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class UserCardDataSpace - { - /// - /// - /// - [JsonPropertyName("s_img")] - public string SImg { get; set; } - - /// - /// - /// - [JsonPropertyName("l_img")] - public string LImg { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/User/UserCards.cs b/src/BiliSharp/Api/Models/User/UserCards.cs deleted file mode 100644 index 2ce52fe..0000000 --- a/src/BiliSharp/Api/Models/User/UserCards.cs +++ /dev/null @@ -1,443 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.User -{ - /// - /// https://api.vc.bilibili.com/account/v1/user/cards?uids=314521322,206840230,49246269 - /// - public class UserCards - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("msg")] - public string Msg { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public List Data { get; set; } - } - - /// - /// - /// - public class UserCardsData - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("sex")] - public string Sex { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("sign")] - public string Sign { get; set; } - - /// - /// - /// - [JsonPropertyName("rank")] - public int Rank { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public int Level { get; set; } - - /// - /// - /// - [JsonPropertyName("silence")] - public int Silence { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public UserCardsDataVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("pendant")] - public UserCardsDataPendant Pendant { get; set; } - - /// - /// - /// - [JsonPropertyName("nameplate")] - public UserCardsDataNameplate Nameplate { get; set; } - - /// - /// - /// - [JsonPropertyName("official")] - public UserCardsDataOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("birthday")] - public long Birthday { get; set; } - - /// - /// - /// - [JsonPropertyName("is_fake_account")] - public int IsFakeAccount { get; set; } - - /// - /// - /// - [JsonPropertyName("is_deleted")] - public int IsDeleted { get; set; } - - /// - /// - /// - [JsonPropertyName("in_reg_audit")] - public int InRegAudit { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft")] - public int FaceNft { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft_new")] - public int FaceNftNew { get; set; } - - /// - /// - /// - [JsonPropertyName("is_senior_member")] - public int IsSeniorMember { get; set; } - - /// - /// - /// - [JsonPropertyName("digital_id")] - public string DigitalId { get; set; } - - /// - /// - /// - [JsonPropertyName("digital_type")] - public int DigitalType { get; set; } - } - - /// - /// - /// - public class UserCardsDataVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public long DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public UserCardsDataVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_due_date")] - public long TvDueDate { get; set; } - } - - /// - /// - /// - public class UserCardsDataVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class UserCardsDataPendant - { - /// - /// - /// - [JsonPropertyName("pid")] - public int Pid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("expire")] - public int Expire { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance")] - public string ImageEnhance { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance_frame")] - public string ImageEnhanceFrame { get; set; } - } - - /// - /// - /// - public class UserCardsDataNameplate - { - /// - /// - /// - [JsonPropertyName("nid")] - public int Nid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("image_small")] - public string ImageSmall { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public string Level { get; set; } - - /// - /// - /// - [JsonPropertyName("condition")] - public string Condition { get; set; } - } - - /// - /// - /// - public class UserCardsDataOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/User/UserSpaceInfo.cs b/src/BiliSharp/Api/Models/User/UserSpaceInfo.cs deleted file mode 100644 index 5c5ae1f..0000000 --- a/src/BiliSharp/Api/Models/User/UserSpaceInfo.cs +++ /dev/null @@ -1,827 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.User -{ - /// - /// https://api.bilibili.com/x/space/acc/info?mid= - /// - public class UserSpaceInfo - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public UserSpaceInfoData Data { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoData - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("sex")] - public string Sex { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft")] - public int FaceNft { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft_type")] - public int FaceNftType { get; set; } - - /// - /// - /// - [JsonPropertyName("sign")] - public string Sign { get; set; } - - /// - /// - /// - [JsonPropertyName("rank")] - public int Rank { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public int Level { get; set; } - - /// - /// - /// - [JsonPropertyName("jointime")] - public int Jointime { get; set; } - - /// - /// - /// - [JsonPropertyName("moral")] - public int Moral { get; set; } - - /// - /// - /// - [JsonPropertyName("silence")] - public int Silence { get; set; } - - /// - /// - /// - [JsonPropertyName("coins")] - public int Coins { get; set; } - - /// - /// - /// - [JsonPropertyName("fans_badge")] - public bool FansBadge { get; set; } - - /// - /// - /// - [JsonPropertyName("fans_medal")] - public UserSpaceInfoDataFansMedal FansMedal { get; set; } - - /// - /// - /// - [JsonPropertyName("official")] - public UserSpaceInfoDataOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public UserSpaceInfoDataVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("pendant")] - public UserSpaceInfoDataPendant Pendant { get; set; } - - /// - /// - /// - [JsonPropertyName("nameplate")] - public UserSpaceInfoDataNameplate Nameplate { get; set; } - - /// - /// - /// - [JsonPropertyName("user_honour_info")] - public UserSpaceInfoDataUserHonourInfo UserHonourInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("is_followed")] - public bool IsFollowed { get; set; } - - /// - /// - /// - [JsonPropertyName("top_photo")] - public string TopPhoto { get; set; } - - /// - /// - /// - [JsonPropertyName("theme")] - public UserSpaceInfoDataTheme Theme { get; set; } - - /// - /// - /// - [JsonPropertyName("sys_notice")] - public UserSpaceInfoDataSysNotice SysNotice { get; set; } - - /// - /// - /// - [JsonPropertyName("live_room")] - public UserSpaceInfoDataLiveRoom LiveRoom { get; set; } - - /// - /// - /// - [JsonPropertyName("birthday")] - public string Birthday { get; set; } - - /// - /// - /// - [JsonPropertyName("school")] - public UserSpaceInfoDataSchool School { get; set; } - - /// - /// - /// - [JsonPropertyName("profession")] - public UserSpaceInfoDataProfession Profession { get; set; } - - /// - /// - /// - [JsonPropertyName("tags")] - public object Tags { get; set; } - - /// - /// - /// - [JsonPropertyName("series")] - public UserSpaceInfoDataSeries Series { get; set; } - - /// - /// - /// - [JsonPropertyName("is_senior_member")] - public int IsSeniorMember { get; set; } - - /// - /// - /// - [JsonPropertyName("mcn_info")] - public object McnInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("gaia_res_type")] - public int GaiaResType { get; set; } - - /// - /// - /// - [JsonPropertyName("gaia_data")] - public object GaiaData { get; set; } - - /// - /// - /// - [JsonPropertyName("is_risk")] - public bool IsRisk { get; set; } - - /// - /// - /// - [JsonPropertyName("elec")] - public UserSpaceInfoDataElec Elec { get; set; } - - /// - /// - /// - [JsonPropertyName("contract")] - public UserSpaceInfoDataContract Contract { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataFansMedal - { - /// - /// - /// - [JsonPropertyName("show")] - public bool Show { get; set; } - - /// - /// - /// - [JsonPropertyName("wear")] - public bool Wear { get; set; } - - /// - /// - /// - [JsonPropertyName("medal")] - public object Medal { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public long DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public UserSpaceInfoDataVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataPendant - { - /// - /// - /// - [JsonPropertyName("pid")] - public int Pid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("expire")] - public int Expire { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance")] - public string ImageEnhance { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance_frame")] - public string ImageEnhanceFrame { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataNameplate - { - /// - /// - /// - [JsonPropertyName("nid")] - public int Nid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("image_small")] - public string ImageSmall { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public string Level { get; set; } - - /// - /// - /// - [JsonPropertyName("condition")] - public string Condition { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataUserHonourInfo - { - /// - /// - /// - [JsonPropertyName("mid")] - public int Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("colour")] - public object Colour { get; set; } - - /// - /// - /// - [JsonPropertyName("tags")] - public List Tags { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataTheme - { } - - /// - /// - /// - public class UserSpaceInfoDataSysNotice - { } - - /// - /// - /// - public class UserSpaceInfoDataLiveRoom - { - /// - /// - /// - [JsonPropertyName("roomStatus")] - public int Roomstatus { get; set; } - - /// - /// - /// - [JsonPropertyName("liveStatus")] - public int Livestatus { get; set; } - - /// - /// - /// - [JsonPropertyName("url")] - public string Url { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("cover")] - public string Cover { get; set; } - - /// - /// - /// - [JsonPropertyName("roomid")] - public long Roomid { get; set; } - - /// - /// - /// - [JsonPropertyName("roundStatus")] - public int Roundstatus { get; set; } - - /// - /// - /// - [JsonPropertyName("broadcast_type")] - public int BroadcastType { get; set; } - - /// - /// - /// - [JsonPropertyName("watched_show")] - public UserSpaceInfoDataLiveRoomWatchedShow WatchedShow { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataLiveRoomWatchedShow - { - /// - /// - /// - [JsonPropertyName("switch")] - public bool Switch { get; set; } - - /// - /// - /// - [JsonPropertyName("num")] - public int Num { get; set; } - - /// - /// - /// - [JsonPropertyName("text_small")] - public string TextSmall { get; set; } - - /// - /// - /// - [JsonPropertyName("text_large")] - public string TextLarge { get; set; } - - /// - /// - /// - [JsonPropertyName("icon")] - public string Icon { get; set; } - - /// - /// - /// - [JsonPropertyName("icon_location")] - public string IconLocation { get; set; } - - /// - /// - /// - [JsonPropertyName("icon_web")] - public string IconWeb { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataSchool - { - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataProfession - { - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("department")] - public string Department { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("is_show")] - public int IsShow { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataSeries - { - /// - /// - /// - [JsonPropertyName("user_upgrade_status")] - public int UserUpgradeStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("show_upgrade_window")] - public bool ShowUpgradeWindow { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataElec - { - /// - /// - /// - [JsonPropertyName("show_info")] - public UserSpaceInfoDataElecShowInfo ShowInfo { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataElecShowInfo - { - /// - /// - /// - [JsonPropertyName("show")] - public bool Show { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("icon")] - public string Icon { get; set; } - - /// - /// - /// - [JsonPropertyName("jump_url")] - public string JumpUrl { get; set; } - } - - /// - /// - /// - public class UserSpaceInfoDataContract - { - /// - /// - /// - [JsonPropertyName("is_display")] - public bool IsDisplay { get; set; } - - /// - /// - /// - [JsonPropertyName("is_follow_display")] - public bool IsFollowDisplay { get; set; } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Models/Video/VideoView.cs b/src/BiliSharp/Api/Models/Video/VideoView.cs deleted file mode 100644 index 33694b3..0000000 --- a/src/BiliSharp/Api/Models/Video/VideoView.cs +++ /dev/null @@ -1,3257 +0,0 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; - -namespace BiliSharp.Api.Models.Video -{ - /// - /// https://api.bilibili.com/x/web-interface/wbi/view/detail?platform=web&bvid=BV1Pu4y1y7FA&aid=872233698&need_operation_card=1&web_rm_repeat=1&need_elec=1&out_referer=&page_no=1&p=1&web_location=1446382&w_rid=b9d75e9f42896cc2093f022e5e9b1fd2&wts=1694017091 - /// - public class VideoView - { - /// - /// - /// - [JsonPropertyName("code")] - public int Code { get; set; } - - /// - /// - /// - [JsonPropertyName("message")] - public string Message { get; set; } - - /// - /// - /// - [JsonPropertyName("ttl")] - public int Ttl { get; set; } - - /// - /// - /// - [JsonPropertyName("data")] - public VideoViewData Data { get; set; } - } - - /// - /// - /// - public class VideoViewData - { - /// - /// - /// - [JsonPropertyName("View")] - public VideoViewDataView View { get; set; } - - /// - /// - /// - [JsonPropertyName("Card")] - public VideoViewDataCard Card { get; set; } - - /// - /// - /// - [JsonPropertyName("Tags")] - public List Tags { get; set; } - - /// - /// - /// - [JsonPropertyName("Reply")] - public VideoViewDataReply Reply { get; set; } - - /// - /// - /// - [JsonPropertyName("Related")] - public List Related { get; set; } - - /// - /// - /// - [JsonPropertyName("Spec")] - public object Spec { get; set; } - - /// - /// - /// - [JsonPropertyName("hot_share")] - public VideoViewDataHotShare HotShare { get; set; } - - /// - /// - /// - [JsonPropertyName("elec")] - public VideoViewDataElec Elec { get; set; } - - /// - /// - /// - [JsonPropertyName("recommend")] - public object Recommend { get; set; } - - /// - /// - /// - //[JsonPropertyName("view_addit")] - //public VideoViewDataViewAddit ViewAddit { get; set; } - - /// - /// - /// - [JsonPropertyName("guide")] - public object Guide { get; set; } - - /// - /// - /// - [JsonPropertyName("query_tags")] - public object QueryTags { get; set; } - - /// - /// - /// - [JsonPropertyName("is_old_user")] - public bool IsOldUser { get; set; } - } - - /// - /// - /// - public class VideoViewDataView - { - /// - /// - /// - [JsonPropertyName("bvid")] - public string Bvid { get; set; } - - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("videos")] - public int Videos { get; set; } - - /// - /// - /// - [JsonPropertyName("tid")] - public int Tid { get; set; } - - /// - /// - /// - [JsonPropertyName("tname")] - public string Tname { get; set; } - - /// - /// - /// - [JsonPropertyName("copyright")] - public int Copyright { get; set; } - - /// - /// - /// - [JsonPropertyName("pic")] - public string Pic { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("pubdate")] - public long Pubdate { get; set; } - - /// - /// - /// - [JsonPropertyName("ctime")] - public long Ctime { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("desc_v2")] - public List DescV2 { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("duration")] - public int Duration { get; set; } - - /// - /// - /// - [JsonPropertyName("mission_id")] - public long MissionId { get; set; } - - /// - /// - /// - [JsonPropertyName("rights")] - public VideoViewDataViewRights Rights { get; set; } - - /// - /// - /// - [JsonPropertyName("owner")] - public VideoViewDataViewOwner Owner { get; set; } - - /// - /// - /// - [JsonPropertyName("stat")] - public VideoViewDataViewStat Stat { get; set; } - - /// - /// - /// - [JsonPropertyName("dynamic")] - public string Dynamic { get; set; } - - /// - /// - /// - [JsonPropertyName("cid")] - public long Cid { get; set; } - - /// - /// - /// - [JsonPropertyName("dimension")] - public VideoViewDataViewDimension Dimension { get; set; } - - /// - /// - /// - [JsonPropertyName("season_id")] - public long SeasonId { get; set; } - - /// - /// - /// - [JsonPropertyName("premiere")] - public object Premiere { get; set; } - - /// - /// - /// - [JsonPropertyName("teenage_mode")] - public int TeenageMode { get; set; } - - /// - /// - /// - [JsonPropertyName("is_chargeable_season")] - public bool IsChargeableSeason { get; set; } - - /// - /// - /// - [JsonPropertyName("is_story")] - public bool IsStory { get; set; } - - /// - /// - /// - [JsonPropertyName("is_upower_exclusive")] - public bool IsUpowerExclusive { get; set; } - - /// - /// - /// - [JsonPropertyName("is_upower_play")] - public bool IsUpowerPlay { get; set; } - - /// - /// - /// - [JsonPropertyName("enable_vt")] - public int EnableVt { get; set; } - - /// - /// - /// - [JsonPropertyName("vt_display")] - public string VtDisplay { get; set; } - - /// - /// - /// - [JsonPropertyName("no_cache")] - public bool NoCache { get; set; } - - /// - /// - /// - [JsonPropertyName("pages")] - public List Pages { get; set; } - - /// - /// - /// - [JsonPropertyName("subtitle")] - public VideoViewDataViewSubtitle Subtitle { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public VideoViewDataViewLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("staff")] - public List Staff { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_season")] - public VideoViewDataViewUgcSeason UgcSeason { get; set; } - - /// - /// - /// - [JsonPropertyName("is_season_display")] - public bool IsSeasonDisplay { get; set; } - - /// - /// - /// - [JsonPropertyName("user_garb")] - public VideoViewDataViewUserGarb UserGarb { get; set; } - - /// - /// - /// - [JsonPropertyName("honor_reply")] - public VideoViewDataViewHonorReply HonorReply { get; set; } - - /// - /// - /// - [JsonPropertyName("like_icon")] - public string LikeIcon { get; set; } - - /// - /// - /// - [JsonPropertyName("need_jump_bv")] - public bool NeedJumpBv { get; set; } - - /// - /// - /// - [JsonPropertyName("disable_show_up_info")] - public bool DisableShowUpInfo { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewDescV2 - { - /// - /// - /// - [JsonPropertyName("raw_text")] - public string RawText { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("biz_id")] - public int BizId { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewRights - { - /// - /// - /// - [JsonPropertyName("bp")] - public int Bp { get; set; } - - /// - /// - /// - [JsonPropertyName("elec")] - public int Elec { get; set; } - - /// - /// - /// - [JsonPropertyName("download")] - public int Download { get; set; } - - /// - /// - /// - [JsonPropertyName("movie")] - public int Movie { get; set; } - - /// - /// - /// - [JsonPropertyName("pay")] - public int Pay { get; set; } - - /// - /// - /// - [JsonPropertyName("hd5")] - public int Hd5 { get; set; } - - /// - /// - /// - [JsonPropertyName("no_reprint")] - public int NoReprint { get; set; } - - /// - /// - /// - [JsonPropertyName("autoplay")] - public int Autoplay { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_pay")] - public int UgcPay { get; set; } - - /// - /// - /// - [JsonPropertyName("is_cooperation")] - public int IsCooperation { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_pay_preview")] - public int UgcPayPreview { get; set; } - - /// - /// - /// - [JsonPropertyName("no_background")] - public int NoBackground { get; set; } - - /// - /// - /// - [JsonPropertyName("clean_mode")] - public int CleanMode { get; set; } - - /// - /// - /// - [JsonPropertyName("is_stein_gate")] - public int IsSteinGate { get; set; } - - /// - /// - /// - [JsonPropertyName("is_360")] - public int Is360 { get; set; } - - /// - /// - /// - [JsonPropertyName("no_share")] - public int NoShare { get; set; } - - /// - /// - /// - [JsonPropertyName("arc_pay")] - public int ArcPay { get; set; } - - /// - /// - /// - [JsonPropertyName("free_watch")] - public int FreeWatch { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewOwner - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewStat - { - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("view")] - public long View { get; set; } - - /// - /// - /// - [JsonPropertyName("danmaku")] - public int Danmaku { get; set; } - - /// - /// - /// - [JsonPropertyName("reply")] - public int Reply { get; set; } - - /// - /// - /// - [JsonPropertyName("favorite")] - public int Favorite { get; set; } - - /// - /// - /// - [JsonPropertyName("coin")] - public int Coin { get; set; } - - /// - /// - /// - [JsonPropertyName("share")] - public int Share { get; set; } - - /// - /// - /// - [JsonPropertyName("now_rank")] - public int NowRank { get; set; } - - /// - /// - /// - [JsonPropertyName("his_rank")] - public int HisRank { get; set; } - - /// - /// - /// - [JsonPropertyName("like")] - public int Like { get; set; } - - /// - /// - /// - [JsonPropertyName("dislike")] - public int Dislike { get; set; } - - /// - /// - /// - [JsonPropertyName("evaluation")] - public string Evaluation { get; set; } - - /// - /// - /// - [JsonPropertyName("argue_msg")] - public string ArgueMsg { get; set; } - - /// - /// - /// - [JsonPropertyName("vt")] - public int Vt { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewDimension - { - /// - /// - /// - [JsonPropertyName("width")] - public int Width { get; set; } - - /// - /// - /// - [JsonPropertyName("height")] - public int Height { get; set; } - - /// - /// - /// - [JsonPropertyName("rotate")] - public int Rotate { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewPages - { - /// - /// - /// - [JsonPropertyName("cid")] - public long Cid { get; set; } - - /// - /// - /// - [JsonPropertyName("page")] - public int Page { get; set; } - - /// - /// - /// - [JsonPropertyName("from")] - public string From { get; set; } - - /// - /// - /// - [JsonPropertyName("part")] - public string Part { get; set; } - - /// - /// - /// - [JsonPropertyName("duration")] - public int Duration { get; set; } - - /// - /// - /// - [JsonPropertyName("vid")] - public string Vid { get; set; } - - /// - /// - /// - [JsonPropertyName("weblink")] - public string Weblink { get; set; } - - /// - /// - /// - [JsonPropertyName("dimension")] - public VideoViewDataViewPagesDimension Dimension { get; set; } - - /// - /// - /// - [JsonPropertyName("first_frame")] - public string FirstFrame { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewPagesDimension - { - /// - /// - /// - [JsonPropertyName("width")] - public int Width { get; set; } - - /// - /// - /// - [JsonPropertyName("height")] - public int Height { get; set; } - - /// - /// - /// - [JsonPropertyName("rotate")] - public int Rotate { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewSubtitle - { - /// - /// - /// - [JsonPropertyName("allow_submit")] - public bool AllowSubmit { get; set; } - - /// - /// - /// - [JsonPropertyName("list")] - public List List { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewLabel - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewStaff - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public VideoViewDataViewStaffVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("official")] - public VideoViewDataViewStaffOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("follower")] - public long Follower { get; set; } - - /// - /// - /// - [JsonPropertyName("label_style")] - public int LabelStyle { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewStaffVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public long DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public VideoViewDataViewStaffVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_due_date")] - public int TvDueDate { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewStaffVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewStaffOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeason - { - /// - /// - /// - [JsonPropertyName("id")] - public long Id { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("cover")] - public string Cover { get; set; } - - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("intro")] - public string Intro { get; set; } - - /// - /// - /// - [JsonPropertyName("sign_state")] - public int SignState { get; set; } - - /// - /// - /// - [JsonPropertyName("attribute")] - public int Attribute { get; set; } - - /// - /// - /// - [JsonPropertyName("sections")] - public List Sections { get; set; } - - /// - /// - /// - [JsonPropertyName("stat")] - public VideoViewDataViewUgcSeasonStat Stat { get; set; } - - /// - /// - /// - [JsonPropertyName("ep_count")] - public int EpCount { get; set; } - - /// - /// - /// - [JsonPropertyName("season_type")] - public int SeasonType { get; set; } - - /// - /// - /// - [JsonPropertyName("is_pay_season")] - public bool IsPaySeason { get; set; } - - /// - /// - /// - [JsonPropertyName("enable_vt")] - public int EnableVt { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSections - { - /// - /// - /// - [JsonPropertyName("season_id")] - public long SeasonId { get; set; } - - /// - /// - /// - [JsonPropertyName("id")] - public long Id { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("episodes")] - public List Episodes { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodes - { - /// - /// - /// - [JsonPropertyName("season_id")] - public long SeasonId { get; set; } - - /// - /// - /// - [JsonPropertyName("section_id")] - public long SectionId { get; set; } - - /// - /// - /// - [JsonPropertyName("id")] - public long Id { get; set; } - - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("cid")] - public long Cid { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("attribute")] - public int Attribute { get; set; } - - /// - /// - /// - [JsonPropertyName("arc")] - public VideoViewDataViewUgcSeasonSectionsEpisodesArc Arc { get; set; } - - /// - /// - /// - [JsonPropertyName("page")] - public VideoViewDataViewUgcSeasonSectionsEpisodesPage Page { get; set; } - - /// - /// - /// - [JsonPropertyName("bvid")] - public string Bvid { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesArc - { - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("videos")] - public int Videos { get; set; } - - /// - /// - /// - [JsonPropertyName("type_id")] - public int TypeId { get; set; } - - /// - /// - /// - [JsonPropertyName("type_name")] - public string TypeName { get; set; } - - /// - /// - /// - [JsonPropertyName("copyright")] - public int Copyright { get; set; } - - /// - /// - /// - [JsonPropertyName("pic")] - public string Pic { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("pubdate")] - public long Pubdate { get; set; } - - /// - /// - /// - [JsonPropertyName("ctime")] - public long Ctime { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("duration")] - public int Duration { get; set; } - - /// - /// - /// - [JsonPropertyName("rights")] - public VideoViewDataViewUgcSeasonSectionsEpisodesArcRights Rights { get; set; } - - /// - /// - /// - [JsonPropertyName("author")] - public VideoViewDataViewUgcSeasonSectionsEpisodesArcAuthor Author { get; set; } - - /// - /// - /// - [JsonPropertyName("stat")] - public VideoViewDataViewUgcSeasonSectionsEpisodesArcStat Stat { get; set; } - - /// - /// - /// - [JsonPropertyName("dynamic")] - public string Dynamic { get; set; } - - /// - /// - /// - [JsonPropertyName("dimension")] - public VideoViewDataViewUgcSeasonSectionsEpisodesArcDimension Dimension { get; set; } - - /// - /// - /// - [JsonPropertyName("desc_v2")] - public object DescV2 { get; set; } - - /// - /// - /// - [JsonPropertyName("is_chargeable_season")] - public bool IsChargeableSeason { get; set; } - - /// - /// - /// - [JsonPropertyName("is_blooper")] - public bool IsBlooper { get; set; } - - /// - /// - /// - [JsonPropertyName("enable_vt")] - public int EnableVt { get; set; } - - /// - /// - /// - [JsonPropertyName("vt_display")] - public string VtDisplay { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesArcRights - { - /// - /// - /// - [JsonPropertyName("bp")] - public int Bp { get; set; } - - /// - /// - /// - [JsonPropertyName("elec")] - public int Elec { get; set; } - - /// - /// - /// - [JsonPropertyName("download")] - public int Download { get; set; } - - /// - /// - /// - [JsonPropertyName("movie")] - public int Movie { get; set; } - - /// - /// - /// - [JsonPropertyName("pay")] - public int Pay { get; set; } - - /// - /// - /// - [JsonPropertyName("hd5")] - public int Hd5 { get; set; } - - /// - /// - /// - [JsonPropertyName("no_reprint")] - public int NoReprint { get; set; } - - /// - /// - /// - [JsonPropertyName("autoplay")] - public int Autoplay { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_pay")] - public int UgcPay { get; set; } - - /// - /// - /// - [JsonPropertyName("is_cooperation")] - public int IsCooperation { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_pay_preview")] - public int UgcPayPreview { get; set; } - - /// - /// - /// - [JsonPropertyName("arc_pay")] - public int ArcPay { get; set; } - - /// - /// - /// - [JsonPropertyName("free_watch")] - public int FreeWatch { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesArcAuthor - { - /// - /// - /// - [JsonPropertyName("mid")] - public int Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesArcStat - { - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("view")] - public long View { get; set; } - - /// - /// - /// - [JsonPropertyName("danmaku")] - public int Danmaku { get; set; } - - /// - /// - /// - [JsonPropertyName("reply")] - public int Reply { get; set; } - - /// - /// - /// - [JsonPropertyName("fav")] - public int Fav { get; set; } - - /// - /// - /// - [JsonPropertyName("coin")] - public int Coin { get; set; } - - /// - /// - /// - [JsonPropertyName("share")] - public int Share { get; set; } - - /// - /// - /// - [JsonPropertyName("now_rank")] - public int NowRank { get; set; } - - /// - /// - /// - [JsonPropertyName("his_rank")] - public int HisRank { get; set; } - - /// - /// - /// - [JsonPropertyName("like")] - public long Like { get; set; } - - /// - /// - /// - [JsonPropertyName("dislike")] - public int Dislike { get; set; } - - /// - /// - /// - [JsonPropertyName("evaluation")] - public string Evaluation { get; set; } - - /// - /// - /// - [JsonPropertyName("argue_msg")] - public string ArgueMsg { get; set; } - - /// - /// - /// - [JsonPropertyName("vt")] - public int Vt { get; set; } - - /// - /// - /// - [JsonPropertyName("vv")] - public long Vv { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesArcDimension - { - /// - /// - /// - [JsonPropertyName("width")] - public int Width { get; set; } - - /// - /// - /// - [JsonPropertyName("height")] - public int Height { get; set; } - - /// - /// - /// - [JsonPropertyName("rotate")] - public int Rotate { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesPage - { - /// - /// - /// - [JsonPropertyName("cid")] - public long Cid { get; set; } - - /// - /// - /// - [JsonPropertyName("page")] - public int Page { get; set; } - - /// - /// - /// - [JsonPropertyName("from")] - public string From { get; set; } - - /// - /// - /// - [JsonPropertyName("part")] - public string Part { get; set; } - - /// - /// - /// - [JsonPropertyName("duration")] - public int Duration { get; set; } - - /// - /// - /// - [JsonPropertyName("vid")] - public string Vid { get; set; } - - /// - /// - /// - [JsonPropertyName("weblink")] - public string Weblink { get; set; } - - /// - /// - /// - [JsonPropertyName("dimension")] - public VideoViewDataViewUgcSeasonSectionsEpisodesPageDimension Dimension { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonSectionsEpisodesPageDimension - { - /// - /// - /// - [JsonPropertyName("width")] - public int Width { get; set; } - - /// - /// - /// - [JsonPropertyName("height")] - public int Height { get; set; } - - /// - /// - /// - [JsonPropertyName("rotate")] - public int Rotate { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUgcSeasonStat - { - /// - /// - /// - [JsonPropertyName("season_id")] - public long SeasonId { get; set; } - - /// - /// - /// - [JsonPropertyName("view")] - public long View { get; set; } - - /// - /// - /// - [JsonPropertyName("danmaku")] - public int Danmaku { get; set; } - - /// - /// - /// - [JsonPropertyName("reply")] - public int Reply { get; set; } - - /// - /// - /// - [JsonPropertyName("fav")] - public long Fav { get; set; } - - /// - /// - /// - [JsonPropertyName("coin")] - public long Coin { get; set; } - - /// - /// - /// - [JsonPropertyName("share")] - public long Share { get; set; } - - /// - /// - /// - [JsonPropertyName("now_rank")] - public int NowRank { get; set; } - - /// - /// - /// - [JsonPropertyName("his_rank")] - public int HisRank { get; set; } - - /// - /// - /// - [JsonPropertyName("like")] - public long Like { get; set; } - - /// - /// - /// - [JsonPropertyName("vt")] - public int Vt { get; set; } - - /// - /// - /// - [JsonPropertyName("vv")] - public int Vv { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewUserGarb - { - /// - /// - /// - [JsonPropertyName("url_image_ani_cut")] - public string UrlImageAniCut { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewHonorReply - { - /// - /// - /// - [JsonPropertyName("honor")] - public List Honor { get; set; } - } - - /// - /// - /// - public class VideoViewDataViewHonorReplyHonor - { - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("weekly_recommend_num")] - public int WeeklyRecommendNum { get; set; } - } - - /// - /// - /// - public class VideoViewDataCard - { - /// - /// - /// - [JsonPropertyName("card")] - public VideoViewDataCardCard Card { get; set; } - - /// - /// - /// - [JsonPropertyName("space")] - public VideoViewDataCardSpace Space { get; set; } - - /// - /// - /// - [JsonPropertyName("following")] - public bool Following { get; set; } - - /// - /// - /// - [JsonPropertyName("archive_count")] - public int ArchiveCount { get; set; } - - /// - /// - /// - [JsonPropertyName("article_count")] - public int ArticleCount { get; set; } - - /// - /// - /// - [JsonPropertyName("follower")] - public long Follower { get; set; } - - /// - /// - /// - [JsonPropertyName("like_num")] - public long LikeNum { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCard - { - /// - /// - /// - [JsonPropertyName("mid")] - public string Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("approve")] - public bool Approve { get; set; } - - /// - /// - /// - [JsonPropertyName("sex")] - public string Sex { get; set; } - - /// - /// - /// - [JsonPropertyName("rank")] - public string Rank { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft")] - public int FaceNft { get; set; } - - /// - /// - /// - [JsonPropertyName("face_nft_type")] - public int FaceNftType { get; set; } - - /// - /// - /// - [JsonPropertyName("DisplayRank")] - public string Displayrank { get; set; } - - /// - /// - /// - [JsonPropertyName("regtime")] - public int Regtime { get; set; } - - /// - /// - /// - [JsonPropertyName("spacesta")] - public int Spacesta { get; set; } - - /// - /// - /// - [JsonPropertyName("birthday")] - public string Birthday { get; set; } - - /// - /// - /// - [JsonPropertyName("place")] - public string Place { get; set; } - - /// - /// - /// - [JsonPropertyName("description")] - public string Description { get; set; } - - /// - /// - /// - [JsonPropertyName("article")] - public int Article { get; set; } - - /// - /// - /// - [JsonPropertyName("attentions")] - public List Attentions { get; set; } - - /// - /// - /// - [JsonPropertyName("fans")] - public long Fans { get; set; } - - /// - /// - /// - [JsonPropertyName("friend")] - public int Friend { get; set; } - - /// - /// - /// - [JsonPropertyName("attention")] - public int Attention { get; set; } - - /// - /// - /// - [JsonPropertyName("sign")] - public string Sign { get; set; } - - /// - /// - /// - [JsonPropertyName("level_info")] - public VideoViewDataCardCardLevelInfo LevelInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("pendant")] - public VideoViewDataCardCardPendant Pendant { get; set; } - - /// - /// - /// - [JsonPropertyName("nameplate")] - public VideoViewDataCardCardNameplate Nameplate { get; set; } - - /// - /// - /// - [JsonPropertyName("Official")] - public VideoViewDataCardCardOfficial Official { get; set; } - - /// - /// - /// - [JsonPropertyName("official_verify")] - public VideoViewDataCardCardOfficialVerify OfficialVerify { get; set; } - - /// - /// - /// - [JsonPropertyName("vip")] - public VideoViewDataCardCardVip Vip { get; set; } - - /// - /// - /// - [JsonPropertyName("is_senior_member")] - public int IsSeniorMember { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardLevelInfo - { - /// - /// - /// - [JsonPropertyName("current_level")] - public int CurrentLevel { get; set; } - - /// - /// - /// - [JsonPropertyName("current_min")] - public int CurrentMin { get; set; } - - /// - /// - /// - [JsonPropertyName("current_exp")] - public int CurrentExp { get; set; } - - /// - /// - /// - [JsonPropertyName("next_exp")] - public int NextExp { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardPendant - { - /// - /// - /// - [JsonPropertyName("pid")] - public int Pid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("expire")] - public int Expire { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance")] - public string ImageEnhance { get; set; } - - /// - /// - /// - [JsonPropertyName("image_enhance_frame")] - public string ImageEnhanceFrame { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardNameplate - { - /// - /// - /// - [JsonPropertyName("nid")] - public int Nid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("image")] - public string Image { get; set; } - - /// - /// - /// - [JsonPropertyName("image_small")] - public string ImageSmall { get; set; } - - /// - /// - /// - [JsonPropertyName("level")] - public string Level { get; set; } - - /// - /// - /// - [JsonPropertyName("condition")] - public string Condition { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardOfficial - { - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardOfficialVerify - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardVip - { - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("status")] - public int Status { get; set; } - - /// - /// - /// - [JsonPropertyName("due_date")] - public int DueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vip_pay_type")] - public int VipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("theme_type")] - public int ThemeType { get; set; } - - /// - /// - /// - [JsonPropertyName("label")] - public VideoViewDataCardCardVipLabel Label { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript")] - public int AvatarSubscript { get; set; } - - /// - /// - /// - [JsonPropertyName("nickname_color")] - public string NicknameColor { get; set; } - - /// - /// - /// - [JsonPropertyName("role")] - public int Role { get; set; } - - /// - /// - /// - [JsonPropertyName("avatar_subscript_url")] - public string AvatarSubscriptUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_status")] - public int TvVipStatus { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_vip_pay_type")] - public int TvVipPayType { get; set; } - - /// - /// - /// - [JsonPropertyName("tv_due_date")] - public int TvDueDate { get; set; } - - /// - /// - /// - [JsonPropertyName("vipType")] - public int Viptype { get; set; } - - /// - /// - /// - [JsonPropertyName("vipStatus")] - public int Vipstatus { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardCardVipLabel - { - /// - /// - /// - [JsonPropertyName("path")] - public string Path { get; set; } - - /// - /// - /// - [JsonPropertyName("text")] - public string Text { get; set; } - - /// - /// - /// - [JsonPropertyName("label_theme")] - public string LabelTheme { get; set; } - - /// - /// - /// - [JsonPropertyName("text_color")] - public string TextColor { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_style")] - public int BgStyle { get; set; } - - /// - /// - /// - [JsonPropertyName("bg_color")] - public string BgColor { get; set; } - - /// - /// - /// - [JsonPropertyName("border_color")] - public string BorderColor { get; set; } - - /// - /// - /// - [JsonPropertyName("use_img_label")] - public bool UseImgLabel { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans")] - public string ImgLabelUriHans { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant")] - public string ImgLabelUriHant { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hans_static")] - public string ImgLabelUriHansStatic { get; set; } - - /// - /// - /// - [JsonPropertyName("img_label_uri_hant_static")] - public string ImgLabelUriHantStatic { get; set; } - } - - /// - /// - /// - public class VideoViewDataCardSpace - { - /// - /// - /// - [JsonPropertyName("s_img")] - public string SImg { get; set; } - - /// - /// - /// - [JsonPropertyName("l_img")] - public string LImg { get; set; } - } - - /// - /// - /// - public class VideoViewDataTags - { - /// - /// - /// - [JsonPropertyName("tag_id")] - public int TagId { get; set; } - - /// - /// - /// - [JsonPropertyName("tag_name")] - public string TagName { get; set; } - - /// - /// - /// - [JsonPropertyName("cover")] - public string Cover { get; set; } - - /// - /// - /// - [JsonPropertyName("head_cover")] - public string HeadCover { get; set; } - - /// - /// - /// - [JsonPropertyName("content")] - public string Content { get; set; } - - /// - /// - /// - [JsonPropertyName("short_content")] - public string ShortContent { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("ctime")] - public int Ctime { get; set; } - - /// - /// - /// - [JsonPropertyName("count")] - public VideoViewDataTagsCount Count { get; set; } - - /// - /// - /// - [JsonPropertyName("is_atten")] - public int IsAtten { get; set; } - - /// - /// - /// - [JsonPropertyName("likes")] - public int Likes { get; set; } - - /// - /// - /// - [JsonPropertyName("hates")] - public int Hates { get; set; } - - /// - /// - /// - [JsonPropertyName("attribute")] - public int Attribute { get; set; } - - /// - /// - /// - [JsonPropertyName("liked")] - public int Liked { get; set; } - - /// - /// - /// - [JsonPropertyName("hated")] - public int Hated { get; set; } - - /// - /// - /// - [JsonPropertyName("extra_attr")] - public int ExtraAttr { get; set; } - - /// - /// - /// - [JsonPropertyName("music_id")] - public string MusicId { get; set; } - - /// - /// - /// - [JsonPropertyName("tag_type")] - public string TagType { get; set; } - - /// - /// - /// - [JsonPropertyName("is_activity")] - public bool IsActivity { get; set; } - - /// - /// - /// - [JsonPropertyName("color")] - public string Color { get; set; } - - /// - /// - /// - [JsonPropertyName("alpha")] - public int Alpha { get; set; } - - /// - /// - /// - [JsonPropertyName("is_season")] - public bool IsSeason { get; set; } - - /// - /// - /// - [JsonPropertyName("subscribed_count")] - public int SubscribedCount { get; set; } - - /// - /// - /// - [JsonPropertyName("archive_count")] - public string ArchiveCount { get; set; } - - /// - /// - /// - [JsonPropertyName("featured_count")] - public int FeaturedCount { get; set; } - - /// - /// - /// - [JsonPropertyName("jump_url")] - public string JumpUrl { get; set; } - } - - /// - /// - /// - public class VideoViewDataTagsCount - { - /// - /// - /// - [JsonPropertyName("view")] - public int View { get; set; } - - /// - /// - /// - [JsonPropertyName("use")] - public int Use { get; set; } - - /// - /// - /// - [JsonPropertyName("atten")] - public int Atten { get; set; } - } - - /// - /// - /// - public class VideoViewDataReply - { - /// - /// - /// - [JsonPropertyName("page")] - public object Page { get; set; } - - /// - /// - /// - [JsonPropertyName("replies")] - public List Replies { get; set; } - } - - /// - /// - /// - public class VideoViewDataReplyReplies - { - /// - /// - /// - [JsonPropertyName("rpid")] - public int Rpid { get; set; } - - /// - /// - /// - [JsonPropertyName("oid")] - public int Oid { get; set; } - - /// - /// - /// - [JsonPropertyName("type")] - public int Type { get; set; } - - /// - /// - /// - [JsonPropertyName("mid")] - public int Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("root")] - public int Root { get; set; } - - /// - /// - /// - [JsonPropertyName("parent")] - public int Parent { get; set; } - - /// - /// - /// - [JsonPropertyName("dialog")] - public int Dialog { get; set; } - - /// - /// - /// - [JsonPropertyName("count")] - public int Count { get; set; } - - /// - /// - /// - [JsonPropertyName("rcount")] - public int Rcount { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("fansgrade")] - public int Fansgrade { get; set; } - - /// - /// - /// - [JsonPropertyName("attr")] - public int Attr { get; set; } - - /// - /// - /// - [JsonPropertyName("ctime")] - public int Ctime { get; set; } - - /// - /// - /// - [JsonPropertyName("like")] - public int Like { get; set; } - - /// - /// - /// - [JsonPropertyName("action")] - public int Action { get; set; } - - /// - /// - /// - [JsonPropertyName("content")] - public object Content { get; set; } - - /// - /// - /// - [JsonPropertyName("replies")] - public object Replies { get; set; } - - /// - /// - /// - [JsonPropertyName("assist")] - public int Assist { get; set; } - - /// - /// - /// - [JsonPropertyName("show_follow")] - public bool ShowFollow { get; set; } - } - - /// - /// - /// - public class VideoViewDataRelated - { - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("videos")] - public int Videos { get; set; } - - /// - /// - /// - [JsonPropertyName("tid")] - public int Tid { get; set; } - - /// - /// - /// - [JsonPropertyName("tname")] - public string Tname { get; set; } - - /// - /// - /// - [JsonPropertyName("copyright")] - public int Copyright { get; set; } - - /// - /// - /// - [JsonPropertyName("pic")] - public string Pic { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("pubdate")] - public long Pubdate { get; set; } - - /// - /// - /// - [JsonPropertyName("ctime")] - public long Ctime { get; set; } - - /// - /// - /// - [JsonPropertyName("desc")] - public string Desc { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("duration")] - public int Duration { get; set; } - - /// - /// - /// - [JsonPropertyName("mission_id")] - public long MissionId { get; set; } - - /// - /// - /// - [JsonPropertyName("rights")] - public VideoViewDataRelatedRights Rights { get; set; } - - /// - /// - /// - [JsonPropertyName("owner")] - public VideoViewDataRelatedOwner Owner { get; set; } - - /// - /// - /// - [JsonPropertyName("stat")] - public VideoViewDataRelatedStat Stat { get; set; } - - /// - /// - /// - [JsonPropertyName("dynamic")] - public string Dynamic { get; set; } - - /// - /// - /// - [JsonPropertyName("cid")] - public long Cid { get; set; } - - /// - /// - /// - [JsonPropertyName("dimension")] - public VideoViewDataRelatedDimension Dimension { get; set; } - - /// - /// - /// - [JsonPropertyName("season_id")] - public long SeasonId { get; set; } - - /// - /// - /// - [JsonPropertyName("short_link_v2")] - public string ShortLinkV2 { get; set; } - - /// - /// - /// - [JsonPropertyName("up_from_v2")] - public int UpFromV2 { get; set; } - - /// - /// - /// - [JsonPropertyName("first_frame")] - public string FirstFrame { get; set; } - - /// - /// - /// - [JsonPropertyName("pub_location")] - public string PubLocation { get; set; } - - /// - /// - /// - [JsonPropertyName("bvid")] - public string Bvid { get; set; } - - /// - /// - /// - [JsonPropertyName("season_type")] - public int SeasonType { get; set; } - - /// - /// - /// - [JsonPropertyName("is_ogv")] - public bool IsOgv { get; set; } - - /// - /// - /// - [JsonPropertyName("ogv_info")] - public object OgvInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("rcmd_reason")] - public string RcmdReason { get; set; } - - /// - /// - /// - [JsonPropertyName("enable_vt")] - public int EnableVt { get; set; } - } - - /// - /// - /// - public class VideoViewDataRelatedRights - { - /// - /// - /// - [JsonPropertyName("bp")] - public int Bp { get; set; } - - /// - /// - /// - [JsonPropertyName("elec")] - public int Elec { get; set; } - - /// - /// - /// - [JsonPropertyName("download")] - public int Download { get; set; } - - /// - /// - /// - [JsonPropertyName("movie")] - public int Movie { get; set; } - - /// - /// - /// - [JsonPropertyName("pay")] - public int Pay { get; set; } - - /// - /// - /// - [JsonPropertyName("hd5")] - public int Hd5 { get; set; } - - /// - /// - /// - [JsonPropertyName("no_reprint")] - public int NoReprint { get; set; } - - /// - /// - /// - [JsonPropertyName("autoplay")] - public int Autoplay { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_pay")] - public int UgcPay { get; set; } - - /// - /// - /// - [JsonPropertyName("is_cooperation")] - public int IsCooperation { get; set; } - - /// - /// - /// - [JsonPropertyName("ugc_pay_preview")] - public int UgcPayPreview { get; set; } - - /// - /// - /// - [JsonPropertyName("no_background")] - public int NoBackground { get; set; } - - /// - /// - /// - [JsonPropertyName("arc_pay")] - public int ArcPay { get; set; } - - /// - /// - /// - [JsonPropertyName("pay_free_watch")] - public int PayFreeWatch { get; set; } - } - - /// - /// - /// - public class VideoViewDataRelatedOwner - { - /// - /// - /// - [JsonPropertyName("mid")] - public long Mid { get; set; } - - /// - /// - /// - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// - /// - [JsonPropertyName("face")] - public string Face { get; set; } - } - - /// - /// - /// - public class VideoViewDataRelatedStat - { - /// - /// - /// - [JsonPropertyName("aid")] - public long Aid { get; set; } - - /// - /// - /// - [JsonPropertyName("view")] - public long View { get; set; } - - /// - /// - /// - [JsonPropertyName("danmaku")] - public int Danmaku { get; set; } - - /// - /// - /// - [JsonPropertyName("reply")] - public int Reply { get; set; } - - /// - /// - /// - [JsonPropertyName("favorite")] - public int Favorite { get; set; } - - /// - /// - /// - [JsonPropertyName("coin")] - public int Coin { get; set; } - - /// - /// - /// - [JsonPropertyName("share")] - public int Share { get; set; } - - /// - /// - /// - [JsonPropertyName("now_rank")] - public int NowRank { get; set; } - - /// - /// - /// - [JsonPropertyName("his_rank")] - public int HisRank { get; set; } - - /// - /// - /// - [JsonPropertyName("like")] - public long Like { get; set; } - - /// - /// - /// - [JsonPropertyName("dislike")] - public int Dislike { get; set; } - - /// - /// - /// - [JsonPropertyName("vt")] - public int Vt { get; set; } - - /// - /// - /// - [JsonPropertyName("vv")] - public long Vv { get; set; } - } - - /// - /// - /// - public class VideoViewDataRelatedDimension - { - /// - /// - /// - [JsonPropertyName("width")] - public int Width { get; set; } - - /// - /// - /// - [JsonPropertyName("height")] - public int Height { get; set; } - - /// - /// - /// - [JsonPropertyName("rotate")] - public int Rotate { get; set; } - } - - /// - /// - /// - public class VideoViewDataHotShare - { - /// - /// - /// - [JsonPropertyName("show")] - public bool Show { get; set; } - - /// - /// - /// - [JsonPropertyName("list")] - public List List { get; set; } - } - - /// - /// - /// - public class VideoViewDataElec - { - /// - /// - /// - [JsonPropertyName("show_info")] - public VideoViewDataElecShowInfo ShowInfo { get; set; } - - /// - /// - /// - [JsonPropertyName("av_count")] - public int AvCount { get; set; } - - /// - /// - /// - [JsonPropertyName("count")] - public int Count { get; set; } - - /// - /// - /// - [JsonPropertyName("total_count")] - public int TotalCount { get; set; } - - /// - /// - /// - [JsonPropertyName("special_day")] - public int SpecialDay { get; set; } - - /// - /// - /// - [JsonPropertyName("display_num")] - public int DisplayNum { get; set; } - } - - /// - /// - /// - public class VideoViewDataElecShowInfo - { - /// - /// - /// - [JsonPropertyName("show")] - public bool Show { get; set; } - - /// - /// - /// - [JsonPropertyName("state")] - public int State { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("jump_url")] - public string JumpUrl { get; set; } - - /// - /// - /// - [JsonPropertyName("icon")] - public string Icon { get; set; } - - /// - /// - /// - [JsonPropertyName("high_level")] - public VideoViewDataElecShowInfoHighLevel HighLevel { get; set; } - } - - /// - /// - /// - public class VideoViewDataElecShowInfoHighLevel - { - /// - /// - /// - [JsonPropertyName("privilege_type")] - public int PrivilegeType { get; set; } - - /// - /// - /// - [JsonPropertyName("level_str")] - public string LevelStr { get; set; } - - /// - /// - /// - [JsonPropertyName("title")] - public string Title { get; set; } - - /// - /// - /// - [JsonPropertyName("intro")] - public string Intro { get; set; } - - /// - /// - /// - [JsonPropertyName("open")] - public bool Open { get; set; } - } - - /// - /// - /// - //public class VideoViewDataViewAddit - //{ - // /// - // /// - // /// - // [JsonPropertyName("63")] - // public bool 63 { get; set; } - - // /// - // /// - // /// - // [JsonPropertyName("64")] - // public bool 64 { get; set; } - - // /// - // /// - // /// - // [JsonPropertyName("69")] - // public bool 69 { get; set; } - - // /// - // /// - // /// - // [JsonPropertyName("71")] - // public bool 71 { get; set; } - - // /// - // /// - // /// - // [JsonPropertyName("72")] - // public bool 72 { get; set; } - //} -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Sign/WbiSign.cs b/src/BiliSharp/Api/Sign/WbiSign.cs deleted file mode 100644 index 43e4937..0000000 --- a/src/BiliSharp/Api/Sign/WbiSign.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; - -namespace BiliSharp.Api.Sign -{ - public static class WbiSign - { - private static Tuple Keys; - - /// - /// 打乱重排实时口令 - /// - /// - /// - private static string GetMixinKey(string origin) - { - int[] mixinKeyEncTab = new int[] - { - 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, - 33, 9, 42, 19, 29, 28, 14, 39,12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, - 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, - 36, 20, 34, 44, 52 - }; - - var temp = new StringBuilder(); - foreach (var i in mixinKeyEncTab) - { - temp.Append(origin[i]); - } - return temp.ToString()[..32]; - } - - /// - /// 将字典参数转为字符串 - /// - /// - /// - public static string ParametersToQuery(Dictionary parameters) - { - var keys = parameters.Keys.ToList(); - var queryList = new List(); - foreach (var item in keys) - { - var value = parameters[item]; - queryList.Add($"{item}={value}"); - } - return string.Join("&", queryList); - } - - /// - /// 返回imgKey,subKey - /// - /// - public static Tuple GetKey() - { - // 当Keys为null时,返回一个硬编码的key, - // 这个key无效,只为了保证不报错 - return Keys ?? new Tuple("653657f524a547ac981ded72ea172057", "6e4909c702f846728e64f6007736a338"); - } - - /// - /// 设置imgKey,subKey - /// - /// - public static void SetKey(Tuple keys) - { - Keys = keys; - } - - /// - /// Wbi签名,返回所有参数字典 - /// - /// - /// - public static Dictionary EncodeWbi(Dictionary parameters) - { - return EncodeWbi(parameters, GetKey().Item1, GetKey().Item2); - } - - /// - /// Wbi签名,返回所有参数字典 - /// - /// - /// - /// - /// - public static Dictionary EncodeWbi(Dictionary parameters, string imgKey, string subKey) - { - var mixinKey = GetMixinKey(imgKey + subKey); - - var chrFilter = new Regex("[!'()*]"); - - var newParameters = new Dictionary - { - { "wts", (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds } - }; - - foreach (var para in parameters) - { - var key = para.Key; - var value = para.Value.ToString(); - - var encodedValue = chrFilter.Replace(value, ""); - - newParameters.Add(Uri.EscapeDataString(key), Uri.EscapeDataString(encodedValue)); - } - - var keys = newParameters.Keys.ToList(); - keys.Sort(); - - var queryList = new List(); - foreach (var item in keys) - { - var value = newParameters[item]; - queryList.Add($"{item}={value}"); - } - - var queryString = string.Join("&", queryList); - var md5Hasher = MD5.Create(); - var hashStr = queryString + mixinKey; - var hashedQueryString = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(hashStr)); - var wbiSign = BitConverter.ToString(hashedQueryString).Replace("-", "").ToLower(); - - newParameters.Add("w_rid", wbiSign); - return newParameters; - } - - } -} diff --git a/src/BiliSharp/Api/User/Nickname.cs b/src/BiliSharp/Api/User/Nickname.cs deleted file mode 100644 index ddcab9e..0000000 --- a/src/BiliSharp/Api/User/Nickname.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace BiliSharp.Api.User -{ - /// - /// 检查昵称是否可注册 - /// - public static class Nickname - { - /// - /// 检查昵称 - /// - /// - /// - public static Models.User.Nickname CheckNickname(string nickname) - { - string url = $"https://passport.bilibili.com/web/generic/check/nickname?nickName={nickname}"; - return Utils.GetData(url); - } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/User/UserInfo.cs b/src/BiliSharp/Api/User/UserInfo.cs deleted file mode 100644 index b89f3e2..0000000 --- a/src/BiliSharp/Api/User/UserInfo.cs +++ /dev/null @@ -1,66 +0,0 @@ -using BiliSharp.Api.Models.User; -using BiliSharp.Api.Sign; -using System.Collections.Generic; - -namespace BiliSharp.Api.User -{ - /// - /// 用户基本信息 - /// - public static class UserInfo - { - /// - /// 用户空间详细信息 - /// - /// - public static UserSpaceInfo GetUserInfo(long mid) - { - var parameters = new Dictionary - { - { "mid", mid } - }; - string query = WbiSign.ParametersToQuery(WbiSign.EncodeWbi(parameters)); - string url = $"https://api.bilibili.com/x/space/wbi/acc/info?{query}"; - return Utils.GetData(url); - } - - /// - /// 用户名片信息 - /// - /// - /// - /// - public static UserCard GetUserCard(long mid, bool isPhoto = false) - { - string url = $"https://api.bilibili.com/x/web-interface/card?mid={mid}&photo={isPhoto}"; - return Utils.GetData(url); - } - - /// - /// 登录用户空间详细信息 - /// - /// - public static MyInfo GetMyInfo() - { - string url = "https://api.bilibili.com/x/space/myinfo"; - return Utils.GetData(url); - } - - /// - /// 多用户详细信息 - /// - /// - /// - public static UserCards GetUserCards(List ids) - { - string url = "https://api.vc.bilibili.com/account/v1/user/cards?uids="; - foreach (long id in ids) - { - url += $"{id},"; - } - url = url.TrimEnd(','); - - return Utils.GetData(url); - } - } -} \ No newline at end of file diff --git a/src/BiliSharp/Api/Video/VideoInfo.cs b/src/BiliSharp/Api/Video/VideoInfo.cs deleted file mode 100644 index cf29210..0000000 --- a/src/BiliSharp/Api/Video/VideoInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using BiliSharp.Api.Models.Video; -using BiliSharp.Api.Sign; -using System.Collections.Generic; - -namespace BiliSharp.Api.Video -{ - /// - /// 视频基本信息 - /// - public static class VideoInfo - { - /// - /// 获取视频超详细信息(web端) - /// - /// - /// - /// - public static VideoView GetVideoViewInfo(string bvid, long aid) - { - var parameters = new Dictionary - { - { "platform", "web" }, - //{ "need_operation_card", 1 }, - //{ "web_location", 1446382 }, - { "need_elec", 1 }, - { "aid", aid }, - { "bvid", bvid }, - }; - string query = WbiSign.ParametersToQuery(WbiSign.EncodeWbi(parameters)); - string url = $"https://api.bilibili.com/x/web-interface/wbi/view/detail?{query}"; - return Utils.GetData(url); - } - - } -} diff --git a/src/BiliSharp/BiliManager.cs b/src/BiliSharp/BiliManager.cs deleted file mode 100644 index 2aaabf2..0000000 --- a/src/BiliSharp/BiliManager.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Net; - -namespace BiliSharp -{ - public class BiliManager - { - private static readonly BiliManager _instance = new BiliManager(); - private string _userAgent; - private CookieContainer _cookies; - - private BiliManager() { } - - public static BiliManager Instance() - { - return _instance; - } - - /// - /// 设置cookies - /// - /// - /// - public BiliManager SetCookies(CookieContainer cookies) - { - _cookies = cookies; - return this; - } - - /// - /// 获取cookies - /// - /// - public CookieContainer GetCookies() { return _cookies; } - - /// - /// 设置userAgent - /// - /// - /// - public BiliManager SetUserAgent(string userAgent) - { - _userAgent = userAgent; - return this; - } - - /// - /// 获取userAgent - /// - /// - public string GetUserAgent() { return _userAgent; } - - } -} \ No newline at end of file diff --git a/src/BiliSharp/BiliSharp.csproj b/src/BiliSharp/BiliSharp.csproj deleted file mode 100644 index c675825..0000000 --- a/src/BiliSharp/BiliSharp.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - netstandard2.1 - - - - - - - diff --git a/src/BiliSharp/Utils.cs b/src/BiliSharp/Utils.cs deleted file mode 100644 index 7ff2142..0000000 --- a/src/BiliSharp/Utils.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Net; -using System.Text.Json; - -namespace BiliSharp -{ - internal static class Utils - { - internal static T GetData(string url) - { - string referer = "https://www.bilibili.com"; - string userAgent = BiliManager.Instance().GetUserAgent(); - CookieContainer cookies = BiliManager.Instance().GetCookies(); - - string response = WebClient.RequestWeb(url, referer, userAgent, cookies); - - try - { - var obj = JsonSerializer.Deserialize(response); - return obj; - } - catch (Exception) - { - return default; - } - } - - } -} \ No newline at end of file diff --git a/src/BiliSharp/WebClient.cs b/src/BiliSharp/WebClient.cs deleted file mode 100644 index 9d8a0c5..0000000 --- a/src/BiliSharp/WebClient.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Net; -using System.Text; - -namespace BiliSharp -{ - internal static class WebClient - { - /// - /// 发送get或post请求 - /// - /// - /// - /// - /// - /// - /// - /// - /// - internal static string RequestWeb(string url, string referer = null, string userAgent = null, CookieContainer cookies = null, string method = "GET", Dictionary parameters = null, int retry = 3) - { - // 重试次数 - if (retry <= 0) { return ""; } - - // post请求,发送参数 - if (method == "POST" && parameters != null) - { - var 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 = 60 * 1000; - - 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"; - - // userAgent - if (userAgent != null) - { - request.UserAgent = userAgent; - } - else - { - request.UserAgent = "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"; - } - - // referer - if (referer != null) - { - request.Referer = referer; - } - - // 构造cookie - if (!url.Contains("getLogin")) - { - //request.Headers["origin"] = "https://www.bilibili.com"; - - if (cookies != null) - { - request.CookieContainer = cookies; - } - } - - string html = string.Empty; - using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) - { - if (response.ContentEncoding.ToLower().Contains("gzip")) - { - using var stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress); - using var reader = new StreamReader(stream, Encoding.UTF8); - html = reader.ReadToEnd(); - } - else if (response.ContentEncoding.ToLower().Contains("deflate")) - { - using var stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress); - using var reader = new StreamReader(stream, Encoding.UTF8); - html = reader.ReadToEnd(); - } - else if (response.ContentEncoding.ToLower().Contains("br")) - { - using var stream = new BrotliStream(response.GetResponseStream(), CompressionMode.Decompress); - using var reader = new StreamReader(stream, Encoding.UTF8); - html = reader.ReadToEnd(); - } - else - { - using var stream = response.GetResponseStream(); - using var reader = new StreamReader(stream, Encoding.UTF8); - html = reader.ReadToEnd(); - } - } - - return html; - } - catch (Exception) - { - return RequestWeb(url, referer, userAgent, cookies, method, parameters, retry - 1); - } - } - } -} \ No newline at end of file diff --git a/src/Downkyi.sln b/src/Downkyi.sln index de1498f..eb4fd0f 100644 --- a/src/Downkyi.sln +++ b/src/Downkyi.sln @@ -9,12 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Downkyi.UI", "Downkyi.UI\Do EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Downkyi.Core", "Downkyi.Core\Downkyi.Core.csproj", "{5CED42DB-2155-45D0-B195-57BB894CB97B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BiliSharp", "BiliSharp\BiliSharp.csproj", "{199B3491-51F0-460D-AB90-191B7DD377D6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BiliSharp.UnitTest", "BiliSharp.UnitTest\BiliSharp.UnitTest.csproj", "{107D1B61-6936-45A0-B4AF-3776C736649A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Gif", "Avalonia.Gif\Avalonia.Gif.csproj", "{0E32DD42-C1C8-45A4-9572-8D963D85B0EF}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,18 +27,6 @@ Global {5CED42DB-2155-45D0-B195-57BB894CB97B}.Debug|Any CPU.Build.0 = Debug|Any CPU {5CED42DB-2155-45D0-B195-57BB894CB97B}.Release|Any CPU.ActiveCfg = Release|Any CPU {5CED42DB-2155-45D0-B195-57BB894CB97B}.Release|Any CPU.Build.0 = Release|Any CPU - {199B3491-51F0-460D-AB90-191B7DD377D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {199B3491-51F0-460D-AB90-191B7DD377D6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {199B3491-51F0-460D-AB90-191B7DD377D6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {199B3491-51F0-460D-AB90-191B7DD377D6}.Release|Any CPU.Build.0 = Release|Any CPU - {107D1B61-6936-45A0-B4AF-3776C736649A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {107D1B61-6936-45A0-B4AF-3776C736649A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {107D1B61-6936-45A0-B4AF-3776C736649A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {107D1B61-6936-45A0-B4AF-3776C736649A}.Release|Any CPU.Build.0 = Release|Any CPU - {0E32DD42-C1C8-45A4-9572-8D963D85B0EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0E32DD42-C1C8-45A4-9572-8D963D85B0EF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0E32DD42-C1C8-45A4-9572-8D963D85B0EF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0E32DD42-C1C8-45A4-9572-8D963D85B0EF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/third_party/Avalonia.GIF-11rc1.zip b/third_party/Avalonia.GIF-11rc1.zip deleted file mode 100644 index 75c53c896f16c3b310f14d49553d4700c19df0d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8964111 zcmb4qbBr)fljhjAZQHhI-mz`lwr$(CZQC~9v3 zlZ4wLan-duHPM;uYQdj`WRM6F2H-L=?C0eh4nV50#&r`D8zdk|IQ!Gh*}k7|R?`IJ zlgMVwip^1n64j}2VbZ?IR7nH+Gx;Q^TG}-D+A>USH+5n_aNU@B0ct3RLZjDI^P=|j z6p&vxRlKr=5^ka6b+7@8yxK^q2uqc-?3!MKEvfeMp;D*~T~QOw^~!^r!XJgxB}w%Ov!G_0erA*%gV)tc0b|ezH0!8KE&G z5PN}(tjxNGOZ7fPKX$9br1mftRZIYD8gxl)=isT2mKc(qE16b{E=`Ow4QF`b2fN3# z+sSfFG*E8u_4e23ta%?^FLv}8ahKNC^E+mTcDEl6wTPB7Ec@e(EIYMb zN*59xE*5!Nx4mHN)8!7vE(CcDmaLV^^b&W~=FH^s9cG4!S(IG{3>fB3IjCxWU8dXH zwgdHavSp?1#apO1vt4zVx?p++OkD$LQ4l~#(c;YE^X zjW8kw>0i(;3Lw&Jq1>iQr#;rXbhqq%%_Luk`lEO={%@2*A|y#|d@9)vvKt%0>4L4+ zzvQjii)LTv@Qa*|^-ar5`w@Na#|cNmRE6XRtcIIl8-wjcz1sYIENtBf10n>7W65*t zZ{8vX&eL?tfQxmL(=}i^4@Fs?W1f2xiESJlBH66jLb)+1m1m0qQ!=0G1cTU&mF)q) z3=udOI7k!lH%CoP)=3kg#sZ!9yT3NZc0*XI`y1GCj~fWqe%IBH8ZUG0rMw~N;&-Pq zoi6!sq9wnceP`F9@;Mcvej2}kzq4k8QDIxj3BluG)X!_jlyN8<1n&l)hWKFfK1m7= z{Ro)PoVa+1X|AP=gSE3Tpr%X_NfQK;;30X5X+xoWXj}E%Vi`H^9`q;Gj#ttpG>kS_ z#jH#e?=F$nhqB))$JUVGBUbRP?&k)e6148E;iJZ`C2QSI~~2-K3?Ru zYFLKB*-xsdj8~v71<@|aeu2m%$u%-|`LrIVuxb&SW?fbI<_7V;>M^gixz`#sm4>&M z-nW&$%^w4-&-XtRYX{xi|KzC88C|1T*s{zc6sXshBkDGyCD?}K@D~2--q`iw!I#sP!y>^u9rws6@ zs5vWPv}>-*~Daw-V2SvYw zgYPg`z0?7>3rk~RCGqGV6|B%E*wUnaQ?2#gx|L{8^2;RmjMw$NzHh z0SHLe1L21dSsN6K`RtM#vTRbsyL0Qh1XI*`Fp86WMDJd_M?b&{rnlo10l4IorUEhp zHAMyzXCR`4!;}|uQ>{>R9K+o6FpU8sR|%P;GpW5K(^5w$h&=fNGhqfu_ow?a;;=LC z`yYpaTMur8alp8WYa<=jE-NZfK?AC!%3TjS=EPf0o4)Yt{DaeZN-8BrR?^CQeN}HLtBPBsH~%+ zqSAY7t}DvC;(Dy*d-Rte|H<#pAX;v(YouLSB%)sG;owwnR>og#9DDvLwIA3;Z#-_c zn$rB6-_V}oX)A1{LfAw8VV>7-H_olp=7@)%uggyd%`H)A7YG1Sem)Qctn0pSnyfY( zskO%voSz3>kRd#imvnUv^$?HBWA3zmb%Y!^ybf{!JL@DhGl0(zmpFj0jPh9eG{Q*! z2}G_^cmPeAs@|2wmW)0}qm5Laa$-ooKtU$5^D#}3OVPc#J0j5Qy*xGk z*Kyc&0h8*l*e2)D0=ZvVnQ)c5*%�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 _LWlmt%Ubfv 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