avm2: Initialize the loaderURL for empty movies

Fixes #14217
This commit is contained in:
Tom Schuster 2024-08-31 21:55:52 +02:00
parent 2fd8f600bc
commit 7e064bffc4
5 changed files with 22 additions and 10 deletions

View File

@ -40,7 +40,7 @@ pub fn loader_allocator<'gc>(
// us the correct value (0) for them.
let loader_info = LoaderInfoObject::not_yet_loaded(
activation,
Arc::new(SwfMovie::empty(activation.context.swf.version())),
Arc::new(SwfMovie::empty_child(activation.context.swf)),
Some(loader),
None,
false,
@ -93,7 +93,7 @@ pub fn load<'gc>(
// This is a dummy MovieClip, which will get overwritten in `Loader`
let content = MovieClip::new(
Arc::new(SwfMovie::empty(activation.context.swf.version())),
Arc::new(SwfMovie::empty_child(activation.context.swf)),
activation.context.gc_context,
);
@ -103,7 +103,7 @@ pub fn load<'gc>(
.unwrap()
.set_loader_stream(
LoaderStream::NotYetLoaded(
Arc::new(SwfMovie::empty(activation.context.swf.version())),
Arc::new(SwfMovie::empty_child(activation.context.swf)),
Some(content.into()),
false,
),
@ -256,7 +256,7 @@ pub fn load_bytes<'gc>(
// This is a dummy MovieClip, which will get overwritten in `Loader`
let content = MovieClip::new(
Arc::new(SwfMovie::empty(activation.context.swf.version())),
Arc::new(SwfMovie::empty_child(activation.context.swf)),
activation.context.gc_context,
);

View File

@ -373,7 +373,7 @@ impl<'gc> LoaderInfoObject<'gc> {
pub fn unload(&self, activation: &mut Activation<'_, 'gc>) {
// Reset properties
let empty_swf = Arc::new(SwfMovie::empty(activation.context.swf.version()));
let empty_swf = Arc::new(SwfMovie::empty_child(activation.context.swf));
let loader_stream = LoaderStream::NotYetLoaded(empty_swf, None, false);
self.set_loader_stream(loader_stream, activation.context.gc_context);
self.set_errored(false);

View File

@ -472,7 +472,7 @@ impl<'gc> MovieClip<'gc> {
loader_info: Option<LoaderInfoObject<'gc>>,
) {
let mut mc = self.0.write(context.gc_context);
let movie = movie.unwrap_or_else(|| Arc::new(SwfMovie::empty(mc.movie().version())));
let movie = movie.unwrap_or_else(|| Arc::new(SwfMovie::empty_child(&mc.movie())));
let total_frames = movie.num_frames();
assert_eq!(
mc.static_data.loader_info, None,
@ -2478,9 +2478,8 @@ impl<'gc> MovieClip<'gc> {
fn transform_to_unloaded_state(&self, context: &mut UpdateContext<'gc>) {
let movie = if let Some(DisplayObject::MovieClip(parent_mc)) = self.parent() {
let parent_movie = parent_mc.movie();
let parent_version = parent_movie.version();
let parent_url = parent_movie.url();
let mut unloaded_movie = SwfMovie::empty(parent_version);
let mut unloaded_movie = SwfMovie::empty_child(&parent_movie);
unloaded_movie.set_url(parent_url.to_string());
Some(Arc::new(unloaded_movie))

View File

@ -2689,9 +2689,8 @@ impl<'gc> Loader<'gc> {
// In this loading state, the URL is the URL of the parent movie / doesn't change.
let current_movie = mc.movie();
let current_version = current_movie.version();
let current_url = current_movie.url();
let mut initial_loading_movie = SwfMovie::empty(current_version);
let mut initial_loading_movie = SwfMovie::empty_child(&current_movie);
initial_loading_movie.set_url(current_url.to_string());
mc.replace_with_movie(uc, Some(Arc::new(initial_loading_movie)), true, None);

View File

@ -87,6 +87,20 @@ impl SwfMovie {
}
}
/// Construct an empty child movie.
pub fn empty_child(parent: &SwfMovie) -> Self {
Self {
header: HeaderExt::default_with_swf_version(parent.version()),
data: vec![],
url: "file:///".into(),
loader_url: Some(parent.url().into()),
parameters: Vec::new(),
encoding: swf::UTF_8,
compressed_len: 0,
is_movie: false,
}
}
/// Construct an empty movie with a fake `compressed_len`.
/// This is used by `Loader` when firing an initial `progress` event:
/// `LoaderInfo.bytesTotal` is set to the actual value, but no data is available,