Skip to content

Commit 5c29c85

Browse files
Merge pull request #283 from alley-rs/dev
2 parents 282f5a0 + ef96d4a commit 5c29c85

File tree

22 files changed

+191
-331
lines changed

22 files changed

+191
-331
lines changed

src-tauri/src/error.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ use std::fmt;
22

33
use serde::{Serialize, Serializer};
44

5-
use crate::eval::EvalError;
6-
7-
pub(super) type LsarResult<T> = std::result::Result<T, LsarError>;
5+
pub(super) type Result<T> = std::result::Result<T, LsarError>;
6+
pub(super) type LsarResult<T> = Result<T>;
87

98
#[derive(Debug, thiserror::Error)]
109
pub(super) enum LsarError {
@@ -40,8 +39,6 @@ pub(super) enum LsarError {
4039
#[error(transparent)]
4140
UrlParse(#[from] url::ParseError),
4241
#[error(transparent)]
43-
Eval(#[from] EvalError),
44-
#[error(transparent)]
4542
SerdeJSON(#[from] serde_json::Error),
4643
#[error(transparent)]
4744
VarError(#[from] std::env::VarError),
@@ -138,10 +135,6 @@ pub(super) enum MissKeyFieldError {
138135
/// 不是所有平台都支持分类,此成员仅用于部分平台
139136
#[error("解析分类失败")]
140137
Category,
141-
#[error("解析签名函数失败")]
142-
SignatureFunction,
143-
#[error("解析随机数失败")]
144-
RandomNumber,
145138
#[error("解析房间号失败,请检查房间号是否正确")]
146139
RoomId,
147140
}

src-tauri/src/eval.rs

Lines changed: 0 additions & 39 deletions
This file was deleted.

src-tauri/src/main.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
mod config;
55
mod data;
66
mod error;
7-
mod eval;
87
mod global;
98
mod http;
109
mod log;
@@ -30,7 +29,6 @@ use tauri::{AppHandle, Manager};
3029
use crate::config::{read_config_file, write_config_file};
3130
use crate::data::db::{delete_a_history_by_id, get_all_history, insert_a_history};
3231
use crate::error::LsarResult;
33-
use crate::eval::eval_result;
3432
use crate::http::{get, post};
3533
use crate::log::{debug, error, info, trace, warn};
3634
use crate::parsers::{parse_bigo, parse_bilibili, parse_douyin, parse_douyu, parse_huya, parse_yy};
@@ -113,7 +111,6 @@ fn main() {
113111
open,
114112
read_config_file,
115113
write_config_file,
116-
eval_result,
117114
parse_bigo,
118115
parse_douyu,
119116
parse_huya,

src-tauri/src/network/http.rs

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
use std::error::Error;
22

33
use bytes::Bytes;
4-
use reqwest::{header::CONTENT_TYPE, Body, Client as InnerClient, Response};
4+
use reqwest::{
5+
header::{HeaderMap, CONTENT_TYPE},
6+
Client as InnerClient, Response,
7+
};
58
use serde::{de::DeserializeOwned, Serialize};
6-
use tauri::http::HeaderMap;
79

810
use crate::error::{LsarError, LsarResult};
911

1012
#[derive(Clone)]
1113
pub struct Client {
1214
pub inner: InnerClient,
13-
headers: HeaderMap,
1415
}
1516

1617
impl Client {
1718
pub fn new() -> Self {
1819
trace!("Creating new HttpClient instance");
1920

20-
let headers = HeaderMap::default();
21-
2221
let inner = InnerClient::builder()
2322
.user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
2423
.build()
2524
.unwrap();
2625

27-
let client = Client { inner, headers };
26+
let client = Client { inner };
2827
debug!("HttpClient instance created with default headers");
2928
client
3029
}
@@ -43,9 +42,10 @@ impl Client {
4342
pub async fn send_request(
4443
&self,
4544
request: reqwest::RequestBuilder,
45+
headers: Option<HeaderMap>,
4646
) -> LsarResult<reqwest::Response> {
4747
request
48-
.headers(self.headers.clone())
48+
.headers(headers.unwrap_or_default())
4949
.send()
5050
.await
5151
.map_err(|e| {
@@ -56,7 +56,7 @@ impl Client {
5656

5757
pub async fn get(&self, url: &str) -> LsarResult<Response> {
5858
info!("Sending GET request to: {}", url);
59-
let response = self.send_request(self.inner.get(url)).await?;
59+
let response = self.send_request(self.inner.get(url), None).await?;
6060

6161
debug!("GET request successful, status: {}", response.status());
6262

@@ -91,9 +91,15 @@ impl Client {
9191
Ok(bytes)
9292
}
9393

94-
pub async fn get_json<T: DeserializeOwned>(&self, url: &str) -> LsarResult<T> {
94+
pub async fn get_json<T: DeserializeOwned, H: Into<Option<HeaderMap>>>(
95+
&self,
96+
url: &str,
97+
headers: H,
98+
) -> LsarResult<T> {
9599
info!("Sending GET request for JSON to: {}", url);
96-
let response = self.send_request(self.inner.get(url)).await?;
100+
let response = self
101+
.send_request(self.inner.get(url), headers.into())
102+
.await?;
97103

98104
debug!("GET request successful, headers: {:?}", response.headers());
99105

@@ -120,41 +126,21 @@ impl Client {
120126
Ok(json)
121127
}
122128

123-
pub async fn post<D: DeserializeOwned, T: Into<Body>>(
124-
&self,
125-
url: &str,
126-
body: T,
127-
) -> LsarResult<D> {
128-
info!("Sending POST request with body to: {}", url);
129-
130-
let request = self
131-
.inner
132-
.post(url)
133-
.body(body)
134-
.header(CONTENT_TYPE, "application/x-www-form-urlencoded");
135-
136-
let response = self.send_request(request).await?;
137-
138-
debug!("POST request successful, status: {}", response.status());
139-
let json = response.json().await.map_err(|e| {
140-
error!("Failed to parse JSON response from POST request: {}", e);
141-
LsarError::Http(e.into())
142-
})?;
143-
144-
trace!("JSON response from POST request parsed successfully");
145-
Ok(json)
146-
}
147-
148-
pub async fn post_form<D: DeserializeOwned, T: Serialize + ?Sized>(
129+
pub async fn post_form<
130+
D: DeserializeOwned,
131+
T: Serialize + ?Sized,
132+
H: Into<Option<HeaderMap>>,
133+
>(
149134
&self,
150135
url: &str,
151136
form: &T,
137+
headers: H,
152138
) -> LsarResult<D> {
153139
info!("Sending POST request with body to: {}", url);
154140

155141
let request = self.inner.post(url).form(form);
156142

157-
let response = self.send_request(request).await?;
143+
let response = self.send_request(request, headers.into()).await?;
158144

159145
debug!("POST request successful, status: {}", response.status());
160146
let json = response.json().await.map_err(|e| {
@@ -175,7 +161,7 @@ impl Client {
175161
.body(body.to_owned())
176162
.header(CONTENT_TYPE, "text/plain;charset=UTF-8");
177163

178-
let response = self.send_request(request).await?;
164+
let response = self.send_request(request, None).await?;
179165

180166
debug!("POST request successful, status: {}", response.status());
181167
let json = response.json().await.map_err(|e| {
@@ -193,7 +179,9 @@ impl Client {
193179
body: &S,
194180
) -> LsarResult<T> {
195181
info!("Sending POST request with JSON body to: {}", url);
196-
let response = self.send_request(self.inner.post(url).json(body)).await?;
182+
let response = self
183+
.send_request(self.inner.post(url).json(body), None)
184+
.await?;
197185

198186
debug!("POST request successful, status: {}", response.status());
199187
let json = response.json().await.map_err(|e| {

src-tauri/src/parsers/bigo/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl BigoParser {
4141
async fn get_real_url(&self) -> LsarResult<RoomInfo> {
4242
const URL: &str = "https://ta.bigo.tv/official_website/studio/getInternalStudioInfo";
4343
let body = [("siteId", self.room_id)];
44-
let resp: Response = self.http_client.post_form(URL, &body).await?;
44+
let resp: Response = self.http_client.post_form(URL, &body, None).await?;
4545

4646
Ok(resp.data)
4747
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
pub const DEVICE_ID: &str = "10000000000000000000000000001501";
1+
pub const DEVICE_ID: &str = "10000000000000000000000000003306";
22
pub const ROOM_OFFLINE_STATE: &str = "房间未开播";
33
pub const INVALID_REQUEST: &str = "非法请求";
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use reqwest::header::{HeaderMap, HeaderValue, REFERER};
2+
use serde::Deserialize;
3+
4+
use crate::error::{LsarError, Result};
5+
use crate::network::http::Client;
6+
use crate::parsers::douyu::constants::DEVICE_ID;
7+
use crate::utils::{md5, now};
8+
9+
#[derive(Debug, Deserialize)]
10+
struct EncryptionData {
11+
rand_str: String,
12+
key: String,
13+
enc_time: u8,
14+
is_special: u8,
15+
enc_data: String,
16+
}
17+
18+
#[derive(Debug, Deserialize)]
19+
struct EncryptionResponse {
20+
error: i8,
21+
msg: String,
22+
data: EncryptionData,
23+
}
24+
25+
#[derive(Debug)]
26+
pub struct Encryption {
27+
pub enc_data: String,
28+
pub ts: u64,
29+
pub auth: String,
30+
}
31+
32+
pub struct EncryptionFetcher {
33+
client: Client,
34+
}
35+
36+
impl EncryptionFetcher {
37+
pub fn new(client: Client) -> Self {
38+
Self { client }
39+
}
40+
41+
pub async fn fetch_encryption(&self, room_id: u64) -> Result<Encryption> {
42+
let url = format!(
43+
"https://www.douyu.com/wgapi/livenc/liveweb/websec/getEncryption?did={}",
44+
DEVICE_ID
45+
);
46+
let headers = HeaderMap::from_iter([(
47+
REFERER,
48+
HeaderValue::from_str(&format!("https://www.douyu.com/{}", room_id)).unwrap(),
49+
)]);
50+
let data: EncryptionResponse = self.client.get_json(&url, headers).await?;
51+
if data.error != 0 {
52+
return Err(LsarError::Other(format!(
53+
"Douyu encryption fetch failed: {}",
54+
data.msg
55+
)));
56+
}
57+
58+
let ts = now()?.as_secs();
59+
let sign_str = if data.data.is_special == 1 {
60+
"".to_string()
61+
} else {
62+
format!("{}{}", room_id, ts)
63+
};
64+
65+
let mut auth = data.data.rand_str;
66+
for _ in 0..data.data.enc_time {
67+
auth = md5(format!("{}{}", auth, data.data.key));
68+
}
69+
auth = md5(format!("{}{}{}", auth, data.data.key, sign_str));
70+
71+
Ok(Encryption {
72+
enc_data: data.data.enc_data,
73+
ts,
74+
auth,
75+
})
76+
}
77+
}

0 commit comments

Comments
 (0)