mirror of
https://github.com/yaobiao131/downkyicore.git
synced 2025-08-10 00:52:31 +00:00
feat: 首次完成测试
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
.idea/
|
||||
.vs/
|
||||
.vs_code/
|
||||
**/.DS_Store
|
||||
|
||||
*/**/obj
|
||||
*/**/bin
|
||||
|
||||
DownKyi.sln.DotSettings.user
|
||||
86
DownKyi.Core/BiliApi/Bangumi/BangumiInfo.cs
Normal file
86
DownKyi.Core/BiliApi/Bangumi/BangumiInfo.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Console = DownKyi.Core.Utils.Debugging.Console;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi;
|
||||
|
||||
public static class BangumiInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 剧集基本信息(mediaId方式)
|
||||
/// </summary>
|
||||
/// <param name="mediaId"></param>
|
||||
/// <returns></returns>
|
||||
public static BangumiMedia BangumiMediaInfo(long mediaId)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/pgc/review/user?media_id={mediaId}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var media = JsonConvert.DeserializeObject<BangumiMediaOrigin>(response);
|
||||
if (media != null && media.Result != null)
|
||||
{
|
||||
return media.Result.Media;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("BangumiMediaInfo()发生异常: {0}", e);
|
||||
LogManager.Error("BangumiInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取剧集明细(web端)(seasonId/episodeId方式)
|
||||
/// </summary>
|
||||
/// <param name="seasonId"></param>
|
||||
/// <param name="episodeId"></param>
|
||||
/// <returns></returns>
|
||||
public static BangumiSeason BangumiSeasonInfo(long seasonId = -1, long episodeId = -1)
|
||||
{
|
||||
string baseUrl = "https://api.bilibili.com/pgc/view/web/season";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string url;
|
||||
if (seasonId > -1)
|
||||
{
|
||||
url = $"{baseUrl}?season_id={seasonId}";
|
||||
}
|
||||
else if (episodeId > -1)
|
||||
{
|
||||
url = $"{baseUrl}?ep_id={episodeId}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var bangumiSeason = JsonConvert.DeserializeObject<BangumiSeasonOrigin>(response);
|
||||
if (bangumiSeason != null)
|
||||
{
|
||||
return bangumiSeason.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("BangumiSeasonInfo()发生异常: {0}", e);
|
||||
LogManager.Error("BangumiInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
DownKyi.Core/BiliApi/Bangumi/BangumiType.cs
Normal file
32
DownKyi.Core/BiliApi/Bangumi/BangumiType.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace DownKyi.Core.BiliApi.Bangumi;
|
||||
|
||||
public static class BangumiType
|
||||
{
|
||||
public static Dictionary<int, string> Type = new Dictionary<int, string>()
|
||||
{
|
||||
{ 1, "Anime" },
|
||||
{ 2, "Movie" },
|
||||
{ 3, "Documentary" },
|
||||
{ 4, "Guochuang" },
|
||||
{ 5, "TV" },
|
||||
{ 6, "Unknown" },
|
||||
{ 7, "Entertainment" },
|
||||
{ 8, "Unknown" },
|
||||
{ 9, "Unknown" },
|
||||
{ 10, "Unknown" }
|
||||
};
|
||||
|
||||
public static Dictionary<int, int> TypeId = new Dictionary<int, int>()
|
||||
{
|
||||
{ 1, 13 },
|
||||
{ 2, 23 },
|
||||
{ 3, 177 },
|
||||
{ 4, 167 },
|
||||
{ 5, 11 },
|
||||
{ 6, -1 },
|
||||
{ 7, -1 },
|
||||
{ 8, -1 },
|
||||
{ 9, -1 },
|
||||
{ 10, -1 }
|
||||
};
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Bangumi/Models/BangumiArea.cs
Normal file
10
DownKyi.Core/BiliApi/Bangumi/Models/BangumiArea.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiArea : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public int Id { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
}
|
||||
39
DownKyi.Core/BiliApi/Bangumi/Models/BangumiEpisode.cs
Normal file
39
DownKyi.Core/BiliApi/Bangumi/Models/BangumiEpisode.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiEpisode : BaseModel
|
||||
{
|
||||
[JsonProperty("aid")] public long Aid { get; set; }
|
||||
|
||||
[JsonProperty("badge")] public string Badge { get; set; }
|
||||
|
||||
// badge_info
|
||||
// badge_type
|
||||
[JsonProperty("bvid")] public string Bvid { get; set; }
|
||||
[JsonProperty("cid")] public long Cid { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("dimension")] public Dimension Dimension { get; set; }
|
||||
[JsonProperty("duration")] public long Duration { get; set; }
|
||||
[JsonProperty("from")] public string From { get; set; }
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("link")] public string Link { get; set; }
|
||||
[JsonProperty("long_title")] public string LongTitle { get; set; }
|
||||
|
||||
[JsonProperty("pub_time")] public long PubTime { get; set; }
|
||||
|
||||
// pv
|
||||
// release_date
|
||||
// rights
|
||||
[JsonProperty("share_copy")] public string ShareCopy { get; set; }
|
||||
[JsonProperty("share_url")] public string ShareUrl { get; set; }
|
||||
|
||||
[JsonProperty("short_link")] public string ShortLink { get; set; }
|
||||
|
||||
// stat
|
||||
[JsonProperty("status")] public int Status { get; set; }
|
||||
[JsonProperty("subtitle")] public string Subtitle { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("vid")] public string Vid { get; set; }
|
||||
}
|
||||
36
DownKyi.Core/BiliApi/Bangumi/Models/BangumiMedia.cs
Normal file
36
DownKyi.Core/BiliApi/Bangumi/Models/BangumiMedia.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
// https://api.bilibili.com/pgc/review/user
|
||||
public class BangumiMediaOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("result")] public BangumiMediaData Result { get; set; }
|
||||
}
|
||||
|
||||
public class BangumiMediaData : BaseModel
|
||||
{
|
||||
[JsonProperty("media")] public BangumiMedia Media { get; set; }
|
||||
}
|
||||
|
||||
public class BangumiMedia : BaseModel
|
||||
{
|
||||
[JsonProperty("areas")] public List<BangumiArea> Areas { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
|
||||
[JsonProperty("media_id")] public long MediaId { get; set; }
|
||||
|
||||
// new_ep
|
||||
// rating
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
[JsonProperty("share_url")] public string ShareUrl { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("type_name")] public string TypeName { get; set; }
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Bangumi/Models/BangumiPositive.cs
Normal file
10
DownKyi.Core/BiliApi/Bangumi/Models/BangumiPositive.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiPositive : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
}
|
||||
65
DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeason.cs
Normal file
65
DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeason.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
// https://api.bilibili.com/pgc/view/web/season
|
||||
public class BangumiSeasonOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("result")] public BangumiSeason Result { get; set; }
|
||||
}
|
||||
|
||||
public class BangumiSeason : BaseModel
|
||||
{
|
||||
// activity
|
||||
// alias
|
||||
[JsonProperty("areas")] public List<BangumiArea> Areas { get; set; }
|
||||
[JsonProperty("bkg_cover")] public string BkgCover { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("episodes")] public List<BangumiEpisode> Episodes { get; set; }
|
||||
|
||||
[JsonProperty("evaluate")] public string Evaluate { get; set; }
|
||||
|
||||
// freya
|
||||
// jp_title
|
||||
[JsonProperty("link")] public string Link { get; set; }
|
||||
|
||||
[JsonProperty("media_id")] public long MediaId { get; set; }
|
||||
|
||||
// mode
|
||||
// new_ep
|
||||
// payment
|
||||
[JsonProperty("positive")] public BangumiPositive Positive { get; set; }
|
||||
|
||||
// publish
|
||||
// rating
|
||||
// record
|
||||
// rights
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
[JsonProperty("season_title")] public string SeasonTitle { get; set; }
|
||||
[JsonProperty("seasons")] public List<BangumiSeasonInfo> Seasons { get; set; }
|
||||
|
||||
[JsonProperty("section")] public List<BangumiSection> Section { get; set; }
|
||||
|
||||
// series
|
||||
// share_copy
|
||||
// share_sub_title
|
||||
// share_url
|
||||
// show
|
||||
[JsonProperty("square_cover")] public string SquareCover { get; set; }
|
||||
|
||||
[JsonProperty("stat")] public BangumiStat Stat { get; set; }
|
||||
|
||||
// status
|
||||
[JsonProperty("subtitle")] public string Subtitle { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("total")] public int Total { get; set; }
|
||||
[JsonProperty("type")] public int Type { get; set; }
|
||||
[JsonProperty("up_info")] public BangumiUpInfo UpInfo { get; set; }
|
||||
}
|
||||
22
DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeasonInfo.cs
Normal file
22
DownKyi.Core/BiliApi/Bangumi/Models/BangumiSeasonInfo.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiSeasonInfo : BaseModel
|
||||
{
|
||||
[JsonProperty("badge")] public string Badge { get; set; }
|
||||
|
||||
// badge_info
|
||||
// badge_type
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
|
||||
[JsonProperty("media_id")] public long MediaId { get; set; }
|
||||
|
||||
// new_ep
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
[JsonProperty("season_title")] public string SeasonTitle { get; set; }
|
||||
|
||||
[JsonProperty("season_type")] public int SeasonType { get; set; }
|
||||
// stat
|
||||
}
|
||||
13
DownKyi.Core/BiliApi/Bangumi/Models/BangumiSection.cs
Normal file
13
DownKyi.Core/BiliApi/Bangumi/Models/BangumiSection.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiSection : BaseModel
|
||||
{
|
||||
[JsonProperty("episode_id")] public long EpisodeId { get; set; }
|
||||
[JsonProperty("episodes")] public List<BangumiEpisode> Episodes { get; set; }
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("type")] public int Type { get; set; }
|
||||
}
|
||||
16
DownKyi.Core/BiliApi/Bangumi/Models/BangumiStat.cs
Normal file
16
DownKyi.Core/BiliApi/Bangumi/Models/BangumiStat.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiStat : BaseModel
|
||||
{
|
||||
[JsonProperty("coins")] public long Coins { get; set; }
|
||||
[JsonProperty("danmakus")] public long Danmakus { get; set; }
|
||||
[JsonProperty("favorite")] public long Favorite { get; set; }
|
||||
[JsonProperty("favorites")] public long Favorites { get; set; }
|
||||
[JsonProperty("likes")] public long Likes { get; set; }
|
||||
[JsonProperty("reply")] public long Reply { get; set; }
|
||||
[JsonProperty("share")] public long Share { get; set; }
|
||||
[JsonProperty("views")] public long Views { get; set; }
|
||||
}
|
||||
20
DownKyi.Core/BiliApi/Bangumi/Models/BangumiUpInfo.cs
Normal file
20
DownKyi.Core/BiliApi/Bangumi/Models/BangumiUpInfo.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Bangumi.Models;
|
||||
|
||||
public class BangumiUpInfo : BaseModel
|
||||
{
|
||||
[JsonProperty("avatar")] public string Avatar { get; set; }
|
||||
|
||||
// follower
|
||||
// is_follow
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
|
||||
// pendant
|
||||
// theme_type
|
||||
[JsonProperty("uname")] public string Name { get; set; }
|
||||
// verify_type
|
||||
// vip_status
|
||||
// vip_type
|
||||
}
|
||||
59
DownKyi.Core/BiliApi/BiliUtils/BvId.cs
Normal file
59
DownKyi.Core/BiliApi/BiliUtils/BvId.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
namespace DownKyi.Core.BiliApi.BiliUtils;
|
||||
|
||||
public static class BvId
|
||||
{
|
||||
private const string tableStr = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"; //码表
|
||||
private static readonly char[] table = tableStr.ToCharArray();
|
||||
|
||||
private static readonly char[] tr = new char[124]; //反查码表
|
||||
private const ulong Xor = 177451812; //固定异或值
|
||||
private const ulong add = 8728348608; //固定加法值
|
||||
private static readonly int[] s = { 11, 10, 3, 8, 4, 6 }; //位置编码表
|
||||
|
||||
static BvId()
|
||||
{
|
||||
Tr_init();
|
||||
}
|
||||
|
||||
//初始化反查码表
|
||||
private static void Tr_init()
|
||||
{
|
||||
for (int i = 0; i < 58; i++)
|
||||
tr[table[i]] = (char)i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// bvid转avid
|
||||
/// </summary>
|
||||
/// <param name="bvid"></param>
|
||||
/// <returns></returns>
|
||||
public static ulong Bv2Av(string bvid)
|
||||
{
|
||||
char[] bv = bvid.ToCharArray();
|
||||
|
||||
ulong r = 0;
|
||||
ulong av;
|
||||
for (int i = 0; i < 6; i++)
|
||||
r += tr[bv[s[i]]] * (ulong)Math.Pow(58, i);
|
||||
av = (r - add) ^ Xor;
|
||||
return av;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// avid转bvid
|
||||
/// </summary>
|
||||
/// <param name="av"></param>
|
||||
/// <returns></returns>
|
||||
public static string Av2Bv(ulong av)
|
||||
{
|
||||
//编码结果
|
||||
string res = "BV1 4 1 7 ";
|
||||
char[] result = res.ToCharArray();
|
||||
|
||||
av = (av ^ Xor) + add;
|
||||
for (int i = 0; i < 6; i++)
|
||||
result[s[i]] = table[av / (ulong)Math.Pow(58, i) % 58];
|
||||
string bv = new string(result);
|
||||
return bv;
|
||||
}
|
||||
}
|
||||
74
DownKyi.Core/BiliApi/BiliUtils/Constant.cs
Normal file
74
DownKyi.Core/BiliApi/BiliUtils/Constant.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
namespace DownKyi.Core.BiliApi.BiliUtils;
|
||||
|
||||
public static class Constant
|
||||
{
|
||||
private static readonly List<Quality> resolutions = new List<Quality>
|
||||
{
|
||||
new() { Name = "360P 流畅", Id = 16 },
|
||||
new() { Name = "480P 清晰", Id = 32 },
|
||||
new() { Name = "720P 高清", Id = 64 },
|
||||
new() { Name = "720P 60帧", Id = 74 },
|
||||
new() { Name = "1080P 高清", Id = 80 },
|
||||
new() { Name = "1080P 高码率", Id = 112 },
|
||||
new() { Name = "1080P 60帧", Id = 116 },
|
||||
new() { Name = "4K 超清", Id = 120 },
|
||||
new() { Name = "HDR 真彩", Id = 125 },
|
||||
new() { Name = "杜比视界", Id = 126 },
|
||||
new() { Name = "超高清 8K", Id = 127 },
|
||||
};
|
||||
|
||||
private static readonly List<Quality> codecIds = new List<Quality>
|
||||
{
|
||||
new() { Name = "H.264/AVC", Id = 7 },
|
||||
new() { Name = "H.265/HEVC", Id = 12 },
|
||||
new() { Name = "AV1", Id = 13 },
|
||||
};
|
||||
|
||||
private static readonly List<Quality> qualities = new List<Quality>
|
||||
{
|
||||
//new Quality { Name = "64K", Id = 30216 },
|
||||
//new Quality { Name = "132K", Id = 30232 },
|
||||
//new Quality { Name = "192K", Id = 30280 },
|
||||
new() { Name = "低质量", Id = 30216 },
|
||||
new() { Name = "中质量", Id = 30232 },
|
||||
new() { Name = "高质量", Id = 30280 },
|
||||
new() { Name = "Dolby Atmos", Id = 30250 },
|
||||
new() { Name = "Hi-Res无损", Id = 30251 },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获取支持的视频画质
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<Quality> GetResolutions()
|
||||
{
|
||||
// 使用深复制,
|
||||
// 保证外部修改list后,
|
||||
// 不会影响其他调用处
|
||||
return new List<Quality>(resolutions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取视频编码代码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<Quality> GetCodecIds()
|
||||
{
|
||||
// 使用深复制,
|
||||
// 保证外部修改list后,
|
||||
// 不会影响其他调用处
|
||||
return new List<Quality>(codecIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取支持的视频音质
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<Quality> GetAudioQualities()
|
||||
{
|
||||
// 使用深复制,
|
||||
// 保证外部修改list后,
|
||||
// 不会影响其他调用处
|
||||
return new List<Quality>(qualities);
|
||||
}
|
||||
}
|
||||
157
DownKyi.Core/BiliApi/BiliUtils/DanmakuSender.cs
Normal file
157
DownKyi.Core/BiliApi/BiliUtils/DanmakuSender.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
namespace DownKyi.Core.BiliApi.BiliUtils;
|
||||
|
||||
public static class DanmakuSender
|
||||
{
|
||||
private const uint CRCPOLYNOMIAL = 0xEDB88320;
|
||||
private static readonly uint[] crctable = new uint[256];
|
||||
|
||||
static DanmakuSender()
|
||||
{
|
||||
CreateTable();
|
||||
}
|
||||
|
||||
private static void CreateTable()
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
uint crcreg = (uint)i;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if ((crcreg & 1) != 0)
|
||||
{
|
||||
crcreg = CRCPOLYNOMIAL ^ (crcreg >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
crcreg >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
crctable[i] = crcreg;
|
||||
}
|
||||
}
|
||||
|
||||
private static uint Crc32(string userId)
|
||||
{
|
||||
uint crcstart = 0xFFFFFFFF;
|
||||
for (int i = 0; i < userId.Length; i++)
|
||||
{
|
||||
uint index = (uint)(crcstart ^ (int)userId[i]) & 255;
|
||||
crcstart = (crcstart >> 8) ^ crctable[index];
|
||||
}
|
||||
|
||||
return crcstart;
|
||||
}
|
||||
|
||||
private static uint Crc32LastIndex(string userId)
|
||||
{
|
||||
uint index = 0;
|
||||
uint crcstart = 0xFFFFFFFF;
|
||||
for (int i = 0; i < userId.Length; i++)
|
||||
{
|
||||
index = (uint)((crcstart ^ (int)userId[i]) & 255);
|
||||
crcstart = (crcstart >> 8) ^ crctable[index];
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
private static int GetCrcIndex(long t)
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
if ((crctable[i] >> 24) == t)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static object[] DeepCheck(int i, int[] index)
|
||||
{
|
||||
object[] resultArray = new object[2];
|
||||
|
||||
string result = "";
|
||||
uint tc; // = 0x00;
|
||||
var hashcode = Crc32(i.ToString());
|
||||
tc = (uint)(hashcode & 0xff ^ index[2]);
|
||||
|
||||
if (!(tc <= 57 && tc >= 48))
|
||||
{
|
||||
resultArray[0] = 0;
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
result += (tc - 48).ToString();
|
||||
hashcode = crctable[index[2]] ^ (hashcode >> 8);
|
||||
tc = (uint)(hashcode & 0xff ^ index[1]);
|
||||
|
||||
if (!(tc <= 57 && tc >= 48))
|
||||
{
|
||||
resultArray[0] = 0;
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
result += (tc - 48).ToString();
|
||||
hashcode = crctable[index[1]] ^ (hashcode >> 8);
|
||||
tc = (uint)(hashcode & 0xff ^ index[0]);
|
||||
|
||||
if (!(tc <= 57 && tc >= 48))
|
||||
{
|
||||
resultArray[0] = 0;
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
result += (tc - 48).ToString();
|
||||
//hashcode = crctable[index[0]] ^ (hashcode >> 8);
|
||||
|
||||
resultArray[0] = 1;
|
||||
resultArray[1] = result;
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询弹幕发送者
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
public static string FindDanmakuSender(string userId)
|
||||
{
|
||||
object[] deepCheckData = new object[2];
|
||||
|
||||
int[] index = new int[4];
|
||||
uint ht = (uint)Convert.ToInt32($"0x{userId}", 16);
|
||||
ht ^= 0xffffffff;
|
||||
|
||||
int i;
|
||||
for (i = 3; i > -1; i--)
|
||||
{
|
||||
index[3 - i] = GetCrcIndex(ht >> (i * 8));
|
||||
uint snum = crctable[index[3 - i]];
|
||||
ht ^= snum >> ((3 - i) * 8);
|
||||
}
|
||||
|
||||
for (i = 0; i < 100000000; i++)
|
||||
{
|
||||
uint lastindex = Crc32LastIndex(i.ToString());
|
||||
if (lastindex == index[3])
|
||||
{
|
||||
deepCheckData = DeepCheck(i, index);
|
||||
if ((int)deepCheckData[0] != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 100000000)
|
||||
{
|
||||
return "-1";
|
||||
}
|
||||
|
||||
return $"{i}{deepCheckData[1]}";
|
||||
}
|
||||
}
|
||||
575
DownKyi.Core/BiliApi/BiliUtils/ParseEntrance.cs
Normal file
575
DownKyi.Core/BiliApi/BiliUtils/ParseEntrance.cs
Normal file
@@ -0,0 +1,575 @@
|
||||
using DownKyi.Core.Utils.Validator;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.BiliUtils;
|
||||
|
||||
/// <summary>
|
||||
/// 解析输入的字符串<para/>
|
||||
/// 支持的格式有:<para/>
|
||||
/// av号:av170001, AV170001, https://www.bilibili.com/video/av170001 <para/>
|
||||
/// BV号:BV17x411w7KC, https://www.bilibili.com/video/BV17x411w7KC, https://b23.tv/BV17x411w7KC <para/>
|
||||
/// 番剧(电影、电视剧)ss号:ss32982, SS32982, https://www.bilibili.com/bangumi/play/ss32982 <para/>
|
||||
/// 番剧(电影、电视剧)ep号:ep317925, EP317925, https://www.bilibili.com/bangumi/play/ep317925 <para/>
|
||||
/// 番剧(电影、电视剧)md号:md28228367, MD28228367, https://www.bilibili.com/bangumi/media/md28228367 <para/>
|
||||
/// 课程ss号:https://www.bilibili.com/cheese/play/ss205 <para/>
|
||||
/// 课程ep号:https://www.bilibili.com/cheese/play/ep3489 <para/>
|
||||
/// 收藏夹:ml1329019876, ML1329019876, https://www.bilibili.com/medialist/detail/ml1329019876, https://www.bilibili.com/medialist/play/ml1329019876/ <para/>
|
||||
/// 用户空间:uid928123, UID928123, uid:928123, UID:928123, https://space.bilibili.com/928123
|
||||
/// </summary>
|
||||
public static class ParseEntrance
|
||||
{
|
||||
public static readonly string WwwUrl = "https://www.bilibili.com";
|
||||
public static readonly string ShareWwwUrl = "https://www.bilibili.com/s";
|
||||
public static readonly string ShortUrl = "https://b23.tv/";
|
||||
public static readonly string MobileUrl = "https://m.bilibili.com";
|
||||
|
||||
public static readonly string SpaceUrl = "https://space.bilibili.com";
|
||||
|
||||
public static readonly string VideoUrl = $"{WwwUrl}/video/";
|
||||
public static readonly string BangumiUrl = $"{WwwUrl}/bangumi/play/";
|
||||
public static readonly string BangumiMediaUrl = $"{WwwUrl}/bangumi/media/";
|
||||
public static readonly string CheeseUrl = $"{WwwUrl}/cheese/play/";
|
||||
public static readonly string FavoritesUrl1 = $"{WwwUrl}/medialist/detail/";
|
||||
public static readonly string FavoritesUrl2 = $"{WwwUrl}/medialist/play/";
|
||||
|
||||
#region 视频
|
||||
|
||||
/// <summary>
|
||||
/// 是否为av id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAvId(string input)
|
||||
{
|
||||
return IsIntId(input, "av");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为av url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAvUrl(string input)
|
||||
{
|
||||
string id = GetVideoId(input);
|
||||
return IsAvId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取av id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetAvId(string input)
|
||||
{
|
||||
if (IsAvId(input))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 2));
|
||||
}
|
||||
else if (IsAvUrl(input))
|
||||
{
|
||||
return Number.GetInt(GetVideoId(input).Remove(0, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为bv id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBvId(string input)
|
||||
{
|
||||
return input.StartsWith("BV") && input.Length == 12;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为bv url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBvUrl(string input)
|
||||
{
|
||||
string id = GetVideoId(input);
|
||||
return IsBvId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取bv id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetBvId(string input)
|
||||
{
|
||||
if (IsBvId(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
else if (IsBvUrl(input))
|
||||
{
|
||||
return GetVideoId(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 番剧(电影、电视剧)
|
||||
|
||||
/// <summary>
|
||||
/// 是否为番剧season id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBangumiSeasonId(string input)
|
||||
{
|
||||
return IsIntId(input, "ss");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为番剧season url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBangumiSeasonUrl(string input)
|
||||
{
|
||||
string id = GetBangumiId(input);
|
||||
return IsBangumiSeasonId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取番剧season id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetBangumiSeasonId(string input)
|
||||
{
|
||||
if (IsBangumiSeasonId(input))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 2));
|
||||
}
|
||||
else if (IsBangumiSeasonUrl(input))
|
||||
{
|
||||
return Number.GetInt(GetBangumiId(input).Remove(0, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为番剧episode id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBangumiEpisodeId(string input)
|
||||
{
|
||||
return IsIntId(input, "ep");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为番剧episode url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBangumiEpisodeUrl(string input)
|
||||
{
|
||||
string id = GetBangumiId(input);
|
||||
return IsBangumiEpisodeId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取番剧episode id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetBangumiEpisodeId(string input)
|
||||
{
|
||||
if (IsBangumiEpisodeId(input))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 2));
|
||||
}
|
||||
else if (IsBangumiEpisodeUrl(input))
|
||||
{
|
||||
return Number.GetInt(GetBangumiId(input).Remove(0, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为番剧media id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBangumiMediaId(string input)
|
||||
{
|
||||
return IsIntId(input, "md");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为番剧media url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBangumiMediaUrl(string input)
|
||||
{
|
||||
string id = GetBangumiId(input);
|
||||
return IsBangumiMediaId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取番剧media id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetBangumiMediaId(string input)
|
||||
{
|
||||
if (IsBangumiMediaId(input))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 2));
|
||||
}
|
||||
else if (IsBangumiMediaUrl(input))
|
||||
{
|
||||
return Number.GetInt(GetBangumiId(input).Remove(0, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 课程
|
||||
|
||||
/// <summary>
|
||||
/// 是否为课程season url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsCheeseSeasonUrl(string input)
|
||||
{
|
||||
string id = GetCheeseId(input);
|
||||
return IsIntId(id, "ss");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取课程season id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetCheeseSeasonId(string input)
|
||||
{
|
||||
return IsCheeseSeasonUrl(input) ? Number.GetInt(GetCheeseId(input).Remove(0, 2)) : -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为课程episode url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsCheeseEpisodeUrl(string input)
|
||||
{
|
||||
string id = GetCheeseId(input);
|
||||
return IsIntId(id, "ep");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取课程episode id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetCheeseEpisodeId(string input)
|
||||
{
|
||||
return IsCheeseEpisodeUrl(input) ? Number.GetInt(GetCheeseId(input).Remove(0, 2)) : -1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 收藏夹
|
||||
|
||||
/// <summary>
|
||||
/// 是否为收藏夹id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsFavoritesId(string input)
|
||||
{
|
||||
return IsIntId(input, "ml");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为收藏夹url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsFavoritesUrl(string input)
|
||||
{
|
||||
return IsFavoritesUrl1(input) || IsFavoritesUrl2(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为收藏夹url1
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsFavoritesUrl1(string input)
|
||||
{
|
||||
string favoritesId = GetId(input, FavoritesUrl1);
|
||||
return IsFavoritesId(favoritesId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为收藏夹ur2
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsFavoritesUrl2(string input)
|
||||
{
|
||||
string favoritesId = GetId(input, FavoritesUrl2);
|
||||
return IsFavoritesId(favoritesId.Split('/')[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取收藏夹id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetFavoritesId(string input)
|
||||
{
|
||||
if (IsFavoritesId(input))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 2));
|
||||
}
|
||||
else if (IsFavoritesUrl1(input))
|
||||
{
|
||||
return Number.GetInt(GetId(input, FavoritesUrl1).Remove(0, 2));
|
||||
}
|
||||
else if (IsFavoritesUrl2(input))
|
||||
{
|
||||
return Number.GetInt(GetId(input, FavoritesUrl2).Remove(0, 2).Split('/')[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 用户空间
|
||||
|
||||
/// <summary>
|
||||
/// 是否为用户id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsUserId(string input)
|
||||
{
|
||||
if (input.ToLower().StartsWith("uid:"))
|
||||
{
|
||||
return Regex.IsMatch(input.Remove(0, 4), @"^\d+$");
|
||||
}
|
||||
else if (input.ToLower().StartsWith("uid"))
|
||||
{
|
||||
return Regex.IsMatch(input.Remove(0, 3), @"^\d+$");
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为用户空间url
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsUserUrl(string input)
|
||||
{
|
||||
if (!IsUrl(input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input.Contains("space.bilibili.com"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户mid
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetUserId(string input)
|
||||
{
|
||||
if (input.ToLower().StartsWith("uid:"))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 4));
|
||||
}
|
||||
else if (input.ToLower().StartsWith("uid"))
|
||||
{
|
||||
return Number.GetInt(input.Remove(0, 3));
|
||||
}
|
||||
else if (IsUserUrl(input))
|
||||
{
|
||||
string url = EnableHttps(input);
|
||||
url = DeleteUrlParam(url);
|
||||
var match = Regex.Match(url, @"\d+");
|
||||
if (match.Success)
|
||||
{
|
||||
return long.Parse(match.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 是否为网址
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsUrl(string input)
|
||||
{
|
||||
return input.StartsWith("http://") || input.StartsWith("https://");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将http转为https
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string EnableHttps(string url)
|
||||
{
|
||||
if (!IsUrl(url))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return url.Replace("http://", "https://");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 去除url中的参数
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
private static string DeleteUrlParam(string url)
|
||||
{
|
||||
string[] strList = url.Split('?');
|
||||
|
||||
return strList[0].EndsWith("/") ? strList[0].TrimEnd('/') : strList[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从url中获取视频id(avid/bvid)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetVideoId(string input)
|
||||
{
|
||||
return GetId(input, VideoUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从url中获取番剧id(ss/ep/md)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetBangumiId(string input)
|
||||
{
|
||||
string id = GetId(input, BangumiUrl);
|
||||
if (id != "")
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
return GetId(input, BangumiMediaUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从url中获取课程id(ss/ep)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetCheeseId(string input)
|
||||
{
|
||||
return GetId(input, CheeseUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为数字型id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="prefix"></param>
|
||||
/// <returns></returns>
|
||||
private static bool IsIntId(string input, string prefix)
|
||||
{
|
||||
if (input.ToLower().StartsWith(prefix))
|
||||
{
|
||||
return Regex.IsMatch(input.Remove(0, 2), @"^\d+$");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从url中获取id
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="baseUrl"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetId(string input, string baseUrl)
|
||||
{
|
||||
if (!IsUrl(input))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string url = EnableHttps(input);
|
||||
url = DeleteUrlParam(url);
|
||||
|
||||
url = url.Replace(ShareWwwUrl, WwwUrl);
|
||||
url = url.Replace(MobileUrl, WwwUrl);
|
||||
|
||||
if (url.Contains("b23.tv/ss") || url.Contains("b23.tv/ep"))
|
||||
{
|
||||
url = url.Replace(ShortUrl, BangumiUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
url = url.Replace(ShortUrl, VideoUrl);
|
||||
}
|
||||
|
||||
if (!url.StartsWith(baseUrl))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return url.Replace(baseUrl, "");
|
||||
}
|
||||
}
|
||||
8
DownKyi.Core/BiliApi/BiliUtils/Quality.cs
Normal file
8
DownKyi.Core/BiliApi/BiliUtils/Quality.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace DownKyi.Core.BiliApi.BiliUtils;
|
||||
|
||||
[Serializable]
|
||||
public class Quality
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Id { get; set; }
|
||||
}
|
||||
21
DownKyi.Core/BiliApi/BilibiliImages.axaml
Normal file
21
DownKyi.Core/BiliApi/BilibiliImages.axaml
Normal file
File diff suppressed because one or more lines are too long
88
DownKyi.Core/BiliApi/Cheese/CheeseInfo.cs
Normal file
88
DownKyi.Core/BiliApi/Cheese/CheeseInfo.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using DownKyi.Core.BiliApi.Cheese.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Console = DownKyi.Core.Utils.Debugging.Console;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese;
|
||||
|
||||
public static class CheeseInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取课程基本信息
|
||||
/// </summary>
|
||||
/// <param name="seasonId"></param>
|
||||
/// <param name="episodeId"></param>
|
||||
/// <returns></returns>
|
||||
public static CheeseView CheeseViewInfo(long seasonId = -1, long episodeId = -1)
|
||||
{
|
||||
string baseUrl = "https://api.bilibili.com/pugv/view/web/season";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string url;
|
||||
if (seasonId > -1)
|
||||
{
|
||||
url = $"{baseUrl}?season_id={seasonId}";
|
||||
}
|
||||
else if (episodeId > -1)
|
||||
{
|
||||
url = $"{baseUrl}?ep_id={episodeId}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
CheeseViewOrigin cheese = JsonConvert.DeserializeObject<CheeseViewOrigin>(response);
|
||||
if (cheese != null)
|
||||
{
|
||||
return cheese.Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("CheeseViewInfo()发生异常: {0}", e);
|
||||
LogManager.Error("CheeseInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取课程分集列表
|
||||
/// </summary>
|
||||
/// <param name="seasonId"></param>
|
||||
/// <param name="ps"></param>
|
||||
/// <param name="pn"></param>
|
||||
/// <returns></returns>
|
||||
public static CheeseEpisodeList CheeseEpisodeList(long seasonId, int ps = 50, int pn = 1)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/pugv/view/web/ep/list?season_id={seasonId}&pn={pn}&ps={ps}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
CheeseEpisodeListOrigin cheese = JsonConvert.DeserializeObject<CheeseEpisodeListOrigin>(response);
|
||||
if (cheese != null)
|
||||
{
|
||||
return cheese.Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("CheeseEpisodeList()发生异常: {0}", e);
|
||||
LogManager.Error("CheeseInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
DownKyi.Core/BiliApi/Cheese/Models/CheeseBrief.cs
Normal file
12
DownKyi.Core/BiliApi/Cheese/Models/CheeseBrief.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
public class CheeseBrief : BaseModel
|
||||
{
|
||||
// content
|
||||
[JsonProperty("img")] public List<CheeseImg> Img { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("type")] public int Type { get; set; }
|
||||
}
|
||||
25
DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisode.cs
Normal file
25
DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisode.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
public class CheeseEpisode : BaseModel
|
||||
{
|
||||
[JsonProperty("aid")] public long Aid { get; set; }
|
||||
[JsonProperty("catalogue_index")] public int CatalogueIndex { get; set; }
|
||||
[JsonProperty("cid")] public long Cid { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("duration")] public long Duration { get; set; }
|
||||
[JsonProperty("from")] public string From { get; set; }
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("index")] public int Index { get; set; }
|
||||
[JsonProperty("page")] public int Page { get; set; }
|
||||
[JsonProperty("play")] public long Play { get; set; }
|
||||
[JsonProperty("play_way")] public int PlayWay { get; set; }
|
||||
[JsonProperty("play_way_format")] public string PlayWayFormat { get; set; }
|
||||
[JsonProperty("release_date")] public long ReleaseDate { get; set; }
|
||||
[JsonProperty("status")] public int Status { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("watched")] public bool Watched { get; set; }
|
||||
[JsonProperty("watchedHistory")] public int WatchedHistory { get; set; }
|
||||
}
|
||||
20
DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodeList.cs
Normal file
20
DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodeList.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
// https://api.bilibili.com/pugv/view/web/ep/list
|
||||
public class CheeseEpisodeListOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
[JsonProperty("data")] public CheeseEpisodeList Data { get; set; }
|
||||
}
|
||||
|
||||
public class CheeseEpisodeList : BaseModel
|
||||
{
|
||||
[JsonProperty("items")] public List<CheeseEpisode> Items { get; set; }
|
||||
[JsonProperty("page")] public CheeseEpisodePage Page { get; set; }
|
||||
}
|
||||
12
DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodePage.cs
Normal file
12
DownKyi.Core/BiliApi/Cheese/Models/CheeseEpisodePage.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
public class CheeseEpisodePage : BaseModel
|
||||
{
|
||||
[JsonProperty("next")] public bool Next { get; set; }
|
||||
[JsonProperty("num")] public int Num { get; set; }
|
||||
[JsonProperty("size")] public int Size { get; set; }
|
||||
[JsonProperty("total")] public int Total { get; set; }
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Cheese/Models/CheeseImg.cs
Normal file
10
DownKyi.Core/BiliApi/Cheese/Models/CheeseImg.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
public class CheeseImg : BaseModel
|
||||
{
|
||||
[JsonProperty("aspect_ratio")] public double AspectRatio { get; set; }
|
||||
[JsonProperty("url")] public string Url { get; set; }
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Cheese/Models/CheeseStat.cs
Normal file
10
DownKyi.Core/BiliApi/Cheese/Models/CheeseStat.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
public class CheeseStat : BaseModel
|
||||
{
|
||||
[JsonProperty("play")] public long Play { get; set; }
|
||||
[JsonProperty("play_desc")] public string PlayDesc { get; set; }
|
||||
}
|
||||
15
DownKyi.Core/BiliApi/Cheese/Models/CheeseUpInfo.cs
Normal file
15
DownKyi.Core/BiliApi/Cheese/Models/CheeseUpInfo.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
public class CheeseUpInfo : BaseModel
|
||||
{
|
||||
[JsonProperty("avatar")] public string Avatar { get; set; }
|
||||
[JsonProperty("brief")] public string Brief { get; set; }
|
||||
[JsonProperty("follower")] public long Follower { get; set; }
|
||||
[JsonProperty("is_follow")] public int IsFollow { get; set; }
|
||||
[JsonProperty("link")] public string Link { get; set; }
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("uname")] public string Name { get; set; }
|
||||
}
|
||||
63
DownKyi.Core/BiliApi/Cheese/Models/CheeseView.cs
Normal file
63
DownKyi.Core/BiliApi/Cheese/Models/CheeseView.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Cheese.Models;
|
||||
|
||||
// https://api.bilibili.com/pugv/view/web/season
|
||||
public class CheeseViewOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
[JsonProperty("data")] public CheeseView Data { get; set; }
|
||||
}
|
||||
|
||||
public class CheeseView : BaseModel
|
||||
{
|
||||
// active_market
|
||||
// activity_list
|
||||
[JsonProperty("brief")] public CheeseBrief Brief { get; set; }
|
||||
|
||||
// cooperation
|
||||
// coupon
|
||||
// course_content
|
||||
// courses
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
|
||||
// ep_catalogue
|
||||
// ep_count
|
||||
// episode_page
|
||||
// episode_sort
|
||||
// episode_tag
|
||||
[JsonProperty("episodes")] public List<CheeseEpisode> Episodes { get; set; }
|
||||
|
||||
// faq
|
||||
// faq1
|
||||
// live_ep_count
|
||||
// opened_ep_count
|
||||
// payment
|
||||
// previewed_purchase_note
|
||||
// purchase_format_note
|
||||
// purchase_note
|
||||
// purchase_protocol
|
||||
// recommend_seasons 推荐课程
|
||||
// release_bottom_info
|
||||
// release_info
|
||||
// release_info2
|
||||
// release_status
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
|
||||
[JsonProperty("share_url")] public string ShareUrl { get; set; }
|
||||
|
||||
// short_link
|
||||
[JsonProperty("stat")] public CheeseStat Stat { get; set; }
|
||||
|
||||
// status
|
||||
[JsonProperty("subtitle")] public string Subtitle { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
|
||||
[JsonProperty("up_info")] public CheeseUpInfo UpInfo { get; set; }
|
||||
// update_status
|
||||
// user_status
|
||||
}
|
||||
107
DownKyi.Core/BiliApi/Danmaku/DanmakuProtobuf.cs
Normal file
107
DownKyi.Core/BiliApi/Danmaku/DanmakuProtobuf.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using Bilibili.Community.Service.Dm.V1;
|
||||
using DownKyi.Core.BiliApi.Danmaku.Models;
|
||||
using DownKyi.Core.Storage;
|
||||
using Console = DownKyi.Core.Utils.Debugging.Console;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Danmaku;
|
||||
|
||||
public static class DanmakuProtobuf
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载6分钟内的弹幕,返回弹幕列表
|
||||
/// </summary>
|
||||
/// <param name="avid">稿件avID</param>
|
||||
/// <param name="cid">视频CID</param>
|
||||
/// <param name="segmentIndex">分包,每6分钟一包</param>
|
||||
/// <returns></returns>
|
||||
public static List<BiliDanmaku> GetDanmakuProto(long avid, long cid, int segmentIndex)
|
||||
{
|
||||
string url =
|
||||
$"https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid={cid}&pid={avid}&segment_index={segmentIndex}";
|
||||
//string referer = "https://www.bilibili.com";
|
||||
|
||||
string directory = Path.Combine(StorageManager.GetDanmaku(), $"{cid}");
|
||||
string filePath = Path.Combine(directory, $"{segmentIndex}.proto");
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
System.Net.WebClient mywebclient = new System.Net.WebClient();
|
||||
mywebclient.DownloadFile(url, filePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("GetDanmakuProto()发生异常: {0}", e);
|
||||
//Logging.LogManager.Error(e);
|
||||
}
|
||||
|
||||
var danmakuList = new List<BiliDanmaku>();
|
||||
try
|
||||
{
|
||||
using (var input = File.OpenRead(filePath))
|
||||
{
|
||||
DmSegMobileReply danmakus = DmSegMobileReply.Parser.ParseFrom(input);
|
||||
if (danmakus == null || danmakus.Elems == null)
|
||||
{
|
||||
return danmakuList;
|
||||
}
|
||||
|
||||
foreach (var dm in danmakus.Elems)
|
||||
{
|
||||
var danmaku = new BiliDanmaku
|
||||
{
|
||||
Id = dm.Id,
|
||||
Progress = dm.Progress,
|
||||
Mode = dm.Mode,
|
||||
Fontsize = dm.Fontsize,
|
||||
Color = dm.Color,
|
||||
MidHash = dm.MidHash,
|
||||
Content = dm.Content,
|
||||
Ctime = dm.Ctime,
|
||||
Weight = dm.Weight,
|
||||
//Action = dm.Action,
|
||||
Pool = dm.Pool
|
||||
};
|
||||
danmakuList.Add(danmaku);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("GetDanmakuProto()发生异常: {0}", e);
|
||||
//Logging.LogManager.Error(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return danmakuList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载所有弹幕,返回弹幕列表
|
||||
/// </summary>
|
||||
/// <param name="avid">稿件avID</param>
|
||||
/// <param name="cid">视频CID</param>
|
||||
/// <returns></returns>
|
||||
public static List<BiliDanmaku> GetAllDanmakuProto(long avid, long cid)
|
||||
{
|
||||
var danmakuList = new List<BiliDanmaku>();
|
||||
|
||||
int segmentIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
segmentIndex += 1;
|
||||
var danmakus = GetDanmakuProto(avid, cid, segmentIndex);
|
||||
if (danmakus == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
danmakuList.AddRange(danmakus);
|
||||
}
|
||||
|
||||
return danmakuList;
|
||||
}
|
||||
}
|
||||
34
DownKyi.Core/BiliApi/Danmaku/Models/BiliDanmaku.cs
Normal file
34
DownKyi.Core/BiliApi/Danmaku/Models/BiliDanmaku.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace DownKyi.Core.BiliApi.Danmaku.Models;
|
||||
|
||||
public class BiliDanmaku
|
||||
{
|
||||
public long Id { get; set; } //弹幕dmID
|
||||
public int Progress { get; set; } //出现时间
|
||||
public int Mode { get; set; } //弹幕类型
|
||||
public int Fontsize { get; set; } //文字大小
|
||||
public uint Color { get; set; } //弹幕颜色
|
||||
public string MidHash { get; set; } //发送者UID的HASH
|
||||
public string Content { get; set; } //弹幕内容
|
||||
public long Ctime { get; set; } //发送时间
|
||||
|
||||
public int Weight { get; set; } //权重
|
||||
|
||||
//public string Action { get; set; } //动作?
|
||||
public int Pool { get; set; } //弹幕池
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string separator = "\n";
|
||||
return $"id: {Id}{separator}" +
|
||||
$"progress: {Progress}{separator}" +
|
||||
$"mode: {Mode}{separator}" +
|
||||
$"fontsize: {Fontsize}{separator}" +
|
||||
$"color: {Color}{separator}" +
|
||||
$"midHash: {MidHash}{separator}" +
|
||||
$"content: {Content}{separator}" +
|
||||
$"ctime: {Ctime}{separator}" +
|
||||
$"weight: {Weight}{separator}" +
|
||||
//$"action: {Action}{separator}" +
|
||||
$"pool: {Pool}";
|
||||
}
|
||||
}
|
||||
155
DownKyi.Core/BiliApi/Favorites/FavoritesInfo.cs
Normal file
155
DownKyi.Core/BiliApi/Favorites/FavoritesInfo.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using DownKyi.Core.BiliApi.Favorites.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Console = DownKyi.Core.Utils.Debugging.Console;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites;
|
||||
|
||||
public static class FavoritesInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取收藏夹元数据
|
||||
/// </summary>
|
||||
/// <param name="mediaId"></param>
|
||||
public static FavoritesMetaInfo GetFavoritesInfo(long mediaId)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/x/v3/fav/folder/info?media_id={mediaId}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var info = JsonConvert.DeserializeObject<FavoritesMetaInfoOrigin>(response);
|
||||
if (info != null)
|
||||
{
|
||||
return info.Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("GetFavoritesInfo()发生异常: {0}", e);
|
||||
LogManager.Error("FavoritesInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询用户创建的视频收藏夹
|
||||
/// </summary>
|
||||
/// <param name="mid">目标用户UID</param>
|
||||
/// <param name="pn">页码</param>
|
||||
/// <param name="ps">每页项数</param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMetaInfo> GetCreatedFavorites(long mid, int pn, int ps)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/x/v3/fav/folder/created/list?up_mid={mid}&pn={pn}&ps={ps}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var favorites = JsonConvert.DeserializeObject<FavoritesListOrigin>(response);
|
||||
if (favorites == null || favorites.Data == null || favorites.Data.List == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return favorites.Data.List;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("GetCreatedFavorites()发生异常: {0}", e);
|
||||
LogManager.Error("FavoritesInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询所有的用户创建的视频收藏夹
|
||||
/// </summary>
|
||||
/// <param name="mid">目标用户UID</param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMetaInfo> GetAllCreatedFavorites(long mid)
|
||||
{
|
||||
List<FavoritesMetaInfo> result = new List<FavoritesMetaInfo>();
|
||||
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
i++;
|
||||
int ps = 50;
|
||||
|
||||
var data = GetCreatedFavorites(mid, i, ps);
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
result.AddRange(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询用户收藏的视频收藏夹
|
||||
/// </summary>
|
||||
/// <param name="mid">目标用户UID</param>
|
||||
/// <param name="pn">页码</param>
|
||||
/// <param name="ps">每页项数</param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMetaInfo> GetCollectedFavorites(long mid, int pn, int ps)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/x/v3/fav/folder/collected/list?up_mid={mid}&pn={pn}&ps={ps}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var favorites = JsonConvert.DeserializeObject<FavoritesListOrigin>(response);
|
||||
if (favorites == null || favorites.Data == null || favorites.Data.List == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return favorites.Data.List;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("GetCollectedFavorites()发生异常: {0}", e);
|
||||
LogManager.Error("FavoritesInfo", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询所有的用户收藏的视频收藏夹
|
||||
/// </summary>
|
||||
/// <param name="mid">目标用户UID</param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMetaInfo> GetAllCollectedFavorites(long mid)
|
||||
{
|
||||
List<FavoritesMetaInfo> result = new List<FavoritesMetaInfo>();
|
||||
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
i++;
|
||||
int ps = 50;
|
||||
|
||||
var data = GetCollectedFavorites(mid, i, ps);
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
result.AddRange(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
96
DownKyi.Core/BiliApi/Favorites/FavoritesResource.cs
Normal file
96
DownKyi.Core/BiliApi/Favorites/FavoritesResource.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using DownKyi.Core.BiliApi.Favorites.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites;
|
||||
|
||||
public static class FavoritesResource
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取收藏夹内容明细列表
|
||||
/// </summary>
|
||||
/// <param name="mediaId">收藏夹ID</param>
|
||||
/// <param name="pn">页码</param>
|
||||
/// <param name="ps">每页项数</param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMedia> GetFavoritesMedia(long mediaId, int pn, int ps)
|
||||
{
|
||||
string url =
|
||||
$"https://api.bilibili.com/x/v3/fav/resource/list?media_id={mediaId}&pn={pn}&ps={ps}&platform=web";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var resource = JsonConvert.DeserializeObject<FavoritesMediaResourceOrigin>(response);
|
||||
if (resource == null || resource.Data == null || resource.Data.Medias == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return resource.Data.Medias;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("GetFavoritesMedia()发生异常: {0}", e);
|
||||
LogManager.Error("FavoritesResource", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取收藏夹内容明细列表(全部)
|
||||
/// </summary>
|
||||
/// <param name="mediaId">收藏夹ID</param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMedia> GetAllFavoritesMedia(long mediaId)
|
||||
{
|
||||
List<FavoritesMedia> result = new List<FavoritesMedia>();
|
||||
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
i++;
|
||||
int ps = 20;
|
||||
|
||||
var data = GetFavoritesMedia(mediaId, i, ps);
|
||||
if (data == null || data.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
result.AddRange(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取收藏夹全部内容id
|
||||
/// </summary>
|
||||
/// <param name="mediaId"></param>
|
||||
/// <returns></returns>
|
||||
public static List<FavoritesMediaId> GetFavoritesMediaId(long mediaId)
|
||||
{
|
||||
string url = $"https://api.bilibili.com/x/v3/fav/resource/ids?media_id={mediaId}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var media = JsonConvert.DeserializeObject<FavoritesMediaIdOrigin>(response);
|
||||
if (media == null || media.Data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return media.Data;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("GetFavoritesMediaId()发生异常: {0}", e);
|
||||
LogManager.Error("FavoritesResource", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
DownKyi.Core/BiliApi/Favorites/Models/FavStatus.cs
Normal file
12
DownKyi.Core/BiliApi/Favorites/Models/FavStatus.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
public class FavStatus : BaseModel
|
||||
{
|
||||
[JsonProperty("collect")] public long Collect { get; set; }
|
||||
[JsonProperty("play")] public long Play { get; set; }
|
||||
[JsonProperty("thumb_up")] public long ThumbUp { get; set; }
|
||||
[JsonProperty("share")] public long Share { get; set; }
|
||||
}
|
||||
15
DownKyi.Core/BiliApi/Favorites/Models/FavUpper.cs
Normal file
15
DownKyi.Core/BiliApi/Favorites/Models/FavUpper.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
public class FavUpper : BaseModel
|
||||
{
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("face")] public string Face { get; set; }
|
||||
|
||||
[JsonProperty("followed")] public bool Followed { get; set; }
|
||||
// vip_type
|
||||
// vip_statue
|
||||
}
|
||||
25
DownKyi.Core/BiliApi/Favorites/Models/FavoritesList.cs
Normal file
25
DownKyi.Core/BiliApi/Favorites/Models/FavoritesList.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
// https://api.bilibili.com/x/v3/fav/folder/collected/list
|
||||
public class FavoritesListOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public FavoritesList Data { get; set; }
|
||||
}
|
||||
|
||||
public class FavoritesList : BaseModel
|
||||
{
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
|
||||
[JsonProperty("list")] public List<FavoritesMetaInfo> List { get; set; }
|
||||
//[JsonProperty("has_more")]
|
||||
//public bool HasMore { get; set; }
|
||||
}
|
||||
30
DownKyi.Core/BiliApi/Favorites/Models/FavoritesMedia.cs
Normal file
30
DownKyi.Core/BiliApi/Favorites/Models/FavoritesMedia.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
public class FavoritesMedia : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("type")] public int Type { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("intro")] public string Intro { get; set; }
|
||||
[JsonProperty("page")] public int Page { get; set; }
|
||||
[JsonProperty("duration")] public long Duration { get; set; }
|
||||
|
||||
[JsonProperty("upper")] public FavUpper Upper { get; set; }
|
||||
|
||||
// attr
|
||||
[JsonProperty("cnt_info")] public MediaStatus CntInfo { get; set; }
|
||||
[JsonProperty("link")] public string Link { get; set; }
|
||||
[JsonProperty("ctime")] public long Ctime { get; set; }
|
||||
[JsonProperty("pubtime")] public long Pubtime { get; set; }
|
||||
[JsonProperty("fav_time")] public long FavTime { get; set; }
|
||||
[JsonProperty("bv_id")] public string BvId { get; set; }
|
||||
|
||||
[JsonProperty("bvid")] public string Bvid { get; set; }
|
||||
// season
|
||||
// ogv
|
||||
// ugc
|
||||
}
|
||||
24
DownKyi.Core/BiliApi/Favorites/Models/FavoritesMediaId.cs
Normal file
24
DownKyi.Core/BiliApi/Favorites/Models/FavoritesMediaId.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
// https://api.bilibili.com/x/v3/fav/resource/ids
|
||||
public class FavoritesMediaIdOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public List<FavoritesMediaId> Data { get; set; }
|
||||
}
|
||||
|
||||
public class FavoritesMediaId : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("type")] public int Type { get; set; }
|
||||
[JsonProperty("bv_id")] public string BvId { get; set; }
|
||||
[JsonProperty("bvid")] public string Bvid { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
// https://api.bilibili.com/x/v3/fav/resource/list
|
||||
public class FavoritesMediaResourceOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public FavoritesMediaResource Data { get; set; }
|
||||
}
|
||||
|
||||
public class FavoritesMediaResource : BaseModel
|
||||
{
|
||||
[JsonProperty("info")] public FavoritesMetaInfo Info { get; set; }
|
||||
[JsonProperty("medias")] public List<FavoritesMedia> Medias { get; set; }
|
||||
[JsonProperty("has_more")] public bool HasMore { get; set; }
|
||||
}
|
||||
44
DownKyi.Core/BiliApi/Favorites/Models/FavoritesMetaInfo.cs
Normal file
44
DownKyi.Core/BiliApi/Favorites/Models/FavoritesMetaInfo.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
// https://api.bilibili.com/x/v3/fav/folder/info
|
||||
public class FavoritesMetaInfoOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public FavoritesMetaInfo Data { get; set; }
|
||||
}
|
||||
|
||||
public class FavoritesMetaInfo : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("fid")] public long Fid { get; set; }
|
||||
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
|
||||
// attr
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
|
||||
[JsonProperty("upper")] public FavUpper Upper { get; set; }
|
||||
|
||||
// cover_type
|
||||
[JsonProperty("cnt_info")] public FavStatus CntInfo { get; set; }
|
||||
|
||||
// type
|
||||
[JsonProperty("intro")] public string Intro { get; set; }
|
||||
[JsonProperty("ctime")] public long Ctime { get; set; }
|
||||
|
||||
[JsonProperty("mtime")] public long Mtime { get; set; }
|
||||
|
||||
// state
|
||||
[JsonProperty("fav_state")] public int FavState { get; set; }
|
||||
[JsonProperty("like_state")] public int LikeState { get; set; }
|
||||
[JsonProperty("media_count")] public int MediaCount { get; set; }
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/Favorites/Models/MediaStatus.cs
Normal file
11
DownKyi.Core/BiliApi/Favorites/Models/MediaStatus.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Favorites.Models;
|
||||
|
||||
public class MediaStatus : BaseModel
|
||||
{
|
||||
[JsonProperty("collect")] public long Collect { get; set; }
|
||||
[JsonProperty("play")] public long Play { get; set; }
|
||||
[JsonProperty("danmaku")] public long Danmaku { get; set; }
|
||||
}
|
||||
63
DownKyi.Core/BiliApi/History/History.cs
Normal file
63
DownKyi.Core/BiliApi/History/History.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using DownKyi.Core.BiliApi.History.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History
|
||||
{
|
||||
/// <summary>
|
||||
/// 历史记录
|
||||
/// </summary>
|
||||
public static class History
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取历史记录列表(视频、直播、专栏)
|
||||
/// startId和startTime必须同时使用才有效,分别对应结果中的max和view_at,默认为0
|
||||
/// </summary>
|
||||
/// <param name="startId">历史记录开始目标ID</param>
|
||||
/// <param name="startTime">历史记录开始时间</param>
|
||||
/// <param name="ps">每页项数</param>
|
||||
/// <param name="business">历史记录ID类型</param>
|
||||
/// <returns></returns>
|
||||
public static HistoryData GetHistory(long startId, long startTime, int ps = 30, HistoryBusiness business = HistoryBusiness.ARCHIVE)
|
||||
{
|
||||
string businessStr = string.Empty;
|
||||
switch (business)
|
||||
{
|
||||
case HistoryBusiness.ARCHIVE:
|
||||
businessStr = "archive";
|
||||
break;
|
||||
case HistoryBusiness.PGC:
|
||||
businessStr = "pgc";
|
||||
break;
|
||||
case HistoryBusiness.LIVE:
|
||||
businessStr = "live";
|
||||
break;
|
||||
case HistoryBusiness.ARTICLE_LIST:
|
||||
businessStr = "article-list";
|
||||
break;
|
||||
case HistoryBusiness.ARTICLE:
|
||||
businessStr = "article";
|
||||
break;
|
||||
}
|
||||
|
||||
string url = $"https://api.bilibili.com/x/web-interface/history/cursor?max={startId}&view_at={startTime}&ps={ps}&business={businessStr}";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var history = JsonConvert.DeserializeObject<HistoryOrigin>(response);
|
||||
if (history == null || history.Data == null) { return null; }
|
||||
return history.Data;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Debugging.Console.PrintLine("GetHistory()发生异常: {0}", e);
|
||||
LogManager.Error("History", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/History/Models/HistoryBusiness.cs
Normal file
11
DownKyi.Core/BiliApi/History/Models/HistoryBusiness.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
public enum HistoryBusiness
|
||||
{
|
||||
ARCHIVE = 1, // 稿件
|
||||
PGC, // 番剧(影视)
|
||||
LIVE, // 直播
|
||||
ARTICLE_LIST, // 文集
|
||||
ARTICLE, // 文章
|
||||
}
|
||||
}
|
||||
17
DownKyi.Core/BiliApi/History/Models/HistoryCursor.cs
Normal file
17
DownKyi.Core/BiliApi/History/Models/HistoryCursor.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
public class HistoryCursor : BaseModel
|
||||
{
|
||||
[JsonProperty("max")]
|
||||
public long Max { get; set; }
|
||||
[JsonProperty("view_at")]
|
||||
public long ViewAt { get; set; }
|
||||
[JsonProperty("business")]
|
||||
public string Business { get; set; }
|
||||
[JsonProperty("ps")]
|
||||
public int Ps { get; set; }
|
||||
}
|
||||
}
|
||||
28
DownKyi.Core/BiliApi/History/Models/HistoryData.cs
Normal file
28
DownKyi.Core/BiliApi/History/Models/HistoryData.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
// https://api.bilibili.com/x/web-interface/history/cursor?max={startId}&view_at={startTime}&ps={ps}&business={businessStr}
|
||||
public class HistoryOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")]
|
||||
public HistoryData Data { get; set; }
|
||||
}
|
||||
|
||||
public class HistoryData : BaseModel
|
||||
{
|
||||
[JsonProperty("cursor")]
|
||||
public HistoryCursor Cursor { get; set; }
|
||||
//public List<HistoryDataTab> tab { get; set; }
|
||||
[JsonProperty("list")]
|
||||
public List<HistoryList> List { get; set; }
|
||||
}
|
||||
}
|
||||
46
DownKyi.Core/BiliApi/History/Models/HistoryList.cs
Normal file
46
DownKyi.Core/BiliApi/History/Models/HistoryList.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
public class HistoryList : BaseModel
|
||||
{
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
// long_title
|
||||
[JsonProperty("cover")]
|
||||
public string Cover { get; set; }
|
||||
// covers
|
||||
[JsonProperty("uri")]
|
||||
public string Uri { get; set; }
|
||||
[JsonProperty("history")]
|
||||
public HistoryListHistory History { get; set; }
|
||||
[JsonProperty("videos")]
|
||||
public int Videos { get; set; }
|
||||
[JsonProperty("author_name")]
|
||||
public string AuthorName { get; set; }
|
||||
[JsonProperty("author_face")]
|
||||
public string AuthorFace { get; set; }
|
||||
[JsonProperty("author_mid")]
|
||||
public long AuthorMid { get; set; }
|
||||
[JsonProperty("view_at")]
|
||||
public long ViewAt { get; set; }
|
||||
[JsonProperty("progress")]
|
||||
public long Progress { get; set; }
|
||||
// badge
|
||||
[JsonProperty("show_title")]
|
||||
public string ShowTitle { get; set; }
|
||||
[JsonProperty("duration")]
|
||||
public long Duration { get; set; }
|
||||
// current
|
||||
// total
|
||||
[JsonProperty("new_desc")]
|
||||
public string NewDesc { get; set; }
|
||||
// is_finish
|
||||
// is_fav
|
||||
// kid
|
||||
[JsonProperty("tag_name")]
|
||||
public string TagName { get; set; }
|
||||
// live_status
|
||||
}
|
||||
}
|
||||
25
DownKyi.Core/BiliApi/History/Models/HistoryListHistory.cs
Normal file
25
DownKyi.Core/BiliApi/History/Models/HistoryListHistory.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
public class HistoryListHistory : BaseModel
|
||||
{
|
||||
[JsonProperty("oid")]
|
||||
public long Oid { get; set; }
|
||||
[JsonProperty("epid")]
|
||||
public long Epid { get; set; }
|
||||
[JsonProperty("bvid")]
|
||||
public string Bvid { get; set; }
|
||||
[JsonProperty("page")]
|
||||
public int Page { get; set; }
|
||||
[JsonProperty("cid")]
|
||||
public long Cid { get; set; }
|
||||
[JsonProperty("part")]
|
||||
public string Part { get; set; }
|
||||
[JsonProperty("business")]
|
||||
public string Business { get; set; }
|
||||
[JsonProperty("dt")]
|
||||
public int Dt { get; set; }
|
||||
}
|
||||
}
|
||||
27
DownKyi.Core/BiliApi/History/Models/ToViewData.cs
Normal file
27
DownKyi.Core/BiliApi/History/Models/ToViewData.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
// https://api.bilibili.com/x/v2/history/toview
|
||||
public class ToViewOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")]
|
||||
public ToViewData Data { get; set; }
|
||||
}
|
||||
|
||||
public class ToViewData : BaseModel
|
||||
{
|
||||
[JsonProperty("count")]
|
||||
public int Count { get; set; }
|
||||
[JsonProperty("list")]
|
||||
public List<ToViewList> List { get; set; }
|
||||
}
|
||||
}
|
||||
43
DownKyi.Core/BiliApi/History/Models/ToViewList.cs
Normal file
43
DownKyi.Core/BiliApi/History/Models/ToViewList.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History.Models
|
||||
{
|
||||
public class ToViewList : BaseModel
|
||||
{
|
||||
[JsonProperty("aid")]
|
||||
public long Aid { get; set; }
|
||||
// videos
|
||||
// tid
|
||||
// tname
|
||||
// copyright
|
||||
[JsonProperty("pic")]
|
||||
public string Pic { get; set; }
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
// pubdate
|
||||
// ctime
|
||||
// desc
|
||||
// state
|
||||
// duration
|
||||
// rights
|
||||
[JsonProperty("owner")]
|
||||
public VideoOwner Owner { get; set; }
|
||||
// stat
|
||||
// dynamic
|
||||
// dimension
|
||||
// short_link_v2
|
||||
// first_frame
|
||||
// page
|
||||
// count
|
||||
[JsonProperty("cid")]
|
||||
public long Cid { get; set; }
|
||||
// progress
|
||||
[JsonProperty("add_at")]
|
||||
public long AddAt { get; set; }
|
||||
[JsonProperty("bvid")]
|
||||
public string Bvid { get; set; }
|
||||
// uri
|
||||
// viewed
|
||||
}
|
||||
}
|
||||
38
DownKyi.Core/BiliApi/History/ToView.cs
Normal file
38
DownKyi.Core/BiliApi/History/ToView.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using DownKyi.Core.BiliApi.History.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.History
|
||||
{
|
||||
/// <summary>
|
||||
/// 稍后再看
|
||||
/// </summary>
|
||||
public static class ToView
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取稍后再看视频列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<ToViewList> GetToView()
|
||||
{
|
||||
string url = "https://api.bilibili.com/x/v2/history/toview";
|
||||
string referer = "https://www.bilibili.com";
|
||||
string response = WebClient.RequestWeb(url, referer);
|
||||
|
||||
try
|
||||
{
|
||||
var toView = JsonConvert.DeserializeObject<ToViewOrigin>(response);
|
||||
if (toView == null || toView.Data == null) { return null; }
|
||||
return toView.Data.List;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Debugging.Console.PrintLine("GetToView()发生异常: {0}", e);
|
||||
LogManager.Error("ToView", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
156
DownKyi.Core/BiliApi/Login/LoginHelper.cs
Normal file
156
DownKyi.Core/BiliApi/Login/LoginHelper.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Net;
|
||||
using DownKyi.Core.Logging;
|
||||
using DownKyi.Core.Settings;
|
||||
using DownKyi.Core.Settings.Models;
|
||||
using DownKyi.Core.Storage;
|
||||
using DownKyi.Core.Utils;
|
||||
using Console = DownKyi.Core.Utils.Debugging.Console;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Login
|
||||
{
|
||||
public static class LoginHelper
|
||||
{
|
||||
// 本地位置
|
||||
private static readonly string LOCAL_LOGIN_INFO = StorageManager.GetLogin();
|
||||
|
||||
// 16位密码,ps:密码位数没有限制,可任意设置
|
||||
private static readonly string SecretKey = "EsOat*^y1QR!&0J6";
|
||||
|
||||
/// <summary>
|
||||
/// 保存登录的cookies到文件
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static bool SaveLoginInfoCookies(string url)
|
||||
{
|
||||
string tempFile = LOCAL_LOGIN_INFO + "-" + Guid.NewGuid().ToString("N");
|
||||
CookieContainer cookieContainer = ObjectHelper.ParseCookie(url);
|
||||
|
||||
bool isSucceed = ObjectHelper.WriteCookiesToDisk(tempFile, cookieContainer);
|
||||
if (isSucceed)
|
||||
{
|
||||
// 加密密钥,增加机器码
|
||||
string password = SecretKey;
|
||||
|
||||
try
|
||||
{
|
||||
File.Copy(tempFile, LOCAL_LOGIN_INFO, true);
|
||||
// Encryptor.EncryptFile(tempFile, LOCAL_LOGIN_INFO, password);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("SaveLoginInfoCookies()发生异常: {0}", e);
|
||||
LogManager.Error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(tempFile))
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
|
||||
return isSucceed;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获得登录的cookies
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static CookieContainer GetLoginInfoCookies()
|
||||
{
|
||||
string tempFile = LOCAL_LOGIN_INFO + "-" + Guid.NewGuid().ToString("N");
|
||||
|
||||
if (File.Exists(LOCAL_LOGIN_INFO))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Copy(LOCAL_LOGIN_INFO, tempFile, true);
|
||||
// 加密密钥,增加机器码
|
||||
// string password = SecretKey;
|
||||
// Encryptor.DecryptFile(LOCAL_LOGIN_INFO, tempFile, password);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.PrintLine("GetLoginInfoCookies()发生异常: {0}", e);
|
||||
LogManager.Error(e);
|
||||
if (File.Exists(tempFile))
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CookieContainer cookies = ObjectHelper.ReadCookiesFromDisk(tempFile);
|
||||
|
||||
if (File.Exists(tempFile))
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回登录信息的cookies的字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetLoginInfoCookiesString()
|
||||
{
|
||||
var cookieContainer = GetLoginInfoCookies();
|
||||
if (cookieContainer == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
var cookies = ObjectHelper.GetAllCookies(cookieContainer);
|
||||
|
||||
string cookie = string.Empty;
|
||||
foreach (var item in cookies)
|
||||
{
|
||||
cookie += item.ToString() + ";";
|
||||
}
|
||||
|
||||
return cookie.TrimEnd(';');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool Logout()
|
||||
{
|
||||
if (File.Exists(LOCAL_LOGIN_INFO))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(LOCAL_LOGIN_INFO);
|
||||
|
||||
SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
|
||||
{
|
||||
Mid = -1,
|
||||
Name = "",
|
||||
IsLogin = false,
|
||||
IsVip = false
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Console.PrintLine("Logout()发生异常: {0}", e);
|
||||
LogManager.Error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
DownKyi.Core/BiliApi/Login/LoginQR.cs
Normal file
87
DownKyi.Core/BiliApi/Login/LoginQR.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Avalonia.Media.Imaging;
|
||||
using DownKyi.Core.BiliApi.Login.Models;
|
||||
using DownKyi.Core.Logging;
|
||||
using DownKyi.Core.Utils;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Login;
|
||||
|
||||
public static class LoginQR
|
||||
{
|
||||
/// <summary>
|
||||
/// 申请二维码URL及扫码密钥(web端)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LoginUrlOrigin? GetLoginUrl()
|
||||
{
|
||||
string getLoginUrl = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
|
||||
string response = WebClient.RequestWeb(getLoginUrl);
|
||||
Console.Out.WriteLine(response);
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<LoginUrlOrigin>(response);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Debugging.Console.PrintLine("GetLoginUrl()发生异常: {0}", e);
|
||||
LogManager.Error("LoginQR", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用扫码登录(web端)
|
||||
/// </summary>
|
||||
/// <param name="qrcodeKey"></param>
|
||||
/// <param name="goUrl"></param>
|
||||
/// <returns></returns>
|
||||
public static LoginStatus? GetLoginStatus(string qrcodeKey, string goUrl = "https://www.bilibili.com")
|
||||
{
|
||||
string url = "https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=" + qrcodeKey;
|
||||
|
||||
string response = WebClient.RequestWeb(url);
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<LoginStatus>(response);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Debugging.Console.PrintLine("GetLoginInfo()发生异常: {0}", e);
|
||||
LogManager.Error("LoginQR", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得登录二维码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Bitmap GetLoginQRCode()
|
||||
{
|
||||
try
|
||||
{
|
||||
string loginUrl = GetLoginUrl().Data.Url;
|
||||
return GetLoginQRCode(loginUrl);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Debugging.Console.PrintLine("GetLoginQRCode()发生异常: {0}", e);
|
||||
LogManager.Error("LoginQR", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据输入url生成二维码
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static Bitmap GetLoginQRCode(string url)
|
||||
{
|
||||
// 设置的参数影响app能否成功扫码
|
||||
Bitmap qrCode = QRCode.EncodeQRCode(url, 10, 10, null, 0, 0, false);
|
||||
|
||||
return qrCode;
|
||||
}
|
||||
}
|
||||
23
DownKyi.Core/BiliApi/Login/Models/LoginStatus.cs
Normal file
23
DownKyi.Core/BiliApi/Login/Models/LoginStatus.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Login.Models
|
||||
{
|
||||
[JsonObject]
|
||||
public class LoginStatus : BaseModel
|
||||
{
|
||||
[JsonProperty("code")] public int Code { get; set; }
|
||||
[JsonProperty("message")] public string Message { get; set; }
|
||||
|
||||
[JsonProperty("data")] public LoginStatusData Data { get; set; }
|
||||
}
|
||||
|
||||
[JsonObject]
|
||||
public class LoginStatusData : BaseModel
|
||||
{
|
||||
[JsonProperty("url")] public string Url { get; set; }
|
||||
[JsonProperty("refresh_token")] public string RefreshToken { get; set; }
|
||||
[JsonProperty("code")] public int Code { get; set; }
|
||||
[JsonProperty("message")] public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
23
DownKyi.Core/BiliApi/Login/Models/LoginUrl.cs
Normal file
23
DownKyi.Core/BiliApi/Login/Models/LoginUrl.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Login.Models
|
||||
{
|
||||
// https://passport.bilibili.com/qrcode/getLoginUrl
|
||||
[JsonObject]
|
||||
public class LoginUrlOrigin : BaseModel
|
||||
{
|
||||
//public int code { get; set; }
|
||||
[JsonProperty("data")] public LoginUrl Data { get; set; }
|
||||
|
||||
[JsonProperty("code")] public int Code { get; set; }
|
||||
//public long ts { get; set; }
|
||||
}
|
||||
|
||||
[JsonObject]
|
||||
public class LoginUrl : BaseModel
|
||||
{
|
||||
[JsonProperty("qrcode_key")] public string QrcodeKey { get; set; }
|
||||
[JsonProperty("url")] public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
29
DownKyi.Core/BiliApi/Models/BaseModel.cs
Normal file
29
DownKyi.Core/BiliApi/Models/BaseModel.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Models;
|
||||
|
||||
public abstract class BaseModel
|
||||
{
|
||||
public string ToString(string format = "")
|
||||
{
|
||||
// 设置为去掉null
|
||||
var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case "":
|
||||
return JsonConvert.SerializeObject(this);
|
||||
case "F":
|
||||
// 整理json格式
|
||||
return JsonConvert.SerializeObject(this, Formatting.Indented);
|
||||
case "N":
|
||||
// 去掉null后,转换为json字符串
|
||||
return JsonConvert.SerializeObject(this, Formatting.None, jsonSetting);
|
||||
case "FN":
|
||||
case "NF":
|
||||
return JsonConvert.SerializeObject(this, Formatting.Indented, jsonSetting);
|
||||
default:
|
||||
return ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Models/Dimension.cs
Normal file
10
DownKyi.Core/BiliApi/Models/Dimension.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Models;
|
||||
|
||||
public class Dimension : BaseModel
|
||||
{
|
||||
[JsonProperty("width")] public int Width { get; set; }
|
||||
[JsonProperty("height")] public int Height { get; set; }
|
||||
[JsonProperty("rotate")] public int Rotate { get; set; }
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Models/Json/SubRipText.cs
Normal file
10
DownKyi.Core/BiliApi/Models/Json/SubRipText.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Models.Json;
|
||||
|
||||
public class SubRipText : BaseModel
|
||||
{
|
||||
[JsonProperty("lan")] public string Lan { get; set; }
|
||||
[JsonProperty("lan_doc")] public string LanDoc { get; set; }
|
||||
[JsonProperty("srtString")] public string SrtString { get; set; }
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/Models/Json/Subtitle.cs
Normal file
11
DownKyi.Core/BiliApi/Models/Json/Subtitle.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Models.Json;
|
||||
|
||||
public class Subtitle : BaseModel
|
||||
{
|
||||
[JsonProperty("from")] public float From { get; set; }
|
||||
[JsonProperty("to")] public float To { get; set; }
|
||||
[JsonProperty("location")] public int Location { get; set; }
|
||||
[JsonProperty("content")] public string Content { get; set; }
|
||||
}
|
||||
59
DownKyi.Core/BiliApi/Models/Json/SubtitleJson.cs
Normal file
59
DownKyi.Core/BiliApi/Models/Json/SubtitleJson.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Models.Json;
|
||||
|
||||
public class SubtitleJson : BaseModel
|
||||
{
|
||||
[JsonProperty("font_size")] public float FontSize { get; set; }
|
||||
[JsonProperty("font_color")] public string FontColor { get; set; }
|
||||
[JsonProperty("background_alpha")] public float BackgroundAlpha { get; set; }
|
||||
[JsonProperty("background_color")] public string BackgroundColor { get; set; }
|
||||
[JsonProperty("Stroke")] public string Stroke { get; set; }
|
||||
[JsonProperty("body")] public List<Subtitle> Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// srt格式字幕
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToSubRip()
|
||||
{
|
||||
string subRip = string.Empty;
|
||||
for (int i = 0; i < Body.Count; i++)
|
||||
{
|
||||
subRip += $"{i + 1}\n";
|
||||
subRip += $"{Second2hms(Body[i].From)} --> {Second2hms(Body[i].To)}\n";
|
||||
subRip += $"{Body[i].Content}\n";
|
||||
subRip += "\n";
|
||||
}
|
||||
|
||||
return subRip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 秒数转 时:分:秒 格式
|
||||
/// </summary>
|
||||
/// <param name="seconds"></param>
|
||||
/// <returns></returns>
|
||||
private static string Second2hms(float seconds)
|
||||
{
|
||||
if (seconds < 0)
|
||||
{
|
||||
return "00:00:00,000";
|
||||
}
|
||||
|
||||
int i = (int)Math.Floor(seconds / 1.0);
|
||||
int dec = (int)(Math.Round(seconds % 1.0f, 2) * 100);
|
||||
if (dec >= 100)
|
||||
{
|
||||
dec = 99;
|
||||
}
|
||||
|
||||
int min = (int)Math.Floor(i / 60.0);
|
||||
int second = (int)(i % 60.0f);
|
||||
|
||||
int hour = (int)Math.Floor(min / 60.0);
|
||||
min = (int)Math.Floor(min % 60.0f);
|
||||
|
||||
return $"{hour:D2}:{min:D2}:{second:D2},{dec:D3}";
|
||||
}
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Models/VideoOwner.cs
Normal file
10
DownKyi.Core/BiliApi/Models/VideoOwner.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Models;
|
||||
|
||||
public class VideoOwner : BaseModel
|
||||
{
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("face")] public string Face { get; set; }
|
||||
}
|
||||
116
DownKyi.Core/BiliApi/Sign/WbiSign.cs
Normal file
116
DownKyi.Core/BiliApi/Sign/WbiSign.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using DownKyi.Core.Settings;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Sign;
|
||||
|
||||
public static class WbiSign
|
||||
{
|
||||
/// <summary>
|
||||
/// 打乱重排实时口令
|
||||
/// </summary>
|
||||
/// <param name="origin"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetMixinKey(string origin)
|
||||
{
|
||||
int[] mixinKeyEncTab = {
|
||||
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().Substring(0, 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>
|
||||
/// 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;
|
||||
}
|
||||
|
||||
public static Tuple<string, string> GetKey()
|
||||
{
|
||||
var user = SettingsManager.GetInstance().GetUserInfo();
|
||||
|
||||
return new Tuple<string, string>(user.ImgKey, user.SubKey);
|
||||
}
|
||||
}
|
||||
65
DownKyi.Core/BiliApi/Users/Models/BangumiFollow.cs
Normal file
65
DownKyi.Core/BiliApi/Users/Models/BangumiFollow.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class BangumiFollow : BaseModel
|
||||
{
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
[JsonProperty("media_id")] public long MediaId { get; set; }
|
||||
[JsonProperty("season_type")] public int SeasonType { get; set; }
|
||||
[JsonProperty("season_type_name")] public string SeasonTypeName { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
|
||||
[JsonProperty("total_count")] public int TotalCount { get; set; }
|
||||
|
||||
// is_finish
|
||||
// is_started
|
||||
// is_play
|
||||
[JsonProperty("badge")] public string Badge { get; set; }
|
||||
|
||||
[JsonProperty("badge_type")] public int BadgeType { get; set; }
|
||||
|
||||
// rights
|
||||
// stat
|
||||
[JsonProperty("new_ep")] public BangumiFollowNewEp NewEp { get; set; }
|
||||
|
||||
// rating
|
||||
// square_cover
|
||||
[JsonProperty("season_status")] public int SeasonStatus { get; set; }
|
||||
[JsonProperty("season_title")] public string SeasonTitle { get; set; }
|
||||
|
||||
[JsonProperty("badge_ep")] public string BadgeEp { get; set; }
|
||||
|
||||
// media_attr
|
||||
// season_attr
|
||||
[JsonProperty("evaluate")] public string Evaluate { get; set; }
|
||||
[JsonProperty("areas")] public List<BangumiFollowAreas> Areas { get; set; }
|
||||
[JsonProperty("subtitle")] public string Subtitle { get; set; }
|
||||
|
||||
[JsonProperty("first_ep")] public long FirstEp { get; set; }
|
||||
|
||||
// can_watch
|
||||
// series
|
||||
// publish
|
||||
// mode
|
||||
// section
|
||||
[JsonProperty("url")] public string Url { get; set; }
|
||||
|
||||
// badge_info
|
||||
// first_ep_info
|
||||
// formal_ep_count
|
||||
// short_url
|
||||
// badge_infos
|
||||
// season_version
|
||||
// horizontal_cover_16_9
|
||||
// horizontal_cover_16_10
|
||||
// subtitle_14
|
||||
// viewable_crowd_type
|
||||
// producers
|
||||
// follow_status
|
||||
// is_new
|
||||
[JsonProperty("progress")] public string Progress { get; set; }
|
||||
// both_follow
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Users/Models/BangumiFollowAreas.cs
Normal file
10
DownKyi.Core/BiliApi/Users/Models/BangumiFollowAreas.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class BangumiFollowAreas : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public int Id { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
}
|
||||
15
DownKyi.Core/BiliApi/Users/Models/BangumiFollowNewEp.cs
Normal file
15
DownKyi.Core/BiliApi/Users/Models/BangumiFollowNewEp.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class BangumiFollowNewEp : BaseModel
|
||||
{
|
||||
[JsonProperty("id")] public long Id { get; set; }
|
||||
[JsonProperty("index_show")] public string IndexShow { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("long_title")] public string LongTitle { get; set; }
|
||||
[JsonProperty("pub_time")] public string PubTime { get; set; }
|
||||
[JsonProperty("duration")] public long Duration { get; set; }
|
||||
}
|
||||
18
DownKyi.Core/BiliApi/Users/Models/BangumiFollowOrigin.cs
Normal file
18
DownKyi.Core/BiliApi/Users/Models/BangumiFollowOrigin.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/space/bangumi/follow/list?vmid={mid}&type={type:D}&pn={pn}&ps={ps}
|
||||
public class BangumiFollowOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public BangumiFollowData Data { get; set; }
|
||||
}
|
||||
|
||||
public class BangumiFollowData : BaseModel
|
||||
{
|
||||
[JsonProperty("list")] public List<BangumiFollow> List { get; set; }
|
||||
[JsonProperty("pn")] public int Pn { get; set; }
|
||||
[JsonProperty("ps")] public int Ps { get; set; }
|
||||
[JsonProperty("total")] public int Total { get; set; }
|
||||
}
|
||||
7
DownKyi.Core/BiliApi/Users/Models/BangumiType.cs
Normal file
7
DownKyi.Core/BiliApi/Users/Models/BangumiType.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public enum BangumiType
|
||||
{
|
||||
ANIME = 1, // 番剧
|
||||
EPISODE = 2 // 剧集、电影
|
||||
}
|
||||
18
DownKyi.Core/BiliApi/Users/Models/FollowingGroup.cs
Normal file
18
DownKyi.Core/BiliApi/Users/Models/FollowingGroup.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/relation/tags
|
||||
public class FollowingGroupOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public List<FollowingGroup> Data { get; set; }
|
||||
}
|
||||
|
||||
public class FollowingGroup : BaseModel
|
||||
{
|
||||
[JsonProperty("tagid")] public int TagId { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
[JsonProperty("tip")] public string Tip { get; set; }
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Users/Models/FollowingGroupContent.cs
Normal file
10
DownKyi.Core/BiliApi/Users/Models/FollowingGroupContent.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/relation/tag?tagid={tagId}&pn={pn}&ps={ps}&order_type={orderType}
|
||||
public class FollowingGroupContent : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public List<RelationFollowInfo> Data { get; set; }
|
||||
}
|
||||
7
DownKyi.Core/BiliApi/Users/Models/FollowingOrder.cs
Normal file
7
DownKyi.Core/BiliApi/Users/Models/FollowingOrder.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public enum FollowingOrder
|
||||
{
|
||||
DEFAULT = 1, // 按照关注顺序排列,默认
|
||||
ATTENTION // 按照最常访问排列
|
||||
}
|
||||
59
DownKyi.Core/BiliApi/Users/Models/MyInfo.cs
Normal file
59
DownKyi.Core/BiliApi/Users/Models/MyInfo.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/space/myinfo
|
||||
public class MyInfoOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public MyInfo Data { get; set; }
|
||||
}
|
||||
|
||||
public class MyInfo : BaseModel
|
||||
{
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("sex")] public string Sex { get; set; }
|
||||
[JsonProperty("face")] public string Face { get; set; }
|
||||
|
||||
[JsonProperty("sign")] public string Sign { get; set; }
|
||||
|
||||
// rank
|
||||
[JsonProperty("level")] public int Level { get; set; }
|
||||
|
||||
// jointime
|
||||
[JsonProperty("moral")] public int Moral { get; set; }
|
||||
[JsonProperty("silence")] public int Silence { get; set; }
|
||||
[JsonProperty("email_status")] public int EmailStatus { get; set; }
|
||||
[JsonProperty("tel_status")] public int TelStatus { get; set; }
|
||||
[JsonProperty("identification")] public int Identification { get; set; }
|
||||
|
||||
[JsonProperty("vip")] public UserInfoVip Vip { get; set; }
|
||||
|
||||
// pendant
|
||||
// nameplate
|
||||
// official
|
||||
[JsonProperty("birthday")] public long Birthday { get; set; }
|
||||
[JsonProperty("is_tourist")] public int IsTourist { get; set; }
|
||||
[JsonProperty("is_fake_account")] public int IsFakeAccount { get; set; }
|
||||
[JsonProperty("pin_prompting")] public int PinPrompting { get; set; }
|
||||
|
||||
[JsonProperty("is_deleted")] public int IsDeleted { get; set; }
|
||||
|
||||
// in_reg_audit
|
||||
// is_rip_user
|
||||
// profession
|
||||
// face_nft
|
||||
// face_nft_new
|
||||
// is_senior_member
|
||||
[JsonProperty("level_exp")] public UserInfoLevelExp LevelExp { get; set; }
|
||||
[JsonProperty("coins")] public float Coins { get; set; }
|
||||
[JsonProperty("following")] public int Following { get; set; }
|
||||
[JsonProperty("follower")] public int Follower { get; set; }
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/Users/Models/NicknameStatus.cs
Normal file
11
DownKyi.Core/BiliApi/Users/Models/NicknameStatus.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/relation/stat?nickName={nickName}
|
||||
public class NicknameStatus : BaseModel
|
||||
{
|
||||
[JsonProperty("code")] public int Code { get; set; }
|
||||
[JsonProperty("message")] public string Message { get; set; }
|
||||
}
|
||||
8
DownKyi.Core/BiliApi/Users/Models/PublicationOrder.cs
Normal file
8
DownKyi.Core/BiliApi/Users/Models/PublicationOrder.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public enum PublicationOrder
|
||||
{
|
||||
PUBDATE = 1, // 最新发布,默认
|
||||
CLICK, // 最多播放
|
||||
STOW // 最多收藏
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Users/Models/RelationBlack.cs
Normal file
10
DownKyi.Core/BiliApi/Users/Models/RelationBlack.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/relation/blacks?pn={pn}&ps={ps}
|
||||
public class RelationBlack : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public List<RelationFollowInfo> Data { get; set; }
|
||||
}
|
||||
20
DownKyi.Core/BiliApi/Users/Models/RelationFollow.cs
Normal file
20
DownKyi.Core/BiliApi/Users/Models/RelationFollow.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/relation/followers?vmid={mid}&pn={pn}&ps={ps}
|
||||
// https://api.bilibili.com/x/relation/followings?vmid={mid}&pn={pn}&ps={ps}&order_type={orderType}
|
||||
public class RelationFollowOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public RelationFollow Data { get; set; }
|
||||
}
|
||||
|
||||
public class RelationFollow : BaseModel
|
||||
{
|
||||
[JsonProperty("list")] public List<RelationFollowInfo> List { get; set; }
|
||||
|
||||
//[JsonProperty("re_version")]
|
||||
//public long reVersion { get; set; }
|
||||
[JsonProperty("total")] public int Total { get; set; }
|
||||
}
|
||||
24
DownKyi.Core/BiliApi/Users/Models/RelationFollowInfo.cs
Normal file
24
DownKyi.Core/BiliApi/Users/Models/RelationFollowInfo.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class RelationFollowInfo : BaseModel
|
||||
{
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("attribute")] public int Attribute { get; set; }
|
||||
[JsonProperty("mtime")] public long Mtime { get; set; }
|
||||
[JsonProperty("tag")] public List<long> Tag { get; set; }
|
||||
|
||||
[JsonProperty("special")] public int Special { get; set; }
|
||||
|
||||
// contract_info
|
||||
[JsonProperty("uname")] public string Name { get; set; }
|
||||
[JsonProperty("face")] public string Face { get; set; }
|
||||
|
||||
[JsonProperty("sign")] public string Sign { get; set; }
|
||||
// face_nft
|
||||
// official_verify
|
||||
// vip
|
||||
// nft_icon
|
||||
}
|
||||
16
DownKyi.Core/BiliApi/Users/Models/RelationWhisper.cs
Normal file
16
DownKyi.Core/BiliApi/Users/Models/RelationWhisper.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/relation/whispers?pn={pn}&ps={ps}
|
||||
public class RelationWhisper : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public RelationWhisperData Data { get; set; }
|
||||
}
|
||||
|
||||
public class RelationWhisperData : BaseModel
|
||||
{
|
||||
[JsonProperty("list")] public List<RelationFollowInfo> List { get; set; }
|
||||
// re_version
|
||||
}
|
||||
19
DownKyi.Core/BiliApi/Users/Models/SpaceChannel.cs
Normal file
19
DownKyi.Core/BiliApi/Users/Models/SpaceChannel.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/space/channel/list?mid={mid}
|
||||
public class SpaceChannelOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")]
|
||||
public SpaceChannel Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceChannel : BaseModel
|
||||
{
|
||||
[JsonProperty("count")]
|
||||
public int Count { get; set; }
|
||||
[JsonProperty("list")]
|
||||
public List<SpaceChannelList> List { get; set; }
|
||||
}
|
||||
42
DownKyi.Core/BiliApi/Users/Models/SpaceChannelArchive.cs
Normal file
42
DownKyi.Core/BiliApi/Users/Models/SpaceChannelArchive.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceChannelArchive : BaseModel
|
||||
{
|
||||
[JsonProperty("aid")] public long Aid { get; set; }
|
||||
|
||||
// videos
|
||||
[JsonProperty("tid")] public int Tid { get; set; }
|
||||
|
||||
[JsonProperty("tname")] public string Tname { get; set; }
|
||||
|
||||
// copyright
|
||||
[JsonProperty("pic")] public string Pic { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
[JsonProperty("pubdate")] public long Pubdate { get; set; }
|
||||
[JsonProperty("ctime")] public long Ctime { get; set; }
|
||||
|
||||
[JsonProperty("desc")] public string Desc { get; set; }
|
||||
|
||||
// state
|
||||
[JsonProperty("duration")] public long Duration { get; set; }
|
||||
|
||||
// mission_id
|
||||
// rights
|
||||
[JsonProperty("owner")] public VideoOwner Owner { get; set; }
|
||||
|
||||
[JsonProperty("stat")] public SpaceChannelArchiveStat Stat { get; set; }
|
||||
|
||||
// dynamic
|
||||
[JsonProperty("cid")] public long Cid { get; set; }
|
||||
|
||||
[JsonProperty("dimension")] public Dimension Dimension { get; set; }
|
||||
|
||||
// season_id
|
||||
// short_link_v2
|
||||
[JsonProperty("bvid")] public string Bvid { get; set; }
|
||||
// inter_video
|
||||
// is_live_playback
|
||||
}
|
||||
19
DownKyi.Core/BiliApi/Users/Models/SpaceChannelArchiveStat.cs
Normal file
19
DownKyi.Core/BiliApi/Users/Models/SpaceChannelArchiveStat.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceChannelArchiveStat : BaseModel
|
||||
{
|
||||
[JsonProperty("aid")] public long Aid { get; set; }
|
||||
[JsonProperty("view")] public long View { get; set; }
|
||||
[JsonProperty("danmaku")] public long Danmaku { get; set; }
|
||||
[JsonProperty("reply")] public long Reply { get; set; }
|
||||
[JsonProperty("favorite")] public long Favorite { get; set; }
|
||||
[JsonProperty("coin")] public long Coin { get; set; }
|
||||
[JsonProperty("share")] public long Share { get; set; }
|
||||
[JsonProperty("now_rank")] public long NowRank { get; set; }
|
||||
[JsonProperty("his_rank")] public long HisRank { get; set; }
|
||||
[JsonProperty("like")] public long Like { get; set; }
|
||||
[JsonProperty("dislike")] public long Dislike { get; set; }
|
||||
}
|
||||
17
DownKyi.Core/BiliApi/Users/Models/SpaceChannelList.cs
Normal file
17
DownKyi.Core/BiliApi/Users/Models/SpaceChannelList.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceChannelList : BaseModel
|
||||
{
|
||||
[JsonProperty("cid")] public long Cid { get; set; }
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("intro")] public string Intro { get; set; }
|
||||
[JsonProperty("mtime")] public long Mtime { get; set; }
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
// is_live_playback
|
||||
}
|
||||
17
DownKyi.Core/BiliApi/Users/Models/SpaceChannelVideo.cs
Normal file
17
DownKyi.Core/BiliApi/Users/Models/SpaceChannelVideo.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/space/channel/video?mid={mid}&cid={cid}&pn={pn}&ps={ps}
|
||||
public class SpaceChannelVideoOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public SpaceChannelVideo Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceChannelVideo : BaseModel
|
||||
{
|
||||
// episodic_button
|
||||
[JsonProperty("list")] public SpaceChannelVideoList List { get; set; }
|
||||
[JsonProperty("page")] public SpaceChannelVideoPage Page { get; set; }
|
||||
}
|
||||
19
DownKyi.Core/BiliApi/Users/Models/SpaceChannelVideoList.cs
Normal file
19
DownKyi.Core/BiliApi/Users/Models/SpaceChannelVideoList.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceChannelVideoList : BaseModel
|
||||
{
|
||||
[JsonProperty("cid")] public long Cid { get; set; }
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("intro")] public string Intro { get; set; }
|
||||
[JsonProperty("mtime")] public long Mtime { get; set; }
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
|
||||
// is_live_playback
|
||||
[JsonProperty("archives")] public List<SpaceChannelArchive> Archives { get; set; }
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/Users/Models/SpaceChannelVideoPage.cs
Normal file
11
DownKyi.Core/BiliApi/Users/Models/SpaceChannelVideoPage.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceChannelVideoPage : BaseModel
|
||||
{
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
[JsonProperty("num")] public int Num { get; set; }
|
||||
[JsonProperty("size")] public int Size { get; set; }
|
||||
}
|
||||
17
DownKyi.Core/BiliApi/Users/Models/SpaceCheese.cs
Normal file
17
DownKyi.Core/BiliApi/Users/Models/SpaceCheese.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceCheese : BaseModel
|
||||
{
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("ep_count")] public int EpCount { get; set; }
|
||||
[JsonProperty("link")] public string Link { get; set; }
|
||||
[JsonProperty("page")] public int Page { get; set; }
|
||||
[JsonProperty("play")] public int Play { get; set; }
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
[JsonProperty("status")] public string Status { get; set; }
|
||||
[JsonProperty("subtitle")] public string SubTitle { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
}
|
||||
16
DownKyi.Core/BiliApi/Users/Models/SpaceCheeseOrigin.cs
Normal file
16
DownKyi.Core/BiliApi/Users/Models/SpaceCheeseOrigin.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/pugv/app/web/season/page?mid={mid}&pn={pn}&ps={ps}
|
||||
public class SpaceCheeseOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public SpaceCheeseData Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceCheeseData : BaseModel
|
||||
{
|
||||
[JsonProperty("items")] public List<SpaceCheese> Items { get; set; }
|
||||
[JsonProperty("page")] public SpaceCheesePage Page { get; set; }
|
||||
}
|
||||
12
DownKyi.Core/BiliApi/Users/Models/SpaceCheesePage.cs
Normal file
12
DownKyi.Core/BiliApi/Users/Models/SpaceCheesePage.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceCheesePage : BaseModel
|
||||
{
|
||||
[JsonProperty("next")] public bool Next { get; set; }
|
||||
[JsonProperty("num")] public int Num { get; set; }
|
||||
[JsonProperty("size")] public int Size { get; set; }
|
||||
[JsonProperty("total")] public int Total { get; set; }
|
||||
}
|
||||
16
DownKyi.Core/BiliApi/Users/Models/SpacePublication.cs
Normal file
16
DownKyi.Core/BiliApi/Users/Models/SpacePublication.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/space/arc/search
|
||||
public class SpacePublicationOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("data")] public SpacePublication Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpacePublication : BaseModel
|
||||
{
|
||||
[JsonProperty("list")] public SpacePublicationList List { get; set; }
|
||||
[JsonProperty("page")] public SpacePublicationPage Page { get; set; }
|
||||
}
|
||||
10
DownKyi.Core/BiliApi/Users/Models/SpacePublicationList.cs
Normal file
10
DownKyi.Core/BiliApi/Users/Models/SpacePublicationList.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpacePublicationList : BaseModel
|
||||
{
|
||||
[JsonProperty("tlist")] public SpacePublicationListType Tlist { get; set; }
|
||||
[JsonProperty("vlist")] public List<SpacePublicationListVideo> Vlist { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpacePublicationListType : BaseModel
|
||||
{
|
||||
[JsonProperty("1")] public SpacePublicationListTypeVideoZone Douga { get; set; }
|
||||
[JsonProperty("13")] public SpacePublicationListTypeVideoZone Anime { get; set; }
|
||||
[JsonProperty("167")] public SpacePublicationListTypeVideoZone Guochuang { get; set; }
|
||||
[JsonProperty("3")] public SpacePublicationListTypeVideoZone Music { get; set; }
|
||||
[JsonProperty("129")] public SpacePublicationListTypeVideoZone Dance { get; set; }
|
||||
[JsonProperty("4")] public SpacePublicationListTypeVideoZone Game { get; set; }
|
||||
[JsonProperty("36")] public SpacePublicationListTypeVideoZone Technology { get; set; }
|
||||
[JsonProperty("188")] public SpacePublicationListTypeVideoZone Digital { get; set; }
|
||||
[JsonProperty("234")] public SpacePublicationListTypeVideoZone Sports { get; set; }
|
||||
[JsonProperty("223")] public SpacePublicationListTypeVideoZone Car { get; set; }
|
||||
[JsonProperty("160")] public SpacePublicationListTypeVideoZone Life { get; set; }
|
||||
[JsonProperty("211")] public SpacePublicationListTypeVideoZone Food { get; set; }
|
||||
[JsonProperty("217")] public SpacePublicationListTypeVideoZone Animal { get; set; }
|
||||
[JsonProperty("119")] public SpacePublicationListTypeVideoZone Kichiku { get; set; }
|
||||
[JsonProperty("155")] public SpacePublicationListTypeVideoZone Fashion { get; set; }
|
||||
[JsonProperty("202")] public SpacePublicationListTypeVideoZone Information { get; set; }
|
||||
[JsonProperty("5")] public SpacePublicationListTypeVideoZone Ent { get; set; }
|
||||
[JsonProperty("181")] public SpacePublicationListTypeVideoZone Cinephile { get; set; }
|
||||
[JsonProperty("177")] public SpacePublicationListTypeVideoZone Documentary { get; set; }
|
||||
[JsonProperty("23")] public SpacePublicationListTypeVideoZone Movie { get; set; }
|
||||
[JsonProperty("11")] public SpacePublicationListTypeVideoZone Tv { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpacePublicationListTypeVideoZone : BaseModel
|
||||
{
|
||||
[JsonProperty("tid")] public int Tid { get; set; }
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpacePublicationListVideo : BaseModel
|
||||
{
|
||||
//[JsonProperty("comment")]
|
||||
//public int Comment { get; set; }
|
||||
[JsonProperty("typeid")] public int Typeid { get; set; }
|
||||
[JsonProperty("play")] public int Play { get; set; }
|
||||
|
||||
[JsonProperty("pic")] public string Pic { get; set; }
|
||||
|
||||
//[JsonProperty("subtitle")]
|
||||
//public string Subtitle { get; set; }
|
||||
//[JsonProperty("description")]
|
||||
//public string Description { get; set; }
|
||||
//[JsonProperty("copyright")]
|
||||
//public string Copyright { get; set; }
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
|
||||
//[JsonProperty("review")]
|
||||
//public int Review { get; set; }
|
||||
//[JsonProperty("author")]
|
||||
//public string Author { get; set; }
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("created")] public long Created { get; set; }
|
||||
|
||||
[JsonProperty("length")] public string Length { get; set; }
|
||||
|
||||
//[JsonProperty("video_review")]
|
||||
//public int VideoReview { get; set; }
|
||||
[JsonProperty("aid")] public long Aid { get; set; }
|
||||
|
||||
[JsonProperty("bvid")] public string Bvid { get; set; }
|
||||
//[JsonProperty("hide_click")]
|
||||
//public bool HideClick { get; set; }
|
||||
//[JsonProperty("is_pay")]
|
||||
//public int IsPay { get; set; }
|
||||
//[JsonProperty("is_union_video")]
|
||||
//public int IsUnionVideo { get; set; }
|
||||
//[JsonProperty("is_steins_gate")]
|
||||
//public int IsSteinsGate { get; set; }
|
||||
//[JsonProperty("is_live_playback")]
|
||||
//public int IsLivePlayback { get; set; }
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/Users/Models/SpacePublicationPage.cs
Normal file
11
DownKyi.Core/BiliApi/Users/Models/SpacePublicationPage.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpacePublicationPage : BaseModel
|
||||
{
|
||||
[JsonProperty("pn")] public int Pn { get; set; }
|
||||
[JsonProperty("ps")] public int Ps { get; set; }
|
||||
[JsonProperty("count")] public int Count { get; set; }
|
||||
}
|
||||
24
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsDetail.cs
Normal file
24
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsDetail.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/polymer/space/seasons_archives_list?mid={mid}&season_id={seasonId}&page_num={pageNum}&page_size={pageSize}&sort_reverse=false
|
||||
public class SpaceSeasonsDetailOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public SpaceSeasonsDetail Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeasonsDetail : BaseModel
|
||||
{
|
||||
[JsonProperty("aids")] public List<long> Aids { get; set; }
|
||||
[JsonProperty("archives")] public List<SpaceSeasonsSeriesArchives> Archives { get; set; }
|
||||
[JsonProperty("meta")] public SpaceSeasonsMeta Meta { get; set; }
|
||||
[JsonProperty("page")] public SpaceSeasonsSeriesPage Page { get; set; }
|
||||
}
|
||||
18
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsSeries.cs
Normal file
18
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsSeries.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceSeasons : BaseModel
|
||||
{
|
||||
[JsonProperty("archives")] public List<SpaceSeasonsSeriesArchives> Archives { get; set; }
|
||||
[JsonProperty("meta")] public SpaceSeasonsMeta Meta { get; set; }
|
||||
[JsonProperty("recent_aids")] public List<long> RecentAids { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeries : BaseModel
|
||||
{
|
||||
[JsonProperty("archives")] public List<SpaceSeasonsSeriesArchives> Archives { get; set; }
|
||||
[JsonProperty("meta")] public SpaceSeriesMeta Meta { get; set; }
|
||||
[JsonProperty("recent_aids")] public List<long> RecentAids { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceSeasonsSeriesArchives : BaseModel
|
||||
{
|
||||
[JsonProperty("aid")] public long Aid { get; set; }
|
||||
[JsonProperty("bvid")] public string Bvid { get; set; }
|
||||
[JsonProperty("ctime")] public long Ctime { get; set; }
|
||||
[JsonProperty("duration")] public long Duration { get; set; }
|
||||
[JsonProperty("interactive_video")] public bool InteractiveVideo { get; set; }
|
||||
[JsonProperty("pic")] public string Pic { get; set; }
|
||||
[JsonProperty("pubdate")] public long Pubdate { get; set; }
|
||||
|
||||
[JsonProperty("stat")] public SpaceSeasonsSeriesStat Stat { get; set; }
|
||||
|
||||
// state
|
||||
[JsonProperty("title")] public string Title { get; set; }
|
||||
// ugc_pay
|
||||
}
|
||||
32
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsSeriesMeta.cs
Normal file
32
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsSeriesMeta.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceSeasonsSeriesMeta : BaseModel
|
||||
{
|
||||
[JsonProperty("category")] public int Category { get; set; }
|
||||
[JsonProperty("cover")] public string Cover { get; set; }
|
||||
[JsonProperty("description")] public string Description { get; set; }
|
||||
[JsonProperty("mid")] public long Mid { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("total")] public int Total { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeasonsMeta : SpaceSeasonsSeriesMeta
|
||||
{
|
||||
[JsonProperty("ptime")] public long Ptime { get; set; }
|
||||
[JsonProperty("season_id")] public long SeasonId { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeriesMeta : SpaceSeasonsSeriesMeta
|
||||
{
|
||||
[JsonProperty("creator")] public string Creator { get; set; }
|
||||
[JsonProperty("ctime")] public long Ctime { get; set; }
|
||||
[JsonProperty("keywords")] public List<string> Keywords { get; set; }
|
||||
[JsonProperty("last_update_ts")] public long LastUpdate { get; set; }
|
||||
[JsonProperty("mtime")] public long Mtime { get; set; }
|
||||
[JsonProperty("raw_keywords")] public string RawKeywords { get; set; }
|
||||
[JsonProperty("series_id")] public long SeriesId { get; set; }
|
||||
[JsonProperty("state")] public int State { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/space/channel/video?mid={mid}&page_num={pageNum}&page_size={pageSize}
|
||||
public class SpaceSeasonsSeriesOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public SpaceSeasonsSeriesData Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeasonsSeriesData : BaseModel
|
||||
{
|
||||
[JsonProperty("items_lists")] public SpaceSeasonsSeries ItemsLists { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeasonsSeries : BaseModel
|
||||
{
|
||||
[JsonProperty("page")] public SpaceSeasonsSeriesPage Page { get; set; }
|
||||
[JsonProperty("seasons_list")] public List<SpaceSeasons> SeasonsList { get; set; }
|
||||
[JsonProperty("series_list")] public List<SpaceSeries> SeriesList { get; set; }
|
||||
}
|
||||
11
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsSeriesPage.cs
Normal file
11
DownKyi.Core/BiliApi/Users/Models/SpaceSeasonsSeriesPage.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceSeasonsSeriesPage : BaseModel
|
||||
{
|
||||
[JsonProperty("page_num")] public int PageNum;
|
||||
[JsonProperty("page_size")] public int PageSize;
|
||||
[JsonProperty("total")] public int Total;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
public class SpaceSeasonsSeriesStat : BaseModel
|
||||
{
|
||||
[JsonProperty("view")] public long View { get; set; }
|
||||
}
|
||||
24
DownKyi.Core/BiliApi/Users/Models/SpaceSeriesDetail.cs
Normal file
24
DownKyi.Core/BiliApi/Users/Models/SpaceSeriesDetail.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/series/archives?mid={mid}&series_id={seriesId}&only_normal=true&sort=desc&pn={pn}&ps={ps}
|
||||
public class SpaceSeriesDetailOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public SpaceSeriesDetail Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeriesDetail : BaseModel
|
||||
{
|
||||
[JsonProperty("aids")] public List<long> Aids { get; set; }
|
||||
|
||||
// page
|
||||
[JsonProperty("archives")] public List<SpaceSeasonsSeriesArchives> Archives { get; set; }
|
||||
}
|
||||
22
DownKyi.Core/BiliApi/Users/Models/SpaceSeriesMeta.cs
Normal file
22
DownKyi.Core/BiliApi/Users/Models/SpaceSeriesMeta.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://api.bilibili.com/x/series/series?series_id={seriesId}
|
||||
public class SpaceSeriesMetaOrigin : BaseModel
|
||||
{
|
||||
//[JsonProperty("code")]
|
||||
//public int Code { get; set; }
|
||||
//[JsonProperty("message")]
|
||||
//public string Message { get; set; }
|
||||
//[JsonProperty("ttl")]
|
||||
//public int Ttl { get; set; }
|
||||
[JsonProperty("data")] public SpaceSeriesMetaData Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSeriesMetaData : BaseModel
|
||||
{
|
||||
[JsonProperty("meta")] public SpaceSeriesMeta Meta { get; set; }
|
||||
[JsonProperty("recent_aids")] public List<long> RecentAids { get; set; }
|
||||
}
|
||||
17
DownKyi.Core/BiliApi/Users/Models/SpaceSettings.cs
Normal file
17
DownKyi.Core/BiliApi/Users/Models/SpaceSettings.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using DownKyi.Core.BiliApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DownKyi.Core.BiliApi.Users.Models;
|
||||
|
||||
// https://space.bilibili.com/ajax/settings/getSettings?mid={mid}
|
||||
public class SpaceSettingsOrigin : BaseModel
|
||||
{
|
||||
[JsonProperty("status")] public bool Status { get; set; }
|
||||
[JsonProperty("data")] public SpaceSettings Data { get; set; }
|
||||
}
|
||||
|
||||
public class SpaceSettings : BaseModel
|
||||
{
|
||||
// ...
|
||||
[JsonProperty("toutu")] public SpaceSettingsToutu Toutu { get; set; }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user