Store an origin URL on every movie that is loaded.

This commit is contained in:
David Wendt 2020-07-21 23:57:43 -04:00
parent 7f7281493f
commit 6998dafdb9
8 changed files with 31 additions and 13 deletions

View File

@ -1246,6 +1246,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
context.player.clone().unwrap(),
level,
fetch,
url,
None,
);
context.navigator.spawn_future(process);
@ -1336,6 +1337,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
context.player.clone().unwrap(),
clip_target,
fetch,
url.to_string(),
None,
);
context.navigator.spawn_future(process);

View File

@ -1096,6 +1096,7 @@ fn load_movie<'gc>(
context.player.clone().unwrap(),
DisplayObject::MovieClip(target),
fetch,
url.to_string(),
None,
);

View File

@ -135,6 +135,7 @@ pub fn load_clip<'gc>(
context.player.clone().unwrap(),
DisplayObject::MovieClip(movieclip),
fetch,
url.to_string(),
Some(this),
);

View File

@ -34,7 +34,8 @@ impl<'gc> Button<'gc> {
) -> Self {
let mut actions = vec![];
for action in &button.actions {
let action_data = source_movie.owned_subslice(action.action_data.clone());
let action_data =
source_movie.owned_subslice(action.action_data.clone(), &source_movie.movie);
for condition in &action.conditions {
let button_action = ButtonAction {
action_data: action_data.clone(),

View File

@ -2567,7 +2567,7 @@ impl ClipAction {
let len = other.action_data.len();
let key_code = other.key_code;
let movie = Arc::new(movie.from_movie_and_subdata(other.action_data));
let movie = Arc::new(movie.from_movie_and_subdata(other.action_data, &movie));
other.events.into_iter().map(move |event| Self {
event: match event {
ClipEventFlag::Construct => ClipEvent::Construct,

View File

@ -116,6 +116,7 @@ impl<'gc> LoadManager<'gc> {
player: Weak<Mutex<Player>>,
target_clip: DisplayObject<'gc>,
fetch: OwnedFuture<Vec<u8>, Error>,
url: String,
target_broadcaster: Option<Object<'gc>>,
) -> OwnedFuture<(), Error> {
let loader = Loader::Movie {
@ -129,7 +130,7 @@ impl<'gc> LoadManager<'gc> {
let loader = self.get_loader_mut(handle).unwrap();
loader.introduce_loader_handle(handle);
loader.movie_loader(player, fetch)
loader.movie_loader(player, fetch, url)
}
/// Indicates that a movie clip has initialized (ran it's first frame).
@ -331,6 +332,7 @@ impl<'gc> Loader<'gc> {
&mut self,
player: Weak<Mutex<Player>>,
fetch: OwnedFuture<Vec<u8>, Error>,
url: String,
) -> OwnedFuture<(), Error> {
let handle = match self {
Loader::Movie { self_handle, .. } => self_handle.expect("Loader not self-introduced"),
@ -375,7 +377,8 @@ impl<'gc> Loader<'gc> {
},
)?;
let data = (fetch.await).and_then(|data| Ok((data.len(), SwfMovie::from_data(&data)?)));
let data = (fetch.await)
.and_then(|data| Ok((data.len(), SwfMovie::from_data(&data, Some(url))?)));
if let Ok((length, movie)) = data {
let movie = Arc::new(movie);

View File

@ -17,6 +17,9 @@ pub struct SwfMovie {
/// Uncompressed SWF data.
data: Vec<u8>,
/// The URL the SWF was downloaded from.
url: Option<String>,
}
impl SwfMovie {
@ -31,25 +34,32 @@ impl SwfMovie {
num_frames: 0,
},
data: vec![],
url: None,
}
}
/// Construct a movie from an existing movie with any particular data on it.
pub fn from_movie_and_subdata(&self, data: Vec<u8>) -> Self {
/// Construct a movie from an existing movie with any particular data on
/// it.
///
/// Use of this method is discouraged. SWF data should be borrowed or
/// sliced as necessary to refer to partial sections of a file.
pub fn from_movie_and_subdata(&self, data: Vec<u8>, source: &SwfMovie) -> Self {
Self {
header: self.header.clone(),
data,
url: source.url.clone(),
}
}
/// Utility method to construct a movie from a file on disk.
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
let url = path.as_ref().to_string_lossy().to_owned().to_string();
let data = std::fs::read(path)?;
Self::from_data(&data)
Self::from_data(&data, Some(url))
}
/// Construct a movie based on the contents of the SWF datastream.
pub fn from_data(swf_data: &[u8]) -> Result<Self, Error> {
pub fn from_data(swf_data: &[u8], url: Option<String>) -> Result<Self, Error> {
let swf_stream = swf::read::read_swf_header(&swf_data[..])?;
let header = swf_stream.header;
let mut reader = swf_stream.reader;
@ -74,7 +84,7 @@ impl SwfMovie {
data
};
Ok(Self { header, data })
Ok(Self { header, data, url })
}
pub fn header(&self) -> &Header {
@ -141,12 +151,12 @@ impl SwfSlice {
/// Construct a new slice with a given dataset only.
///
/// This is used primarily for converting owned data back into a slice: we
/// reattach the SWF data that we can
pub fn owned_subslice(&self, data: Vec<u8>) -> Self {
/// reattach the SWF data to a fresh movie and return a new slice into it.
pub fn owned_subslice(&self, data: Vec<u8>, source: &SwfMovie) -> Self {
let len = data.len();
Self {
movie: Arc::new(self.movie.from_movie_and_subdata(data)),
movie: Arc::new(self.movie.from_movie_and_subdata(data, source)),
start: 0,
end: len,
}

View File

@ -113,7 +113,7 @@ impl Ruffle {
let movie = {
let mut data = vec![0; swf_data.length() as usize];
swf_data.copy_to(&mut data[..]);
SwfMovie::from_data(&data)?
SwfMovie::from_data(&data, None)?
};
let window = web_sys::window().ok_or_else(|| "Expected window")?;