mirror of
https://github.com/leiurayer/downkyi.git
synced 2025-03-23 15:50:12 +08:00
独立出几个项目
This commit is contained in:
parent
8d15ce4018
commit
1ca966f617
@ -1,13 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,10 +0,0 @@
|
||||
namespace Avalonia.Gif
|
||||
{
|
||||
internal enum BgWorkerCommand
|
||||
{
|
||||
Null,
|
||||
Play,
|
||||
Pause,
|
||||
Dispose
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
namespace Avalonia.Gif
|
||||
{
|
||||
internal enum BgWorkerState
|
||||
{
|
||||
Null,
|
||||
Start,
|
||||
Running,
|
||||
Paused,
|
||||
Complete,
|
||||
Dispose
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Avalonia.Gif.Decoding
|
||||
{
|
||||
internal enum BlockTypes
|
||||
{
|
||||
Empty = 0,
|
||||
Extension = 0x21,
|
||||
ImageDescriptor = 0x2C,
|
||||
Trailer = 0x3B,
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace Avalonia.Gif.Decoding
|
||||
{
|
||||
internal enum ExtensionType
|
||||
{
|
||||
GraphicsControl = 0xF9,
|
||||
Application = 0xFF
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace Avalonia.Gif.Decoding
|
||||
{
|
||||
public enum FrameDisposal
|
||||
{
|
||||
Unknown = 0,
|
||||
Leave = 1,
|
||||
Background = 2,
|
||||
Restore = 3
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// A struct that represents a ARGB color and is aligned as
|
||||
/// a BGRA bytefield in memory.
|
||||
/// </summary>
|
||||
/// <param name="r">Red</param>
|
||||
/// <param name="g">Green</param>
|
||||
/// <param name="b">Blue</param>
|
||||
/// <param name="a">Alpha</param>
|
||||
public GifColor(byte r, byte g, byte b, byte a = byte.MaxValue)
|
||||
{
|
||||
A = a;
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<byte> G87AMagic
|
||||
= "GIF87a"u8.ToArray().AsMemory();
|
||||
|
||||
private static readonly ReadOnlyMemory<byte> G89AMagic
|
||||
= "GIF89a"u8.ToArray().AsMemory();
|
||||
|
||||
private static readonly ReadOnlyMemory<byte> 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<GifFrame> 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<byte>.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<byte>.Shared.Return(tmpB);
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void DrawFrame(GifFrame curFrame, Memory<byte> 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<byte> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directly copies the <see cref="GifColor"/> struct array to a bitmap IntPtr.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes GIF Header.
|
||||
/// </summary>
|
||||
private void ProcessHeaderData()
|
||||
{
|
||||
var str = _fileStream;
|
||||
var tmpB = ArrayPool<byte>.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<byte>.Shared.Return(tmpB);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses colors from file stream to target color table.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses screen and other GIF descriptors.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses all frame data.
|
||||
/// </summary>
|
||||
private void ProcessFrameData()
|
||||
{
|
||||
_fileStream.Position = Header.HeaderSize;
|
||||
|
||||
var tempBuf = ArrayPool<byte>.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<byte>.Shared.Return(tempBuf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses GIF Image Descriptor Block.
|
||||
/// </summary>
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses GIF Extension Blocks.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace Avalonia.Gif.Decoding
|
||||
{
|
||||
public class GifRepeatBehavior
|
||||
{
|
||||
public bool LoopForever { get; set; }
|
||||
public int? Count { get; set; }
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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<byte> b) => (ushort)(b[0] | (b[1] << 8));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Skip(this Stream stream, long count)
|
||||
{
|
||||
stream.Position += count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a Gif block from stream while advancing the position.
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skips GIF blocks until it encounters an empty block.
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a <see cref="ushort"/> from stream by providing a temporary buffer.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort ReadUShortS(this Stream stream, byte[] tempBuf)
|
||||
{
|
||||
stream.Read(tempBuf, 0, 2);
|
||||
return SpanToShort(tempBuf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a <see cref="ushort"/> from stream by providing a temporary buffer.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ReadByteS(this Stream stream, byte[] tempBuf)
|
||||
{
|
||||
stream.Read(tempBuf, 0, 1);
|
||||
var finalVal = tempBuf[0];
|
||||
return finalVal;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<string> SourceUriRawProperty =
|
||||
AvaloniaProperty.Register<GifImage, string>("SourceUriRaw");
|
||||
|
||||
public static readonly StyledProperty<Uri> SourceUriProperty =
|
||||
AvaloniaProperty.Register<GifImage, Uri>("SourceUri");
|
||||
|
||||
public static readonly StyledProperty<Stream> SourceStreamProperty =
|
||||
AvaloniaProperty.Register<GifImage, Stream>("SourceStream");
|
||||
|
||||
public static readonly StyledProperty<IterationCount> IterationCountProperty =
|
||||
AvaloniaProperty.Register<GifImage, IterationCount>("IterationCount", IterationCount.Infinite);
|
||||
|
||||
private GifInstance? _gifInstance;
|
||||
|
||||
public static readonly StyledProperty<StretchDirection> StretchDirectionProperty =
|
||||
AvaloniaProperty.Register<GifImage, StretchDirection>("StretchDirection");
|
||||
|
||||
public static readonly StyledProperty<Stretch> StretchProperty =
|
||||
AvaloniaProperty.Register<GifImage, Stretch>("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());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Measures the control.
|
||||
/// </summary>
|
||||
/// <param name="availableSize">The available size.</param>
|
||||
/// <returns>The desired size of the control.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<TimeSpan> _frameTimes;
|
||||
private uint _iterationCount;
|
||||
private int _currentFrameIndex;
|
||||
private readonly List<ulong> _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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<string, object>
|
||||
{
|
||||
{ "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, object>();
|
||||
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<string, string>(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<string, object>
|
||||
{
|
||||
{ "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<string, object>
|
||||
{
|
||||
{ "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"]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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<string, string>(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<long> ids = new()
|
||||
{
|
||||
314521322,
|
||||
206840230,
|
||||
49246269
|
||||
};
|
||||
var users = UserInfo.GetUserCards(ids);
|
||||
|
||||
foreach (var user in users.Data)
|
||||
{
|
||||
Assert.Contains(user.Mid, ids);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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<string, string>(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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="xunit" Version="2.6.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BiliSharp\BiliSharp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,43 +0,0 @@
|
||||
using System.Net;
|
||||
|
||||
namespace BiliSharp.UnitTest;
|
||||
|
||||
public static class Cookies
|
||||
{
|
||||
/// <summary>
|
||||
/// 解析从浏览器获取的cookies,用于设置cookie
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
global using Xunit;
|
@ -1,40 +0,0 @@
|
||||
using BiliSharp.Api.Models.Login;
|
||||
|
||||
namespace BiliSharp.Api.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录基本信息
|
||||
/// </summary>
|
||||
public static class LoginInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 导航栏用户信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static NavigationLoginInfo GetNavigationInfo()
|
||||
{
|
||||
string url = "https://api.bilibili.com/x/web-interface/nav";
|
||||
return Utils.GetData<NavigationLoginInfo>(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录用户状态数(双端)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LoginInfoStat GetLoginInfoStat()
|
||||
{
|
||||
string url = "https://api.bilibili.com/x/web-interface/nav/stat";
|
||||
return Utils.GetData<LoginInfoStat>(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取硬币数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static MyCoin GetMyCoin()
|
||||
{
|
||||
string url = "https://account.bilibili.com/site/getCoin";
|
||||
return Utils.GetData<MyCoin>(url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
namespace BiliSharp.Api.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录记录
|
||||
/// </summary>
|
||||
public static class LoginNotice
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询登录记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Models.Login.LoginNotice GetLoginNotice(long mid)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/x/safecenter/login_notice?mid={mid}";
|
||||
return Utils.GetData<Models.Login.LoginNotice>(url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
using BiliSharp.Api.Models.Login;
|
||||
|
||||
namespace BiliSharp.Api.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// 二维码登录
|
||||
/// </summary>
|
||||
public static class LoginQR
|
||||
{
|
||||
/// <summary>
|
||||
/// 申请二维码(web端)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LoginQRCode GenerateQRCode()
|
||||
{
|
||||
string url = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
|
||||
return Utils.GetData<LoginQRCode>(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扫码登录(web端)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LoginQRCodePoll PollQRCode(string qrcodeKey)
|
||||
{
|
||||
string url = $"https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qrcodeKey}";
|
||||
return Utils.GetData<LoginQRCodePoll>(url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.bilibili.com/x/web-interface/nav/stat
|
||||
/// </summary>
|
||||
public class LoginInfoStat
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public LoginInfoStatData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginInfoStatData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("following")]
|
||||
public int Following { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("follower")]
|
||||
public int Follower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("dynamic_count")]
|
||||
public int DynamicCount { get; set; }
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.bilibili.com/x/safecenter/login_notice?mid=
|
||||
/// </summary>
|
||||
public class LoginNotice
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public LoginNoticeData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginNoticeData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("device_name")]
|
||||
public string DeviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("login_type")]
|
||||
public string LoginType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("login_time")]
|
||||
public string LoginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("location")]
|
||||
public string Location { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ip")]
|
||||
public string Ip { get; set; }
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// https://passport.bilibili.com/x/passport-login/web/qrcode/generate
|
||||
/// </summary>
|
||||
public class LoginQRCode
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public LoginQRCodeData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginQRCodeData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("qrcode_key")]
|
||||
public string QrcodeKey { get; set; }
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=
|
||||
/// </summary>
|
||||
public class LoginQRCodePoll
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public LoginQRCodePollData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginQRCodePollData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("refresh_token")]
|
||||
public string RefreshToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("timestamp")]
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public long Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// https://account.bilibili.com/site/getCoin
|
||||
/// </summary>
|
||||
public class MyCoin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public bool Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public MyCoinData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyCoinData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("money")]
|
||||
public int Money { get; set; }
|
||||
}
|
||||
}
|
@ -1,556 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.bilibili.com/x/web-interface/nav
|
||||
/// </summary>
|
||||
public class NavigationLoginInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public NavigationLoginInfoData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("isLogin")]
|
||||
public bool Islogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("email_verified")]
|
||||
public int EmailVerified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face")]
|
||||
public string Face { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft")]
|
||||
public int FaceNft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft_type")]
|
||||
public int FaceNftType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level_info")]
|
||||
public NavigationLoginInfoDataLevelInfo LevelInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mobile_verified")]
|
||||
public int MobileVerified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("money")]
|
||||
public int Money { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("moral")]
|
||||
public int Moral { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("official")]
|
||||
public NavigationLoginInfoDataOfficial Official { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("officialVerify")]
|
||||
public NavigationLoginInfoDataOfficialverify Officialverify { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pendant")]
|
||||
public NavigationLoginInfoDataPendant Pendant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("scores")]
|
||||
public int Scores { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("uname")]
|
||||
public string Uname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vipDueDate")]
|
||||
public long Vipduedate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vipStatus")]
|
||||
public int Vipstatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vipType")]
|
||||
public int Viptype { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_pay_type")]
|
||||
public int VipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_theme_type")]
|
||||
public int VipThemeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_label")]
|
||||
public NavigationLoginInfoDataVipLabel VipLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_avatar_subscript")]
|
||||
public int VipAvatarSubscript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_nickname_color")]
|
||||
public string VipNicknameColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip")]
|
||||
public NavigationLoginInfoDataVip Vip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("wallet")]
|
||||
public NavigationLoginInfoDataWallet Wallet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("has_shop")]
|
||||
public bool HasShop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("shop_url")]
|
||||
public string ShopUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("allowance_count")]
|
||||
public int AllowanceCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("answer_status")]
|
||||
public int AnswerStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_senior_member")]
|
||||
public int IsSeniorMember { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("wbi_img")]
|
||||
public NavigationLoginInfoDataWbiImg WbiImg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_jury")]
|
||||
public bool IsJury { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataLevelInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_level")]
|
||||
public int CurrentLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_min")]
|
||||
public int CurrentMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_exp")]
|
||||
public int CurrentExp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("next_exp")]
|
||||
public object NextExp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataOfficial
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataOfficialverify
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataPendant
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pid")]
|
||||
public int Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire")]
|
||||
public int Expire { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance")]
|
||||
public string ImageEnhance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance_frame")]
|
||||
public string ImageEnhanceFrame { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataVipLabel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label_theme")]
|
||||
public string LabelTheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_color")]
|
||||
public string TextColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_style")]
|
||||
public int BgStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_color")]
|
||||
public string BgColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("border_color")]
|
||||
public string BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_img_label")]
|
||||
public bool UseImgLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans")]
|
||||
public string ImgLabelUriHans { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant")]
|
||||
public string ImgLabelUriHant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans_static")]
|
||||
public string ImgLabelUriHansStatic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant_static")]
|
||||
public string ImgLabelUriHantStatic { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataVip
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("due_date")]
|
||||
public long DueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_pay_type")]
|
||||
public int VipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("theme_type")]
|
||||
public int ThemeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label")]
|
||||
public NavigationLoginInfoDataVipLabel Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript")]
|
||||
public int AvatarSubscript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nickname_color")]
|
||||
public string NicknameColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript_url")]
|
||||
public string AvatarSubscriptUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_status")]
|
||||
public int TvVipStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_pay_type")]
|
||||
public int TvVipPayType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataWallet
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bcoin_balance")]
|
||||
public int BcoinBalance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("coupon_balance")]
|
||||
public int CouponBalance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("coupon_due_time")]
|
||||
public int CouponDueTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigationLoginInfoDataWbiImg
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_url")]
|
||||
public string ImgUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sub_url")]
|
||||
public string SubUrl { get; set; }
|
||||
}
|
||||
}
|
@ -1,652 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.User
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.bilibili.com/x/space/myinfo
|
||||
/// </summary>
|
||||
public class MyInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public MyInfoData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sex")]
|
||||
public string Sex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face")]
|
||||
public string Face { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sign")]
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("rank")]
|
||||
public int Rank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("jointime")]
|
||||
public int Jointime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("moral")]
|
||||
public int Moral { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("silence")]
|
||||
public int Silence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("email_status")]
|
||||
public int EmailStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tel_status")]
|
||||
public int TelStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("identification")]
|
||||
public int Identification { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip")]
|
||||
public MyInfoDataVip Vip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pendant")]
|
||||
public MyInfoDataPendant Pendant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nameplate")]
|
||||
public MyInfoDataNameplate Nameplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("official")]
|
||||
public MyInfoDataOfficial Official { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("birthday")]
|
||||
public long Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_tourist")]
|
||||
public int IsTourist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_fake_account")]
|
||||
public int IsFakeAccount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pin_prompting")]
|
||||
public int PinPrompting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_deleted")]
|
||||
public int IsDeleted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("in_reg_audit")]
|
||||
public int InRegAudit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_rip_user")]
|
||||
public bool IsRipUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("profession")]
|
||||
public MyInfoDataProfession Profession { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft")]
|
||||
public int FaceNft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft_new")]
|
||||
public int FaceNftNew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_senior_member")]
|
||||
public int IsSeniorMember { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("honours")]
|
||||
public MyInfoDataHonours Honours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("digital_id")]
|
||||
public string DigitalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("digital_type")]
|
||||
public int DigitalType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level_exp")]
|
||||
public MyInfoDataLevelExp LevelExp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("coins")]
|
||||
public int Coins { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("following")]
|
||||
public int Following { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("follower")]
|
||||
public int Follower { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataVip
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("due_date")]
|
||||
public long DueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_pay_type")]
|
||||
public int VipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("theme_type")]
|
||||
public int ThemeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label")]
|
||||
public MyInfoDataVipLabel Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript")]
|
||||
public int AvatarSubscript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nickname_color")]
|
||||
public string NicknameColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript_url")]
|
||||
public string AvatarSubscriptUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_status")]
|
||||
public int TvVipStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_pay_type")]
|
||||
public int TvVipPayType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataVipLabel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label_theme")]
|
||||
public string LabelTheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_color")]
|
||||
public string TextColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_style")]
|
||||
public int BgStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_color")]
|
||||
public string BgColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("border_color")]
|
||||
public string BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_img_label")]
|
||||
public bool UseImgLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans")]
|
||||
public string ImgLabelUriHans { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant")]
|
||||
public string ImgLabelUriHant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans_static")]
|
||||
public string ImgLabelUriHansStatic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant_static")]
|
||||
public string ImgLabelUriHantStatic { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataPendant
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pid")]
|
||||
public int Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire")]
|
||||
public int Expire { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance")]
|
||||
public string ImageEnhance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance_frame")]
|
||||
public string ImageEnhanceFrame { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataNameplate
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nid")]
|
||||
public int Nid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_small")]
|
||||
public string ImageSmall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public string Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("condition")]
|
||||
public string Condition { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataOfficial
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataProfession
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("show_name")]
|
||||
public string ShowName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_show")]
|
||||
public int IsShow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("category_one")]
|
||||
public string CategoryOne { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("realname")]
|
||||
public string Realname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("department")]
|
||||
public string Department { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataHonours
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("colour")]
|
||||
public MyInfoDataHonoursColour Colour { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tags")]
|
||||
public object Tags { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataHonoursColour
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("dark")]
|
||||
public string Dark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("normal")]
|
||||
public string Normal { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MyInfoDataLevelExp
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_level")]
|
||||
public int CurrentLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_min")]
|
||||
public int CurrentMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_exp")]
|
||||
public int CurrentExp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("next_exp")]
|
||||
public int NextExp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level_up")]
|
||||
public long LevelUp { get; set; }
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.User
|
||||
{
|
||||
/// <summary>
|
||||
/// https://passport.bilibili.com/web/generic/check/nickname?nickName=hahaha
|
||||
/// </summary>
|
||||
public class Nickname
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
@ -1,599 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.User
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.bilibili.com/x/web-interface/card?mid=314521322&photo=true
|
||||
/// </summary>
|
||||
public class UserCard
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public UserCardData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("card")]
|
||||
public UserCardDataCard Card { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("space")]
|
||||
public UserCardDataSpace Space { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("following")]
|
||||
public bool Following { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("archive_count")]
|
||||
public int ArchiveCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("article_count")]
|
||||
public int ArticleCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("follower")]
|
||||
public long Follower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("like_num")]
|
||||
public long LikeNum { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCard
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public string Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("approve")]
|
||||
public bool Approve { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sex")]
|
||||
public string Sex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("rank")]
|
||||
public string Rank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face")]
|
||||
public string Face { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft")]
|
||||
public int FaceNft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft_type")]
|
||||
public int FaceNftType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("DisplayRank")]
|
||||
public string Displayrank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("regtime")]
|
||||
public int Regtime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("spacesta")]
|
||||
public int Spacesta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("birthday")]
|
||||
public string Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("place")]
|
||||
public string Place { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("article")]
|
||||
public int Article { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("attentions")]
|
||||
public List<object> Attentions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("fans")]
|
||||
public long Fans { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("friend")]
|
||||
public int Friend { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("attention")]
|
||||
public int Attention { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sign")]
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level_info")]
|
||||
public UserCardDataCardLevelInfo LevelInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pendant")]
|
||||
public UserCardDataCardPendant Pendant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nameplate")]
|
||||
public UserCardDataCardNameplate Nameplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("Official")]
|
||||
public UserCardDataCardOfficial Official { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("official_verify")]
|
||||
public UserCardDataCardOfficialVerify OfficialVerify { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip")]
|
||||
public UserCardDataCardVip Vip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_senior_member")]
|
||||
public int IsSeniorMember { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardLevelInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_level")]
|
||||
public int CurrentLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_min")]
|
||||
public int CurrentMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("current_exp")]
|
||||
public int CurrentExp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("next_exp")]
|
||||
public int NextExp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardPendant
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pid")]
|
||||
public int Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire")]
|
||||
public int Expire { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance")]
|
||||
public string ImageEnhance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance_frame")]
|
||||
public string ImageEnhanceFrame { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardNameplate
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nid")]
|
||||
public int Nid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_small")]
|
||||
public string ImageSmall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public string Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("condition")]
|
||||
public string Condition { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardOfficial
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardOfficialVerify
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardVip
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("due_date")]
|
||||
public long DueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_pay_type")]
|
||||
public int VipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("theme_type")]
|
||||
public int ThemeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label")]
|
||||
public UserCardDataCardVipLabel Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript")]
|
||||
public int AvatarSubscript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nickname_color")]
|
||||
public string NicknameColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript_url")]
|
||||
public string AvatarSubscriptUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_status")]
|
||||
public int TvVipStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_pay_type")]
|
||||
public int TvVipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vipType")]
|
||||
public int Viptype { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vipStatus")]
|
||||
public int Vipstatus { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataCardVipLabel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label_theme")]
|
||||
public string LabelTheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_color")]
|
||||
public string TextColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_style")]
|
||||
public int BgStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_color")]
|
||||
public string BgColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("border_color")]
|
||||
public string BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_img_label")]
|
||||
public bool UseImgLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans")]
|
||||
public string ImgLabelUriHans { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant")]
|
||||
public string ImgLabelUriHant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans_static")]
|
||||
public string ImgLabelUriHansStatic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant_static")]
|
||||
public string ImgLabelUriHantStatic { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardDataSpace
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("s_img")]
|
||||
public string SImg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("l_img")]
|
||||
public string LImg { get; set; }
|
||||
}
|
||||
}
|
@ -1,443 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.User
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.vc.bilibili.com/account/v1/user/cards?uids=314521322,206840230,49246269
|
||||
/// </summary>
|
||||
public class UserCards
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("msg")]
|
||||
public string Msg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public List<UserCardsData> Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardsData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sex")]
|
||||
public string Sex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face")]
|
||||
public string Face { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sign")]
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("rank")]
|
||||
public int Rank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("silence")]
|
||||
public int Silence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip")]
|
||||
public UserCardsDataVip Vip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pendant")]
|
||||
public UserCardsDataPendant Pendant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nameplate")]
|
||||
public UserCardsDataNameplate Nameplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("official")]
|
||||
public UserCardsDataOfficial Official { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("birthday")]
|
||||
public long Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_fake_account")]
|
||||
public int IsFakeAccount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_deleted")]
|
||||
public int IsDeleted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("in_reg_audit")]
|
||||
public int InRegAudit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft")]
|
||||
public int FaceNft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft_new")]
|
||||
public int FaceNftNew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_senior_member")]
|
||||
public int IsSeniorMember { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("digital_id")]
|
||||
public string DigitalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("digital_type")]
|
||||
public int DigitalType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardsDataVip
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("due_date")]
|
||||
public long DueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_pay_type")]
|
||||
public int VipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("theme_type")]
|
||||
public int ThemeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label")]
|
||||
public UserCardsDataVipLabel Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript")]
|
||||
public int AvatarSubscript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nickname_color")]
|
||||
public string NicknameColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript_url")]
|
||||
public string AvatarSubscriptUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_status")]
|
||||
public int TvVipStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_pay_type")]
|
||||
public int TvVipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_due_date")]
|
||||
public long TvDueDate { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardsDataVipLabel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label_theme")]
|
||||
public string LabelTheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_color")]
|
||||
public string TextColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_style")]
|
||||
public int BgStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_color")]
|
||||
public string BgColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("border_color")]
|
||||
public string BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_img_label")]
|
||||
public bool UseImgLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans")]
|
||||
public string ImgLabelUriHans { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant")]
|
||||
public string ImgLabelUriHant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans_static")]
|
||||
public string ImgLabelUriHansStatic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant_static")]
|
||||
public string ImgLabelUriHantStatic { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardsDataPendant
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pid")]
|
||||
public int Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire")]
|
||||
public int Expire { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance")]
|
||||
public string ImageEnhance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance_frame")]
|
||||
public string ImageEnhanceFrame { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardsDataNameplate
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nid")]
|
||||
public int Nid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_small")]
|
||||
public string ImageSmall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public string Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("condition")]
|
||||
public string Condition { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserCardsDataOfficial
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
}
|
||||
}
|
@ -1,827 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BiliSharp.Api.Models.User
|
||||
{
|
||||
/// <summary>
|
||||
/// https://api.bilibili.com/x/space/acc/info?mid=
|
||||
/// </summary>
|
||||
public class UserSpaceInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("ttl")]
|
||||
public int Ttl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("data")]
|
||||
public UserSpaceInfoData Data { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoData
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public long Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sex")]
|
||||
public string Sex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face")]
|
||||
public string Face { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft")]
|
||||
public int FaceNft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("face_nft_type")]
|
||||
public int FaceNftType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sign")]
|
||||
public string Sign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("rank")]
|
||||
public int Rank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("jointime")]
|
||||
public int Jointime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("moral")]
|
||||
public int Moral { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("silence")]
|
||||
public int Silence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("coins")]
|
||||
public int Coins { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("fans_badge")]
|
||||
public bool FansBadge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("fans_medal")]
|
||||
public UserSpaceInfoDataFansMedal FansMedal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("official")]
|
||||
public UserSpaceInfoDataOfficial Official { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip")]
|
||||
public UserSpaceInfoDataVip Vip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pendant")]
|
||||
public UserSpaceInfoDataPendant Pendant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nameplate")]
|
||||
public UserSpaceInfoDataNameplate Nameplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("user_honour_info")]
|
||||
public UserSpaceInfoDataUserHonourInfo UserHonourInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_followed")]
|
||||
public bool IsFollowed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("top_photo")]
|
||||
public string TopPhoto { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("theme")]
|
||||
public UserSpaceInfoDataTheme Theme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("sys_notice")]
|
||||
public UserSpaceInfoDataSysNotice SysNotice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("live_room")]
|
||||
public UserSpaceInfoDataLiveRoom LiveRoom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("birthday")]
|
||||
public string Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("school")]
|
||||
public UserSpaceInfoDataSchool School { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("profession")]
|
||||
public UserSpaceInfoDataProfession Profession { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tags")]
|
||||
public object Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("series")]
|
||||
public UserSpaceInfoDataSeries Series { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_senior_member")]
|
||||
public int IsSeniorMember { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mcn_info")]
|
||||
public object McnInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("gaia_res_type")]
|
||||
public int GaiaResType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("gaia_data")]
|
||||
public object GaiaData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_risk")]
|
||||
public bool IsRisk { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("elec")]
|
||||
public UserSpaceInfoDataElec Elec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("contract")]
|
||||
public UserSpaceInfoDataContract Contract { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataFansMedal
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("show")]
|
||||
public bool Show { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("wear")]
|
||||
public bool Wear { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("medal")]
|
||||
public object Medal { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataOfficial
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("desc")]
|
||||
public string Desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataVip
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("due_date")]
|
||||
public long DueDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("vip_pay_type")]
|
||||
public int VipPayType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("theme_type")]
|
||||
public int ThemeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label")]
|
||||
public UserSpaceInfoDataVipLabel Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript")]
|
||||
public int AvatarSubscript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nickname_color")]
|
||||
public string NicknameColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("role")]
|
||||
public int Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("avatar_subscript_url")]
|
||||
public string AvatarSubscriptUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_status")]
|
||||
public int TvVipStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tv_vip_pay_type")]
|
||||
public int TvVipPayType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataVipLabel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("label_theme")]
|
||||
public string LabelTheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_color")]
|
||||
public string TextColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_style")]
|
||||
public int BgStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("bg_color")]
|
||||
public string BgColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("border_color")]
|
||||
public string BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("use_img_label")]
|
||||
public bool UseImgLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans")]
|
||||
public string ImgLabelUriHans { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant")]
|
||||
public string ImgLabelUriHant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hans_static")]
|
||||
public string ImgLabelUriHansStatic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("img_label_uri_hant_static")]
|
||||
public string ImgLabelUriHantStatic { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataPendant
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("pid")]
|
||||
public int Pid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("expire")]
|
||||
public int Expire { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance")]
|
||||
public string ImageEnhance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_enhance_frame")]
|
||||
public string ImageEnhanceFrame { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataNameplate
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("nid")]
|
||||
public int Nid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image")]
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("image_small")]
|
||||
public string ImageSmall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("level")]
|
||||
public string Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("condition")]
|
||||
public string Condition { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataUserHonourInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("mid")]
|
||||
public int Mid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("colour")]
|
||||
public object Colour { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("tags")]
|
||||
public List<object> Tags { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataTheme
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataSysNotice
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataLiveRoom
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("roomStatus")]
|
||||
public int Roomstatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("liveStatus")]
|
||||
public int Livestatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("cover")]
|
||||
public string Cover { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("roomid")]
|
||||
public long Roomid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("roundStatus")]
|
||||
public int Roundstatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("broadcast_type")]
|
||||
public int BroadcastType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("watched_show")]
|
||||
public UserSpaceInfoDataLiveRoomWatchedShow WatchedShow { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataLiveRoomWatchedShow
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("switch")]
|
||||
public bool Switch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("num")]
|
||||
public int Num { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_small")]
|
||||
public string TextSmall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("text_large")]
|
||||
public string TextLarge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("icon")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("icon_location")]
|
||||
public string IconLocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("icon_web")]
|
||||
public string IconWeb { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataSchool
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataProfession
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("department")]
|
||||
public string Department { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_show")]
|
||||
public int IsShow { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataSeries
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("user_upgrade_status")]
|
||||
public int UserUpgradeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("show_upgrade_window")]
|
||||
public bool ShowUpgradeWindow { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataElec
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("show_info")]
|
||||
public UserSpaceInfoDataElecShowInfo ShowInfo { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataElecShowInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("show")]
|
||||
public bool Show { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("state")]
|
||||
public int State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("icon")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("jump_url")]
|
||||
public string JumpUrl { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserSpaceInfoDataContract
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_display")]
|
||||
public bool IsDisplay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonPropertyName("is_follow_display")]
|
||||
public bool IsFollowDisplay { get; set; }
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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<string, string> Keys;
|
||||
|
||||
/// <summary>
|
||||
/// 打乱重排实时口令
|
||||
/// </summary>
|
||||
/// <param name="origin"></param>
|
||||
/// <returns></returns>
|
||||
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];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字典参数转为字符串
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public static string ParametersToQuery(Dictionary<string, object> parameters)
|
||||
{
|
||||
var keys = parameters.Keys.ToList();
|
||||
var queryList = new List<string>();
|
||||
foreach (var item in keys)
|
||||
{
|
||||
var value = parameters[item];
|
||||
queryList.Add($"{item}={value}");
|
||||
}
|
||||
return string.Join("&", queryList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回imgKey,subKey
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Tuple<string, string> GetKey()
|
||||
{
|
||||
// 当Keys为null时,返回一个硬编码的key,
|
||||
// 这个key无效,只为了保证不报错
|
||||
return Keys ?? new Tuple<string, string>("653657f524a547ac981ded72ea172057", "6e4909c702f846728e64f6007736a338");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置imgKey,subKey
|
||||
/// </summary>
|
||||
/// <param name="keys"></param>
|
||||
public static void SetKey(Tuple<string, string> keys)
|
||||
{
|
||||
Keys = keys;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wbi签名,返回所有参数字典
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, object> EncodeWbi(Dictionary<string, object> parameters)
|
||||
{
|
||||
return EncodeWbi(parameters, GetKey().Item1, GetKey().Item2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wbi签名,返回所有参数字典
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <param name="imgKey"></param>
|
||||
/// <param name="subKey"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, object> EncodeWbi(Dictionary<string, object> parameters, string imgKey, string subKey)
|
||||
{
|
||||
var mixinKey = GetMixinKey(imgKey + subKey);
|
||||
|
||||
var chrFilter = new Regex("[!'()*]");
|
||||
|
||||
var newParameters = new Dictionary<string, object>
|
||||
{
|
||||
{ "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<string>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
namespace BiliSharp.Api.User
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查昵称是否可注册
|
||||
/// </summary>
|
||||
public static class Nickname
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查昵称
|
||||
/// </summary>
|
||||
/// <param name="nickname"></param>
|
||||
/// <returns></returns>
|
||||
public static Models.User.Nickname CheckNickname(string nickname)
|
||||
{
|
||||
string url = $"https://passport.bilibili.com/web/generic/check/nickname?nickName={nickname}";
|
||||
return Utils.GetData<Models.User.Nickname>(url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
using BiliSharp.Api.Models.User;
|
||||
using BiliSharp.Api.Sign;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BiliSharp.Api.User
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户基本信息
|
||||
/// </summary>
|
||||
public static class UserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户空间详细信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static UserSpaceInfo GetUserInfo(long mid)
|
||||
{
|
||||
var parameters = new Dictionary<string, object>
|
||||
{
|
||||
{ "mid", mid }
|
||||
};
|
||||
string query = WbiSign.ParametersToQuery(WbiSign.EncodeWbi(parameters));
|
||||
string url = $"https://api.bilibili.com/x/space/wbi/acc/info?{query}";
|
||||
return Utils.GetData<UserSpaceInfo>(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户名片信息
|
||||
/// </summary>
|
||||
/// <param name="mid"></param>
|
||||
/// <param name="isPhoto"></param>
|
||||
/// <returns></returns>
|
||||
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<UserCard>(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录用户空间详细信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static MyInfo GetMyInfo()
|
||||
{
|
||||
string url = "https://api.bilibili.com/x/space/myinfo";
|
||||
return Utils.GetData<MyInfo>(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 多用户详细信息
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
public static UserCards GetUserCards(List<long> 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<UserCards>(url);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using BiliSharp.Api.Models.Video;
|
||||
using BiliSharp.Api.Sign;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BiliSharp.Api.Video
|
||||
{
|
||||
/// <summary>
|
||||
/// 视频基本信息
|
||||
/// </summary>
|
||||
public static class VideoInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取视频超详细信息(web端)
|
||||
/// </summary>
|
||||
/// <param name="bvid"></param>
|
||||
/// <param name="aid"></param>
|
||||
/// <returns></returns>
|
||||
public static VideoView GetVideoViewInfo(string bvid, long aid)
|
||||
{
|
||||
var parameters = new Dictionary<string, object>
|
||||
{
|
||||
{ "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<VideoView>(url);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置cookies
|
||||
/// </summary>
|
||||
/// <param name="cookies"></param>
|
||||
/// <returns></returns>
|
||||
public BiliManager SetCookies(CookieContainer cookies)
|
||||
{
|
||||
_cookies = cookies;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取cookies
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CookieContainer GetCookies() { return _cookies; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置userAgent
|
||||
/// </summary>
|
||||
/// <param name="userAgent"></param>
|
||||
/// <returns></returns>
|
||||
public BiliManager SetUserAgent(string userAgent)
|
||||
{
|
||||
_userAgent = userAgent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取userAgent
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetUserAgent() { return _userAgent; }
|
||||
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="7.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace BiliSharp
|
||||
{
|
||||
internal static class Utils
|
||||
{
|
||||
internal static T GetData<T>(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<T>(response);
|
||||
return obj;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送get或post请求
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="referer"></param>
|
||||
/// <param name="userAgent"></param>
|
||||
/// <param name="cookies"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="parameters"></param>
|
||||
/// <param name="retry"></param>
|
||||
/// <returns></returns>
|
||||
internal static string RequestWeb(string url, string referer = null, string userAgent = null, CookieContainer cookies = null, string method = "GET", Dictionary<string, string> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
BIN
third_party/Avalonia.GIF-11rc1.zip
vendored
BIN
third_party/Avalonia.GIF-11rc1.zip
vendored
Binary file not shown.
BIN
third_party/Avalonia.Gif.1.0.0.nupkg
vendored
Normal file
BIN
third_party/Avalonia.Gif.1.0.0.nupkg
vendored
Normal file
Binary file not shown.
BIN
third_party/Downkyi.BiliSharp.0.0.2.nupkg
vendored
Normal file
BIN
third_party/Downkyi.BiliSharp.0.0.2.nupkg
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user