avm1: Fix `loadVariablesNum` / `Action::GetUrl2`
This commit is contained in:
parent
badb91c1db
commit
055e1d4dc1
|
@ -1190,29 +1190,59 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
fn action_get_url_2(&mut self, action: GetUrl2) -> Result<FrameControl<'gc>, Error<'gc>> {
|
fn action_get_url_2(&mut self, action: GetUrl2) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||||
// TODO: Support `LoadVariablesFlag`, `LoadTargetFlag`
|
// TODO: Support `LoadVariablesFlag`, `LoadTargetFlag`
|
||||||
// TODO: What happens if there's only one string?
|
// TODO: What happens if there's only one string?
|
||||||
let target = self.context.avm1.pop();
|
let target_val = self.context.avm1.pop();
|
||||||
|
let target = target_val.coerce_to_string(self)?;
|
||||||
let url_val = self.context.avm1.pop();
|
let url_val = self.context.avm1.pop();
|
||||||
let url = url_val.coerce_to_string(self)?;
|
let url = url_val.coerce_to_string(self)?;
|
||||||
|
|
||||||
if let Some(fscommand) = fscommand::parse(&url) {
|
if let Some(fscommand) = fscommand::parse(&url) {
|
||||||
let fsargs = target.coerce_to_string(self)?;
|
// `target` = fscommand arguments!
|
||||||
fscommand::handle(fscommand, &fsargs, self)?;
|
fscommand::handle(fscommand, &target, self)?;
|
||||||
return Ok(FrameControl::Continue);
|
return Ok(FrameControl::Continue);
|
||||||
}
|
}
|
||||||
|
|
||||||
let window_target = target.coerce_to_string(self)?;
|
// TODO: Use `StageObject::get_level_by_path`.
|
||||||
let clip_target: Option<DisplayObject<'gc>> = if action.is_target_sprite() {
|
let level_target = if target.starts_with(WStr::from_units(b"_level")) && target.len() >= 6 {
|
||||||
if let Value::Object(target) = target {
|
match target[6..].parse::<f64>() {
|
||||||
|
Ok(level_id) => level_id as i32,
|
||||||
|
Err(_) => {
|
||||||
|
if target.len() == 6 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
let clip_target: Option<DisplayObject<'gc>> = if level_target > -1 {
|
||||||
|
Some(self.resolve_level(level_target))
|
||||||
|
} else if action.is_load_vars() || action.is_target_sprite() {
|
||||||
|
if let Value::Object(target) = target_val {
|
||||||
target.as_display_object()
|
target.as_display_object()
|
||||||
} else {
|
} else {
|
||||||
let start = self.target_clip_or_root();
|
let start = self.target_clip_or_root();
|
||||||
self.resolve_target_display_object(start, target, true)?
|
self.resolve_target_display_object(start, target_val, true)?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(self.target_clip_or_root())
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if action.is_load_vars() {
|
if action.is_load_vars() {
|
||||||
|
// `loadVariables` or `loadVariablesNum` call.
|
||||||
|
// Depending on the situation, it will open a link in the browser instead.
|
||||||
|
let mut is_load_vars = true;
|
||||||
|
if !(action.is_target_sprite() || level_target > -1) {
|
||||||
|
is_load_vars = false;
|
||||||
|
if matches!(target_val, Value::Object(_)) {
|
||||||
|
if let Some(clip) = clip_target {
|
||||||
|
is_load_vars = DisplayObject::ptr_eq(clip, self.base_clip().avm1_root());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if is_load_vars {
|
||||||
if let Some(clip_target) = clip_target {
|
if let Some(clip_target) = clip_target {
|
||||||
let target_obj = clip_target
|
let target_obj = clip_target
|
||||||
.as_movie_clip()
|
.as_movie_clip()
|
||||||
|
@ -1231,9 +1261,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
);
|
);
|
||||||
self.context.navigator.spawn_future(future);
|
self.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(FrameControl::Continue);
|
return Ok(FrameControl::Continue);
|
||||||
|
}
|
||||||
} else if action.is_target_sprite() {
|
} else if action.is_target_sprite() {
|
||||||
|
// `loadMovie`, `unloadMovie` or `unloadMovieNum` call.
|
||||||
if let Some(clip_target) = clip_target {
|
if let Some(clip_target) = clip_target {
|
||||||
let (url, opts) = self.locals_into_request_options(
|
let (url, opts) = self.locals_into_request_options(
|
||||||
&url,
|
&url,
|
||||||
|
@ -1258,17 +1289,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(FrameControl::Continue);
|
return Ok(FrameControl::Continue);
|
||||||
} else if window_target.starts_with(WStr::from_units(b"_level")) && window_target.len() > 6
|
} else if level_target > -1 {
|
||||||
{
|
// `loadMovieNum` call.
|
||||||
// TODO: Use `StageObject::get_level_by_path`.
|
if let Some(clip_target) = clip_target {
|
||||||
// target of `_level#` indicates a `loadMovieNum` call.
|
|
||||||
match window_target[6..].parse::<i32>() {
|
|
||||||
Ok(level_id) => {
|
|
||||||
let level = self.resolve_level(level_id);
|
|
||||||
|
|
||||||
let future = self.context.load_manager.load_movie_into_clip(
|
let future = self.context.load_manager.load_movie_into_clip(
|
||||||
self.context.player.clone().unwrap(),
|
self.context.player.clone().unwrap(),
|
||||||
level,
|
clip_target,
|
||||||
&url.to_utf8_lossy(),
|
&url.to_utf8_lossy(),
|
||||||
RequestOptions::get(),
|
RequestOptions::get(),
|
||||||
None,
|
None,
|
||||||
|
@ -1276,27 +1302,19 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
);
|
);
|
||||||
self.context.navigator.spawn_future(future);
|
self.context.navigator.spawn_future(future);
|
||||||
}
|
}
|
||||||
Err(e) => avm_warn!(
|
return Ok(FrameControl::Continue);
|
||||||
self,
|
|
||||||
"Couldn't parse level id {} for action_get_url_2: {}",
|
|
||||||
url,
|
|
||||||
e
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(FrameControl::Continue);
|
// `getURL` call.
|
||||||
} else {
|
|
||||||
let vars = match NavigationMethod::from_send_vars_method(action.send_vars_method()) {
|
let vars = match NavigationMethod::from_send_vars_method(action.send_vars_method()) {
|
||||||
Some(method) => Some((method, self.locals_into_form_values())),
|
Some(method) => Some((method, self.locals_into_form_values())),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.context.navigator.navigate_to_url(
|
self.context
|
||||||
url.to_string(),
|
.navigator
|
||||||
Some(window_target.to_string()),
|
.navigate_to_url(url.to_string(), Some(target.to_string()), vars);
|
||||||
vars,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue