From 1aedb7ff8d831d3a7dd28a4c1a2f15ddacb77ed8 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Tue, 28 Feb 2023 17:14:54 +0100 Subject: [PATCH] core: Add CompatibilityRules struct for on-the-fly replacements for compatibility. Initially konggames -> kongregate.com rules --- core/src/compatibility_rules.rs | 42 +++++++++++++++++++++++++++++++++ core/src/lib.rs | 1 + core/src/loader.rs | 11 ++++++--- core/src/player.rs | 11 +++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 core/src/compatibility_rules.rs diff --git a/core/src/compatibility_rules.rs b/core/src/compatibility_rules.rs new file mode 100644 index 000000000..d5e54b3cd --- /dev/null +++ b/core/src/compatibility_rules.rs @@ -0,0 +1,42 @@ +use regress::Regex; + +#[derive(Debug, Clone)] +pub struct UrlRewriteRule { + pub pattern: Regex, + pub replacement: String, +} + +#[derive(Debug, Default, Clone)] +pub struct CompatibilityRules { + swf_url_rewrite_rules: Vec, +} + +impl CompatibilityRules { + pub fn empty() -> Self { + Self::default() + } + + pub fn builtin_rules() -> Self { + Self { + swf_url_rewrite_rules: vec![UrlRewriteRule { + pattern: Regex::new(r"//game(\d+).konggames.com").expect("Regex must compile"), + replacement: "//kongregate.com".to_string(), + }], + } + } + + pub fn rewrite_swf_url(&self, original_url: String) -> String { + let mut url = original_url.clone(); + for rule in &self.swf_url_rewrite_rules { + if let Some(found) = rule.pattern.find(&url) { + url.replace_range(found.range, &rule.replacement); + } + } + + if original_url != url { + tracing::info!("Rewritten SWF url from {original_url} to {url}"); + } + + url + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs index e6082c7c6..1470c3ac9 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -44,6 +44,7 @@ mod vminterface; mod xml; pub mod backend; +pub mod compatibility_rules; pub mod config; pub mod external; pub mod stub; diff --git a/core/src/loader.rs b/core/src/loader.rs index 6f8128114..10ffa28ec 100644 --- a/core/src/loader.rs +++ b/core/src/loader.rs @@ -696,14 +696,19 @@ impl<'gc> Loader<'gc> { })?; // The spoofed root movie URL takes precedence over the actual URL. - let url = player + let swf_url = player + .lock() + .unwrap() + .compatibility_rules() + .rewrite_swf_url(response.url); + let spoofed_or_swf_url = player .lock() .unwrap() .spoofed_url() .map(|u| u.to_string()) - .unwrap_or(response.url); + .unwrap_or(swf_url); - let mut movie = SwfMovie::from_data(&response.body, url, None)?; + let mut movie = SwfMovie::from_data(&response.body, spoofed_or_swf_url, None)?; on_metadata(movie.header()); movie.append_parameters(parameters); player.lock().unwrap().set_root_movie(movie); diff --git a/core/src/player.rs b/core/src/player.rs index cbfaf012e..09d8f61e5 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -17,6 +17,7 @@ use crate::backend::{ storage::StorageBackend, ui::{InputManager, MouseCursor, UiBackend}, }; +use crate::compatibility_rules::CompatibilityRules; use crate::config::Letterbox; use crate::context::{ActionQueue, ActionType, RenderContext, UpdateContext}; use crate::context_menu::{ @@ -296,6 +297,9 @@ pub struct Player { /// The root SWF URL provided to ActionScript. If None, /// the actual loaded url will be used spoofed_url: Option, + + /// Any compatibility rules to apply for this movie. + compatibility_rules: CompatibilityRules, } impl Player { @@ -1886,6 +1890,10 @@ impl Player { self.spoofed_url.as_deref() } + pub fn compatibility_rules(&self) -> &CompatibilityRules { + &self.compatibility_rules + } + pub fn log_backend(&self) -> &Log { &self.log } @@ -1931,6 +1939,7 @@ pub struct PlayerBuilder { warn_on_unsupported_content: bool, load_behavior: LoadBehavior, spoofed_url: Option, + compatibility_rules: CompatibilityRules, player_version: Option, quality: StageQuality, sandbox_type: SandboxType, @@ -1971,6 +1980,7 @@ impl PlayerBuilder { warn_on_unsupported_content: true, load_behavior: LoadBehavior::Streaming, spoofed_url: None, + compatibility_rules: CompatibilityRules::builtin_rules(), player_version: None, quality: StageQuality::High, sandbox_type: SandboxType::LocalTrusted, @@ -2198,6 +2208,7 @@ impl PlayerBuilder { self_reference: self_ref.clone(), load_behavior: self.load_behavior, spoofed_url: self.spoofed_url.clone(), + compatibility_rules: self.compatibility_rules.clone(), stub_tracker: StubCollection::new(), // GC data