diff --git a/src/DownKyi.Core/BiliApi/Sign/WbiSign.cs b/src/DownKyi.Core/BiliApi/Sign/WbiSign.cs
new file mode 100644
index 0000000..4d584dc
--- /dev/null
+++ b/src/DownKyi.Core/BiliApi/Sign/WbiSign.cs
@@ -0,0 +1,120 @@
+using DownKyi.Core.Settings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace DownKyi.Core.BiliApi.Sign
+{
+ public static class WbiSign
+ {
+
+ ///
+ /// 打乱重排实时口令
+ ///
+ ///
+ ///
+ private static string GetMixinKey(string origin)
+ {
+ int[] mixinKeyEncTab = new int[]
+ {
+ 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
+ 33, 9, 42, 19, 29, 28, 14, 39,12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
+ 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
+ 36, 20, 34, 44, 52
+ };
+
+ var temp = new StringBuilder();
+ foreach (var i in mixinKeyEncTab)
+ {
+ temp.Append(origin[i]);
+ }
+ return temp.ToString().Substring(0, 32);
+ }
+
+ ///
+ /// 将字典参数转为字符串
+ ///
+ ///
+ ///
+ public static string ParametersToQuery(Dictionary parameters)
+ {
+ var keys = parameters.Keys.ToList();
+ var queryList = new List();
+ foreach (var item in keys)
+ {
+ var value = parameters[item];
+ queryList.Add($"{item}={value}");
+ }
+ return string.Join("&", queryList);
+ }
+
+ ///
+ /// Wbi签名,返回所有参数字典
+ ///
+ ///
+ ///
+ public static Dictionary EncodeWbi(Dictionary parameters)
+ {
+ return EncodeWbi(parameters, GetKey().Item1, GetKey().Item2);
+ }
+
+ ///
+ /// Wbi签名,返回所有参数字典
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Dictionary EncodeWbi(Dictionary parameters, string imgKey, string subKey)
+ {
+ var mixinKey = GetMixinKey(imgKey + subKey);
+
+ var chrFilter = new Regex("[!'()*]");
+
+ var newParameters = new Dictionary
+ {
+ { "wts", (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds }
+ };
+
+ foreach (var para in parameters)
+ {
+ var key = para.Key;
+ var value = para.Value.ToString();
+
+ var encodedValue = chrFilter.Replace(value, "");
+
+ newParameters.Add(Uri.EscapeDataString(key), Uri.EscapeDataString(encodedValue));
+ }
+
+ var keys = newParameters.Keys.ToList();
+ keys.Sort();
+
+ var queryList = new List();
+ foreach (var item in keys)
+ {
+ var value = newParameters[item];
+ queryList.Add($"{item}={value}");
+ }
+
+ var queryString = string.Join("&", queryList);
+ var md5Hasher = MD5.Create();
+ var hashStr = queryString + mixinKey;
+ var hashedQueryString = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(hashStr));
+ var wbiSign = BitConverter.ToString(hashedQueryString).Replace("-", "").ToLower();
+
+ newParameters.Add("w_rid", wbiSign);
+ return newParameters;
+ }
+
+ public static Tuple GetKey()
+ {
+ var user = SettingsManager.GetInstance().GetUserInfo();
+
+ return new Tuple(user.ImgKey, user.SubKey);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/DownKyi.Core/BiliApi/Users/Models/UserInfoForNavigation.cs b/src/DownKyi.Core/BiliApi/Users/Models/UserInfoForNavigation.cs
index 0801dd3..d1256dc 100644
--- a/src/DownKyi.Core/BiliApi/Users/Models/UserInfoForNavigation.cs
+++ b/src/DownKyi.Core/BiliApi/Users/Models/UserInfoForNavigation.cs
@@ -53,6 +53,9 @@ namespace DownKyi.Core.BiliApi.Users.Models
//public int vip_theme_type { get; set; }
[JsonProperty("wallet")]
public UserInfoWallet Wallet { get; set; }
+
+ [JsonProperty("wbi_img")]
+ public Wbi Wbi { get; set; }
}
//public class NavDataLevelInfo
@@ -105,4 +108,14 @@ namespace DownKyi.Core.BiliApi.Users.Models
[JsonProperty("mid")]
public long Mid { get; set; }
}
+
+ [JsonObject]
+ public class Wbi
+ {
+ [JsonProperty("img_url")]
+ public string ImgUrl { get; set; }
+ [JsonProperty("sub_url")]
+ public string SubUrl { get; set; }
+ }
+
}
diff --git a/src/DownKyi.Core/BiliApi/Users/UserInfo.cs b/src/DownKyi.Core/BiliApi/Users/UserInfo.cs
index 175f1e3..d6d1a21 100644
--- a/src/DownKyi.Core/BiliApi/Users/UserInfo.cs
+++ b/src/DownKyi.Core/BiliApi/Users/UserInfo.cs
@@ -1,7 +1,9 @@
-using DownKyi.Core.BiliApi.Users.Models;
+using DownKyi.Core.BiliApi.Sign;
+using DownKyi.Core.BiliApi.Users.Models;
using DownKyi.Core.Logging;
using Newtonsoft.Json;
using System;
+using System.Collections.Generic;
namespace DownKyi.Core.BiliApi.Users
{
@@ -43,7 +45,12 @@ namespace DownKyi.Core.BiliApi.Users
///
public static UserInfoForSpace GetUserInfoForSpace(long mid)
{
- string url = $"https://api.bilibili.com/x/space/wbi/acc/info?mid={mid}";
+ var parameters = new Dictionary
+ {
+ { "mid", mid }
+ };
+ string query = WbiSign.ParametersToQuery(WbiSign.EncodeWbi(parameters));
+ string url = $"https://api.bilibili.com/x/space/wbi/acc/info?{query}";
string referer = "https://www.bilibili.com";
string response = WebClient.RequestWeb(url, referer);
diff --git a/src/DownKyi.Core/BiliApi/Users/UserSpace.cs b/src/DownKyi.Core/BiliApi/Users/UserSpace.cs
index c76af60..4072cf1 100644
--- a/src/DownKyi.Core/BiliApi/Users/UserSpace.cs
+++ b/src/DownKyi.Core/BiliApi/Users/UserSpace.cs
@@ -1,4 +1,5 @@
-using DownKyi.Core.BiliApi.Users.Models;
+using DownKyi.Core.BiliApi.Sign;
+using DownKyi.Core.BiliApi.Users.Models;
using DownKyi.Core.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -114,7 +115,17 @@ namespace DownKyi.Core.BiliApi.Users
///
public static SpacePublicationList GetPublication(long mid, int pn, int ps, long tid = 0, PublicationOrder order = PublicationOrder.PUBDATE, string keyword = "")
{
- string url = $"https://api.bilibili.com/x/space/wbi/arc/search?mid={mid}&pn={pn}&ps={ps}&order={order.ToString("G").ToLower()}&tid={tid}&keyword={keyword}";
+ var parameters = new Dictionary
+ {
+ { "mid", mid },
+ { "pn", pn },
+ { "ps", ps },
+ { "order", order.ToString("G").ToLower() },
+ { "tid", tid },
+ { "keyword", keyword },
+ };
+ string query = WbiSign.ParametersToQuery(WbiSign.EncodeWbi(parameters));
+ string url = $"https://api.bilibili.com/x/space/wbi/arc/search?{query}";
string referer = "https://www.bilibili.com";
string response = WebClient.RequestWeb(url, referer);
diff --git a/src/DownKyi.Core/DownKyi.Core.csproj b/src/DownKyi.Core/DownKyi.Core.csproj
index c919ea6..2a9a3fb 100644
--- a/src/DownKyi.Core/DownKyi.Core.csproj
+++ b/src/DownKyi.Core/DownKyi.Core.csproj
@@ -186,6 +186,7 @@
+
diff --git a/src/DownKyi.Core/Settings/Models/UserInfoSettings.cs b/src/DownKyi.Core/Settings/Models/UserInfoSettings.cs
index 774b7ec..63debc7 100644
--- a/src/DownKyi.Core/Settings/Models/UserInfoSettings.cs
+++ b/src/DownKyi.Core/Settings/Models/UserInfoSettings.cs
@@ -6,5 +6,8 @@
public string Name { get; set; }
public bool IsLogin { get; set; } // 是否登录
public bool IsVip { get; set; } // 是否为大会员,未登录时为false
+
+ public string ImgKey { get; set; }
+ public string SubKey { get; set; }
}
}
diff --git a/src/DownKyi/Languages/Default.xaml b/src/DownKyi/Languages/Default.xaml
index b6ca780..19cebae 100644
--- a/src/DownKyi/Languages/Default.xaml
+++ b/src/DownKyi/Languages/Default.xaml
@@ -200,7 +200,7 @@
启用https(若下载器提示SSL错误,则关闭此项)
UserAgent:
选择下载器(重启生效):
- 内建下载器(测试)
+ 内建下载器
Aria2下载器
自定义Aria2下载器
Aria服务器地址:
diff --git a/src/DownKyi/Services/Download/DownloadService.cs b/src/DownKyi/Services/Download/DownloadService.cs
index acea7a1..c6297bc 100644
--- a/src/DownKyi/Services/Download/DownloadService.cs
+++ b/src/DownKyi/Services/Download/DownloadService.cs
@@ -20,14 +20,13 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
namespace DownKyi.Services.Download
{
public abstract class DownloadService
{
protected string Tag = "DownloadService";
- protected TaskbarIcon _notifyIcon;
+ protected TaskbarIcon _notifyIcon;
protected IDialogService dialogService;
protected ObservableCollection downloadingList;
protected ObservableCollection downloadedList;
diff --git a/src/DownKyi/ViewModels/ViewIndexViewModel.cs b/src/DownKyi/ViewModels/ViewIndexViewModel.cs
index 9eaeb10..37aff24 100644
--- a/src/DownKyi/ViewModels/ViewIndexViewModel.cs
+++ b/src/DownKyi/ViewModels/ViewIndexViewModel.cs
@@ -1,4 +1,5 @@
using DownKyi.Core.BiliApi.Users;
+using DownKyi.Core.BiliApi.Users.Models;
using DownKyi.Core.Logging;
using DownKyi.Core.Settings;
using DownKyi.Core.Settings.Models;
@@ -12,6 +13,7 @@ using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.IO;
+using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
@@ -227,6 +229,36 @@ namespace DownKyi.ViewModels
InputText = string.Empty;
}
+ private UserInfoForNavigation GetUserInfo()
+ {
+ // 获取用户信息
+ var userInfo = UserInfo.GetUserInfoForNavigation();
+ if (userInfo != null)
+ {
+ SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
+ {
+ Mid = userInfo.Mid,
+ Name = userInfo.Name,
+ IsLogin = userInfo.IsLogin,
+ IsVip = userInfo.VipStatus == 1,
+ ImgKey = userInfo.Wbi.ImgUrl.Split('/').ToList().Last().Split('.')[0],
+ SubKey = userInfo.Wbi.SubUrl.Split('/').ToList().Last().Split('.')[0],
+ });
+ }
+ else
+ {
+ SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
+ {
+ Mid = -1,
+ Name = "",
+ IsLogin = false,
+ IsVip = false,
+ });
+ }
+
+ return userInfo;
+ }
+
///
/// 更新用户登录信息
///
@@ -248,27 +280,7 @@ namespace DownKyi.ViewModels
await Task.Run(new Action(() =>
{
// 获取用户信息
- var userInfo = UserInfo.GetUserInfoForNavigation();
- if (userInfo != null)
- {
- SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
- {
- Mid = userInfo.Mid,
- Name = userInfo.Name,
- IsLogin = userInfo.IsLogin,
- IsVip = userInfo.VipStatus == 1
- });
- }
- else
- {
- SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
- {
- Mid = -1,
- Name = "",
- IsLogin = false,
- IsVip = false
- });
- }
+ var userInfo = GetUserInfo();
PropertyChangeAsync(new Action(() =>
{
@@ -318,21 +330,27 @@ namespace DownKyi.ViewModels
{
return;
}
+
// 启动
if (parameter == "start")
{
UpdateUserInfo();
}
// 从登录页面返回
- if (parameter == "login")
+ else if (parameter == "login")
{
UpdateUserInfo();
}
// 注销
- if (parameter == "logout")
+ else if (parameter == "logout")
{
UpdateUserInfo();
}
+ // 其他情况只更新设置的用户信息,不更新UI
+ else
+ {
+ GetUserInfo();
+ }
}