Skip to content

Commit d0ae719

Browse files
Merge pull request #193 from nICEnnnnnnnLee/dev
V6.31 Update
2 parents 6059e9e + 965e4f0 commit d0ae719

File tree

12 files changed

+115
-17
lines changed

12 files changed

+115
-17
lines changed

.github/release.info

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
* 新增: 添加功能,可以周期性地进行“一键下载”,并通报结果。
2-
* 优化: 现在按平台和架构编译了四个版本ffmpeg,缺省时符合条件的会提示进行下载:`win_amd64`、`linux_amd64`、`win_arm64`、`linux_arm64`
3-
* 优化: 现在补充完善了浏览器指纹等方面的cookie,期望是预防风控[#177](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/177), [#180](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/180)
4-
+ 因为尚不清楚相关机制,目前`通过API上传指纹`这一动作只在`刷新cookie`时才会进行。在遇到风控时,不妨先试一试菜单栏里的`刷新cookie`选项。
5-
+ 现在最好不要随意修改配置的UA,如果必要,需要在隐私模式下抓取cookie并抓包相应API的payload。详见配置页。
6-
* 修复: [#182](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/182) 考虑在`UP主所有视频`类型的链接解析时,keyword中含有空格的情况。
7-
* 删除: 移除解析分页链接时`promptAll`模式相关代码。
1+
* 新增: 重命名文件失败时,尝试添加序号继续重命名。[#185](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/185)
2+
+ 目的地址存在文件时,会在约定的名称末尾尝试添加`(01)、(02)...`这样的序号
3+
+ 通过配置`bilibili.name.autoNumber`可以开启/关闭该功能
4+
* 优化: 查询UP主所有链接时添加`dm_img`系列参数,防止返回352。(不登录也能用了)
5+
* 修复: 查询UP主所有链接时相关请求添加`referer`,防止返回412。[#192](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/192)
6+
* 其它常规优化,详见[V6.30...V6.31](https://github.com/nICEnnnnnnnLee/BilibiliDown/compare/V6.30...V6.31)
87
<hr/>
98

109
如果你是Win64用户,且没有java环境,请下载附件`*.win_x64_jre11.release.zip`

.github/workflows/document.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
run: npm run docs:build
3232

3333
- name: Deploy
34-
uses: peaceiris/actions-gh-pages@main
34+
uses: peaceiris/actions-gh-pages@v4
3535
with:
3636
github_token: ${{ secrets.GITHUB_TOKEN }}
3737
publish_dir: docs/.vitepress/dist

UPDATE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
## UPDATE
2+
* V6.31 `2024-05-08`
3+
* 新增: 重命名文件失败时,尝试添加序号继续重命名。[#185](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/185)
4+
+ 目的地址存在文件时,会在约定的名称末尾尝试添加`(01)、(02)...`这样的序号
5+
+ 通过配置`bilibili.name.autoNumber`可以开启/关闭该功能
6+
* 优化: 查询UP主所有链接时添加`dm_img`系列参数,防止返回352。(不登录也能用了)
7+
* 修复: 查询UP主所有链接时相关请求添加`referer`,防止返回412。[#192](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/192)
8+
* 其它常规优化,详见[V6.30...V6.31](https://github.com/nICEnnnnnnnLee/BilibiliDown/compare/V6.30...V6.31)
9+
210
* V6.30 `2024-02-23`
311
* 新增: 添加功能,可以周期性地进行“一键下载”,并通报结果。
412
* 优化: 现在按平台和架构编译了四个版本ffmpeg,缺省时符合条件的会提示进行下载:`win_amd64``linux_amd64``win_arm64``linux_arm64`

src/nicelee/bilibili/API.java

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
import java.io.UnsupportedEncodingException;
66
import java.net.HttpURLConnection;
77
import java.net.URL;
8-
import java.net.URLDecoder;
98
import java.net.URLEncoder;
109
import java.util.Arrays;
10+
import java.util.Base64;
1111
import java.util.Collections;
1212
import java.util.HashMap;
1313
import java.util.List;
1414
import java.util.Map;
15+
import java.util.Random;
1516
import java.util.regex.Matcher;
1617
import java.util.regex.Pattern;
1718
import java.util.stream.Collectors;
@@ -235,7 +236,12 @@ public static void uploadFingerprint() {
235236
String b_lsid = ResourcesUtil.randomHex(8) + "_" + Long.toHexString(currentTime).toUpperCase();
236237
HttpCookies.set("b_lsid", b_lsid);
237238
}
238-
239+
// 设置 browser_resolution
240+
Matcher mResolution = pResolution.matcher(Global.userAgentPayload);
241+
if(mResolution.find()) {
242+
String resolution = String.format("%s-%s", mResolution.group(1), mResolution.group(2));
243+
HttpCookies.set("browser_resolution", resolution);
244+
}
239245
// TODO payload
240246
String payload = Global.userAgentPayload;
241247
payload = payload.replaceFirst("\"5062\":\"[^\"]+\"", "\"5062\":\"" + currentTime + "\"");
@@ -293,10 +299,67 @@ public static String genNewFingerprint() {
293299
String buvid_fp = Global.userAgentFingerprint;
294300
kvMap.put("buvid_fp", buvid_fp);
295301
kvMap.put("fingerprint", buvid_fp);
302+
// 获取 browser_resolution
303+
Matcher mResolution = pResolution.matcher(Global.userAgentPayload);
304+
mResolution.find();
305+
String resolution = String.format("%s-%s", mResolution.group(1), mResolution.group(2));
306+
kvMap.put("browser_resolution", resolution);
296307
return HttpCookies.map2CookieStr(kvMap);
297308
} catch (IOException e) {
298309
e.printStackTrace();
299310
}
300311
return "";
301312
}
313+
314+
static String b64Sub2(String data) {
315+
try {
316+
String result = new String(Base64.getEncoder().encode(data.getBytes("UTF-8")), "UTF-8");
317+
result = result.substring(0, result.length() - 2);
318+
return result;
319+
} catch (UnsupportedEncodingException e) {
320+
throw new RuntimeException(e);
321+
}
322+
}
323+
324+
static Random random = new Random();
325+
326+
static String f114(int a, int b) {
327+
int t = random.nextInt(114);
328+
return String.format("[%d,%d,%d]", 2 * a + 2 * b + 3 * t, 4 * a - b + t, t);
329+
}
330+
331+
static String f514(int a, int b) {
332+
int t = random.nextInt(514);
333+
return String.format("[%d,%d,%d]", 3 * a + 2 * b + t, 4 * a - 4 * b + 2 * t, t);
334+
}
335+
336+
static Pattern pWebglVersion = Pattern.compile("\"webgl version:([^\"]+)\"");
337+
static Pattern pResolution = Pattern.compile("\"6e7c\":\"(\\d+)x(\\d+)\"");
338+
static Pattern pWebglUnRenderer = Pattern.compile("\"webgl unmasked renderer:([^\"]+)\"");
339+
static Pattern pWebglUnVendor = Pattern.compile("\"webgl unmasked vendor:([^\"]+)\"");
340+
341+
public static String genDmImgParams() {
342+
// TODO dm_img_list 浏览器加载完毕后,如果没什么动作,请求始终为[]
343+
String dm_img_list = "[]";
344+
// dm_img_str
345+
Matcher mWebglVersion = pWebglVersion.matcher(Global.userAgentPayload);
346+
mWebglVersion.find();
347+
String dm_img_str = b64Sub2(mWebglVersion.group(1).trim());
348+
// TODO dm_img_inter 浏览器加载完毕后第一个请求始终为
349+
// {"ds":[],"wh":f114(width, height),"of":f514(0,0)}
350+
Matcher mResolution = pResolution.matcher(Global.userAgentPayload);
351+
mResolution.find();
352+
String _wh = f114(Integer.parseInt(mResolution.group(1)), Integer.parseInt(mResolution.group(2)));
353+
String _of = f514(0, 0);
354+
String dm_img_inter = String.format("{\"ds\":[],\"wh\":%s,\"of\":%s}", _wh, _of);
355+
// dm_cover_img_str
356+
Matcher mWebglUnRenderer = pWebglUnRenderer.matcher(Global.userAgentPayload);
357+
mWebglUnRenderer.find();
358+
Matcher mWebglUnVendor = pWebglUnVendor.matcher(Global.userAgentPayload);
359+
mWebglUnVendor.find();
360+
String dm_cover_img_str = mWebglUnRenderer.group(1).trim() + mWebglUnVendor.group(1).trim();
361+
dm_cover_img_str = b64Sub2(dm_cover_img_str);
362+
return String.format("&dm_img_list=%s&dm_img_str=%s&dm_img_inter=%s&dm_cover_img_str=%s", dm_img_list,
363+
dm_img_str, dm_img_inter, dm_cover_img_str);
364+
}
302365
}

src/nicelee/bilibili/downloaders/Downloader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public boolean download(String url, String avId, int qn, int page) {
5151
try {
5252
this.downloader = downloader.getClass().newInstance();
5353
this.downloader.matches(url);
54+
break;
5455
} catch (InstantiationException | IllegalAccessException e) {
5556
}
5657
}

src/nicelee/bilibili/parsers/impl/URL4UPAllMedialistParser.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ public VideoInfo result(int pageSize, int page, Object... obj) {
142142
try {
143143
// 先获取合集信息
144144
HashMap<String, String> headers = new HttpHeaders().getCommonHeaders("api.bilibili.com");
145+
HashMap<String, String> headersRefer = new HashMap<>(headers);
146+
headersRefer.put("Referer", "https://space.bilibili.com/");
147+
headersRefer.put("Origin", "https://space.bilibili.com/");
145148
if (pageQueryResult.getVideoName() == null) {
146149
String url = "https://api.bilibili.com/x/v1/medialist/info?type=1&tid=0&biz_id=" + spaceID;
147150
Logger.println(url);
@@ -162,10 +165,10 @@ public VideoInfo result(int pageSize, int page, Object... obj) {
162165
break;
163166
}
164167
}
165-
String firstOid = position2Oid((page - 1) * pageSize + 1, headers, sortFieldParam);
168+
String firstOid = position2Oid((page - 1) * pageSize + 1, headersRefer, sortFieldParam);
166169
if(firstOid.equals("end"))
167170
return pageQueryResult;
168-
String lastOidPlus1 = position2Oid(page * pageSize + 1, headers, sortFieldParam);
171+
String lastOidPlus1 = position2Oid(page * pageSize + 1, headersRefer, sortFieldParam);
169172

170173
// 根据oid查询分页的详细信息
171174
String urlFormat = "https://api.bilibili.com/x/v2/medialist/resource/list?type=1&oid=%s&otype=2&biz_id=%s&bvid=&with_current=%s&mobi_app=web&ps=%d&direction=false&sort_field=%d&tid=%s&desc=true";
@@ -267,6 +270,7 @@ private String position2Oid(int pageNumber, HashMap<String, String> headers, Str
267270
// String urlFormat = "https://api.bilibili.com/x/space/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=&order=%s&jsonp=jsonp";
268271
String urlFormat = "https://api.bilibili.com/x/space/wbi/arc/search?mid=%s&ps=%d&tid=%s&special_type=&pn=%d&keyword=&order=%s&platform=web"; // &web_location=1550101&order_avoided=true
269272
String url = String.format(urlFormat, spaceID, 1, params.get("tid"), pageNumber, sortFieldParam);
273+
url += API.genDmImgParams();
270274
url = API.encWbi(url);
271275
String json = util.getContent(url, headers, HttpCookies.globalCookiesWithFingerprint());
272276
Logger.println(url);

src/nicelee/bilibili/parsers/impl/URL4UPAllParser.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,12 @@ protected boolean query(int page, int min, int max, Object... obj) {
8888
String urlFormat = "https://api.bilibili.com/x/space/wbi/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=%s&order=%s&platform=web"; // &web_location=1550101&order_avoided=true
8989
String keyword = API.encodeURL(params.get("keyword"));
9090
String url = String.format(urlFormat, spaceID, API_PMAX, params.get("tid"), page, keyword, params.get("order"));
91+
url += API.genDmImgParams();
9192
url = API.encWbi(url);
92-
String json = util.getContent(url, new HttpHeaders().getCommonHeaders("api.bilibili.com"), HttpCookies.globalCookiesWithFingerprint());
93+
HashMap<String, String> headersRefer = new HttpHeaders().getCommonHeaders("api.bilibili.com");
94+
headersRefer.put("Referer", "https://space.bilibili.com/");
95+
headersRefer.put("Origin", "https://space.bilibili.com/");
96+
String json = util.getContent(url, headersRefer, HttpCookies.globalCookiesWithFingerprint());
9397
Logger.println(url);
9498
Logger.println(json);
9599
JSONObject jobj = new JSONObject(json);

src/nicelee/bilibili/util/CmdUtil.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,17 @@ public synchronized static void convertOrAppendCmdToRenameBat(final String avid_
310310
File folder = file.getParentFile();
311311
if (!folder.exists())
312312
folder.mkdirs();
313-
originFile.renameTo(file);
313+
if((!originFile.renameTo(file)) && Global.autoNumberWhenFileExists) {// 如果不成功,大概率是文件名重复,在后面加上序号,类似于(01)
314+
for(int i = 1; i < 100; i++) {
315+
File f = new File(Global.savePath,
316+
String.format("%s(%02d)%s", formattedTitle, i, tail));
317+
Logger.println(f.getAbsolutePath());
318+
if(!f.exists()) {
319+
originFile.renameTo(f);
320+
break;
321+
}
322+
}
323+
}
314324
} else {
315325
File f = new File(Global.savePath, "rename.bat");
316326
boolean isExist = f.exists();

src/nicelee/bilibili/util/HttpCookies.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ public static boolean set(String key, String value) {
9999
return true;
100100
}
101101
}
102+
HttpCookie cCookie = new HttpCookie(key, value);
103+
globalCookiesWithFingerprint().add(cCookie);
102104
return false;
103105
}
104106
}

src/nicelee/ui/Global.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
public class Global {
2626
// 界面显示相关
27-
@Config(key = "bilibili.version", defaultValue = "v6.30", warning = false)
27+
@Config(key = "bilibili.version", defaultValue = "v6.31", warning = false)
2828
public static String version; // 一般情况下,我们不会设置这个标签,这个用于测试
2929
@Config(key = "bilibili.theme", note = "界面主题", defaultValue = "true", eq_true = "default", valids = { "default", "system" })
3030
public static boolean themeDefault;
@@ -109,6 +109,8 @@ public class Global {
109109
public static String cTimeFormat;
110110
@Config(key = "bilibili.name.doAfterComplete", note = "下载完成后自动重命名", defaultValue = "true", valids = { "true", "false" })
111111
public static boolean doRenameAfterComplete = true;
112+
@Config(key = "bilibili.name.autoNumber", note = "遇到同名文件自动添加序号", defaultValue = "true", valids = { "true", "false" })
113+
public static boolean autoNumberWhenFileExists = true;
112114
@Config(key = "bilibili.repo.definitionStrictMode", note = "是否将同一视频不同清晰度看作不同任务", defaultValue = "false", eq_true = "on", valids = { "on",
113115
"off" }) /* 存在某一清晰度后, 在下载另一种清晰度时是否判断已完成 */
114116
public static boolean repoInDefinitionStrictMode; //

0 commit comments

Comments
 (0)