diff --git a/src-tauri/src/bili_client.rs b/src-tauri/src/bili_client.rs index f6cbbca..be846dd 100644 --- a/src-tauri/src/bili_client.rs +++ b/src-tauri/src/bili_client.rs @@ -309,16 +309,17 @@ impl BiliClient { } pub async fn get_image_index(&self, episode_id: i64) -> anyhow::Result { - let access_token = self.access_token(); + let cookie = self.cookie(); let params = json!({ - "device": "android", - "access_key": access_token, + "platform": "web", + "device": "pc", }); - let payload = json!({"epId": episode_id}); - // 发送获取ImageIndexRespData的请求 + let payload = json!({"ep_id": episode_id}); + // 发送获取ImageIndex的请求 let http_resp = Self::client() .post("https://manga.bilibili.com/twirp/comic.v1.Comic/GetImageIndex") .query(¶ms) + .header("cookie", cookie) .json(&payload) .send() .await?; @@ -355,17 +356,37 @@ impl BiliClient { Ok(image_index_data) } - pub async fn get_image_token(&self, urls: &Vec) -> anyhow::Result { - let cookie = self.app.state::>().read().get_cookie(); + pub async fn get_image_token( + &self, + urls: &Vec, + from_web_api: bool, + ) -> anyhow::Result { + let url = "https://manga.bilibili.com/twirp/comic.v1.Comic/ImageToken"; let urls_str = serde_json::to_string(urls)?; let payload = json!({"urls": urls_str}); + // 构造获取ImageToken的请求 + let http_req = if from_web_api { + let cookie = self.cookie(); + let params = json!({ + "platform": "web", + "device": "pc", + }); + Self::client() + .post(url) + .query(¶ms) + .header("cookie", cookie) + .json(&payload) + } else { + let access_token = self.access_token(); + let params = json!({ + "mobi_app": "android_comic", + "version": "6.5.0", + "access_key": access_token, + }); + Self::client().post(url).query(¶ms).json(&payload) + }; // 发送获取ImageToken的请求 - let http_resp = Self::client() - .post("https://manga.bilibili.com/twirp/comic.v1.Comic/ImageToken") - .header("cookie", cookie) - .json(&payload) - .send() - .await?; + let http_resp = http_req.send().await?; // 检查http响应状态码 let status = http_resp.status(); let body = http_resp.text().await?; @@ -402,6 +423,10 @@ impl BiliClient { .access_token .clone() } + + fn cookie(&self) -> String { + self.app.state::>().read().get_cookie() + } } fn app_sign(mut params: BTreeMap) -> BTreeMap { diff --git a/src-tauri/src/download_manager.rs b/src-tauri/src/download_manager.rs index bf9e731..e372f2c 100644 --- a/src-tauri/src/download_manager.rs +++ b/src-tauri/src/download_manager.rs @@ -151,7 +151,7 @@ impl DownloadManager { .iter() .map(|img| img.path.clone()) .collect(); - let image_token_data_data = bili_client.get_image_token(&urls).await?; + let image_token_data_data = bili_client.get_image_token(&urls, true).await?; let temp_download_dir = get_ep_temp_download_dir(&self.app, &ep_info); std::fs::create_dir_all(&temp_download_dir) @@ -313,7 +313,9 @@ impl DownloadManager { let http_client = create_http_client(); let bili_client = self.bili_client(); - let image_token_data_data = bili_client.get_image_token(&album_plus_item.pic).await?; + let image_token_data_data = bili_client + .get_image_token(&album_plus_item.pic, false) + .await?; let temp_download_dir = get_album_plus_temp_download_dir(&self.app, &album_plus_item); std::fs::create_dir_all(&temp_download_dir) @@ -427,20 +429,17 @@ impl DownloadManager { return; } }; - // 取出url中query部分的cpx参数 - let Some((_, cpx)) = parsed_url.query_pairs().find(|(key, _)| key == "cpx") else { - let err = anyhow!("图片链接 {url} 中没有cpx参数"); - emit_error_event(&self.app, id, url.to_string(), err.to_string()); - return; - }; - // 解密图片数据 - let image_data = match decrypt_img_data(image_data, &cpx) { - Ok(data) => data, - Err(err) => { - let err = err.context(format!("解密图片 {url} 失败")); - emit_error_event(&self.app, id, url, err.to_string_chain()); - return; - } + // 如果 parsed_url 里能找到cpx参数,则解密图片数据,否则用原始数据 + let image_data = match parsed_url.query_pairs().find(|(key, _)| key == "cpx") { + Some((_, cpx)) => match decrypt_img_data(image_data, &cpx) { + Ok(data) => data, + Err(err) => { + let err = err.context(format!("解密图片 {url} 失败")); + emit_error_event(&self.app, id, url, err.to_string_chain()); + return; + } + }, + None => image_data, }; // 保存图片 if let Err(err) = std::fs::write(&save_path, &image_data).map_err(anyhow::Error::from) {