From 50ab1f7a5d8aeaa3720264b4a4b27805bb0e8121 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 5 Feb 2025 11:46:13 +0100 Subject: [PATCH] fix: retry updating deobf data after a RustyPipe update --- src/client/mod.rs | 26 ++++++++++++++++++-------- src/deobfuscate.rs | 8 ++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/client/mod.rs b/src/client/mod.rs index 745870e..2ef3a1f 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -519,7 +519,6 @@ struct CacheHolder { #[serde(default)] struct CacheData { clients: HashMap>, - #[serde(skip_serializing_if = "CacheEntry::is_none")] deobf: CacheEntry, #[serde(skip_serializing_if = "Option::is_none")] oauth_token: Option, @@ -541,6 +540,9 @@ struct CacheEntry { skip_serializing_if = "Option::is_none" )] retry_at: Option, + /// RustyPipe version that failed to updated the entry + #[serde(skip_serializing_if = "Option::is_none")] + failed_version: Option, data: Option, } @@ -575,10 +577,21 @@ impl CacheEntry { self.data.is_none() } + /// Retry updating a cache entry only after a delay or a RustyPipe update fn should_retry(&self) -> bool { self.retry_at .map(|d| OffsetDateTime::now_utc() > d) .unwrap_or(true) + || self + .failed_version + .as_deref() + .map(|v| crate::VERSION != v) + .unwrap_or(true) + } + + fn retry_later(&mut self, delay_h: i64) { + self.retry_at = Some(util::now_sec() + time::Duration::hours(delay_h)); + self.failed_version = Some(crate::VERSION.to_owned()); } } @@ -587,6 +600,7 @@ impl From for CacheEntry { Self { last_update: Some(util::now_sec()), retry_at: None, + failed_version: None, data: Some(f), } } @@ -1071,7 +1085,7 @@ impl RustyPipe { return version.into(); } Err(e) => { - client.retry_at = Some(util::now_sec() + time::Duration::hours(1)); + client.retry_later(1); drop(client); self.store_cache().await; tracing::warn!( @@ -1108,11 +1122,7 @@ impl RustyPipe { if deobf_data.should_retry() { tracing::debug!("getting deobf data"); - match DeobfData::extract( - self.inner.http.clone(), - self.inner.reporter.as_deref(), - ) - .await + match DeobfData::extract(&self.inner.http, self.inner.reporter.as_deref()).await { Ok(new_data) => { // Write new data to the cache @@ -1123,7 +1133,7 @@ impl RustyPipe { } Err(e) => { // Try to fall back to expired cache data if available, otherwise return error - deobf_data.retry_at = Some(util::now_sec() + time::Duration::days(1)); + deobf_data.retry_later(24); let res = match deobf_data.get_expired() { Some(d) => { tracing::warn!("could not get new deobf data ({e}), falling back to expired cache"); diff --git a/src/deobfuscate.rs b/src/deobfuscate.rs index e1bc68e..d0adc12 100644 --- a/src/deobfuscate.rs +++ b/src/deobfuscate.rs @@ -29,9 +29,9 @@ impl DeobfData { /// Download and extract the latest deobfuscation data from YouTube /// /// Creates a report if the data could not be extracted - pub async fn extract(http: Client, reporter: Option<&dyn Reporter>) -> Result { - let js_url = get_player_js_url(&http).await?; - let player_js = get_response(&http, &js_url).await?; + pub async fn extract(http: &Client, reporter: Option<&dyn Reporter>) -> Result { + let js_url = get_player_js_url(http).await?; + let player_js = get_response(http, &js_url).await?; tracing::debug!("downloaded player.js from {}", js_url); let res = Self::extract_fns(&js_url, &player_js); @@ -690,7 +690,7 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c #[traced_test] async fn t_update() { let client = Client::new(); - let deobf_data = DeobfData::extract(client, None).await.unwrap(); + let deobf_data = DeobfData::extract(&client, None).await.unwrap(); let deobf = Deobfuscator::new(&deobf_data).unwrap(); let deobf_sig = deobf.deobfuscate_sig("GOqGOqGOq0QJ8wRAIgaryQHfplJ9xJSKFywyaSMHuuwZYsoMTAvRvfm51qIGECIA5061zWeyfMPX9hEl_U6f9J0tr7GTJMKyPf5XNrJb5fb5i").unwrap();