Both of these are handled automatically by the browser in the
web backend. This makes the desktop client store cookies between
requests (though they are discarded when the desktop player is closed),
and set the "Content-Type" header based on the mime-type supplied
in the URLRequest.
Previously, the volume transformation to adapt the volume for
logarithmic hearing has been performed in the VolumeControls Rust struct
and TypeScript class each.
Since this calculation is the same on desktop and web and should be
implemented in the audio backend, it has been moved into the
AudioMixer::mix_audio method.
The VolumeControls struct and class now only calculate the linear volume
out of the checkbox and the slider.
Player::set_volume and Player::volume now don't take and return the
adapted volume, but use the linear volume (which gets saved internally).
The desktop version of Ruffle now has a volume controls window. It can
be accessed through the menu bar (Controls > Volume controls).
It contains a mute button and a slider from 0 to 100.
The volume settings set in the GUI are saved in a new VolumeControls
struct, which is also used to calculate the real volume (adapted for
logarithmic hearing) out of the entered volume and the mute checkbox.
As soon as the volume is changed in the GUI, the real volume will be set
in the player (if the player exists).
The player doesn't set its volume level according to the PlayerOptions
after its creation anymore. Instead, RuffleGui::on_player_created now
gets the player and sets its volume to the real volume set in the GUI.
The volume in the GUI itself defaults to the PlayerOptions value.
This also fixes the issue that the PlayerOptions volume has previously
not been adapted for logarithmic hearing.
The existing ftl files have been adapted (and new ones have been
created) to include the new multilingual text in the menu bar and the
volume controls window.
This adds a way to modify socket behavior to restrict, ask, or allow all
connections. Also adds a whitelist which can be used to allow specific hosts
without enabiling ask or allow all behaviors.
This was incorrect as this pr was initially based on #8188.
Old code was searching for XML payload end null bytes, now it just reads
and appends bytes.
The `max_execution_duration` feature is pretty much useless on desktop,
and breaks slow SWFs by aborting script execution instead of letting
it continue.
All NavigatorBackend implementations have been refactored, resulting in
improved code quality, less duplicated code, more consistent and easier
to understand procedures, additional error handling and better error
messages.
A resolve_url method has been added to the NavigatorBackend trait. It
takes a URL and and resolves it to the actual URL from which a file can
be fetched (including handling of relative links and pre-processing). It
has been implemented in each NavigatorBackend implementation.
Duplicated code has been put into new public functions in
core/src/backend/navigator.rs which are called by all NavigatorBackend
implementations.
ExternalNavigatorBackend:
- The navigate_to_url and fetch methods have been adapted to use
resolve_url, removing redundant code.
- Error handling has been added in case that the URL can't be converted
to a PathBuf.
- A TODO about differences between the flash player fetch and the
Ruffle fetch implementation has been added.
WebNavigatorBackend:
- The previous resolve_url method exclusively to the WebNavigatorBackend
has been replaced by the new resolve_url method. It is used by
navigate_to_url and fetch.
- resolve_url now always pre-processes the URL if it's valid (even if no
base_url exists) and explicitly returns whether the URL can be parsed.
- navigate_to_url now traces an explanatory error each if the URL can't
be parsed or is local.
- fetch now returns an explanatory error each if the URL can't be parsed
or is local (previously, a vague "Got JS error" has been returned).
TestNavigatorBackend & NullNavigatorBackend:
- fetch pre-processes the URL now (using the resolve_url implementation).
- If the URL isn't local, an explanatory error is returned (previously,
it was just an "Invalid URL" error).
- If the URL can't be parsed, an explanatory error with the reason is
returned (previously, it was just an "Invalid URL" error).
Additionally, error messages in all NavigatorBackend implementations
have been improved and made more consistent, e.g. if a local file can't
be read.
A load_error_swf function has been added to the Loader. It makes the
MovieClip enter the error state in which some attributes have certain
error values to signal that no valid file could be loaded. This happens
if no file could be loaded or if the loaded content is no valid
supported content.
The function creates an error state movie stub using the new
SwfMovie::error_movie function (which uses a new default_error_header
function) and configures remaining variables with the
movie_not_available method.
One TODO in order for the error state to be completely implemented has
been added.
Since the error state of the MovieClip includes the final URL of the SWF
file obtained after any redirects, the load_error_swf and
movie_loader_error functions (now) take an swf_url attribute.
To get this URL in case no file could be loaded, the
NavigatorBackend::fetch method has been changed to return an
ErrorResponse struct (including the url and the actual error) in the
error case. The Response struct returned in the success case has been
renamed to SuccessResponse.
All fetch implementations have been adapted accordingly. Code has been
adjusted to return the actual error where that's needed.
Documentation has been added and improved.
When using a 'Loader', properties on the 'contentLoaderInfo' become
set during specific events in the load sequence. In particular,
'LoaderInfo.bytesTotal' becomes available during the first 'progress'
event.
Also, 'LoaderInfo.parameters' is now properly set from the URL query
parameters. In Flash player, this work even with filesystem urls
(e.g. 'file:///some/path/to/file.txt?paramOne=valOne' will load
a file named 'file.txt', setting and expose the parameter 'paramOne'
with value 'valOne' in `LoaderInfo.parameters`). This required some
cleanup to the desktop and test NavigatorBackend impls to strip
out query parameters when loading a parameter from disk.
Previously, we would set `SwfMovie.parameters` manually from the url.
Now, the various `SwfMovie` constructors automatically extract
query parameters from the provided url. Outside of `SwfMovie`,
we only append *extra* parameters (e.g. those set from `flashvars`).
This makes CPMStar ads work, since the loaded SWF needs to access
`LoaderInfo.parameters`
* wpgu: Initial implementation of PixelBender shader execution
The implementation is split across four crates:
* `ruffle_render` now holds the main PixelBender bytecode parsing
implementation (previously, this was in `ruffle_core`).
* `ruffle_core` holds some helper functions for converting between
AVM2 `Value`s and the PixelBender vector types.
* `naga-pixelbender` (newly created) constructs a Naga `Module`
from parsed PixelBender bytecode
* `ruffle_render_wgpu` sets up the render pipeline for the shader
constructed by `naga-pixelbender`, and actually executes the shader.
The Actionscript-side shader parameters are passed in through uniforms.
This allows us to cache the compiled `naga::Module` and associated
wgpu types inside `ShaderData`, when it's first created. Each invocation
of a `ShaderJob` only needs to create a bind group and render pass.
Limitations:
* Only a few of the PixelBender opcodes are implemented - however, this is
enough to get Stemlands cannon rotation working, as well as a cool
"donut" shader that I found and included as a test.
* PixelBender matrix types are not supported.
* Only BitmapData is supported as an input/output type - Flash Player
also supports using Vector and ByteArray
* ShaderJob execution is always synchronous.
* Adjust comments
* Address review comments
This works around a stack overflow with Bloonts Tower Defense 5,
where we have over 400 stack frames at once due to deep
`construct_frame` recursion in `goto` execution.
Makes opening the same movie repeatedly less tedious.
Note that `Open` still ignore this and will use the default options
provided on the command-line.
These are directly set on the underlying navigator's HTTP
request type, and get printed out in our test navigator backend.
No validation of the header names is performed - on web, this will be
enforced by the browser.
Change `App::event_loop` to an `Option` that will be taken on
`App::run` so that `App::run` can continue to call methods on
`self` later.
This is a little awkward, and better might be to remove `App::new`
and make `App:run` return `Result<!, Error>,` but `!` types are
experimental.
The suggested changes to the navigate_to_url handling in the feedback to
the pull request have been implemented.
Therefore, this commit consists of multiple smaller changes:
1. The allow_javascript_calls variable has been removed (as a CLI
argument and in the navigator). Javascript calls are now always denied
on desktop. This is because setting the argument was useless; no
javascript was executed in any case, at most, just a browser tab opened.
Therefore, it makes no sense to include this option.
2. The NavigateWebsiteHandlingMode default value has been provisionally
changed from Confirm to Allow. In the future (after a GUI toolkit has
been added), the default confirmation windows should include a "Save
this preference" checkbox.
3. The NetworkingRestrictionMode enum has been renamed to
NetworkingAccessMode since the previous naming was counter-intuitive.
4. The NavigateWebsiteHandlingMode enum (and variables related to it)
have been renamed to OpenURLMode to simplify the name.
5. The documentation has been improved.
New configuration options (changing the navigate_to_url call handling)
have been added. The default behaviour has been changed as well.
A NavigateWebsiteHandlingMode enum has been added to Ruffle (in Rust and
Typescript). It contains the values "Allow", "Confirm" and "Deny" and
describes how navigate_to_url website calls should be handled. Allow
means that all website calls are allowed, Confirm means that a
confirmation window opens with each website call and Deny means that all
website calls are denied.
A respective navigate_website_handling_mode variable has been added to
the desktop CLI and to the JS config. The default value is "Confirm" in
each. The variable is given to the navigator (ExternalNavigatorBackend
or WebNavigatorBackend, depending on the platform) and is saved in it.
On each navigate_to_url website call, the respective navigator is now
checking navigate_website_handling_mode and acts correspondingly (allows
it, opens a confirmation window or denies it).
This changes the default behaviour of Ruffle from allowing all website
calls to opening a confirmation window with each website call.
On Safari, the confirm window can cause the background music to stop,
but this seems to be an issue with Safari.
Closes#838.
Additionally, an allow_javascript_calls variable (which defaults to
false) has been added to the desktop CLI. The variable is given to the
desktop navigator and is saved in it.
If a navigate_to_url javascript call is executed on desktop, the
navigator is now checking allow_javascript_calls and acts
correspondingly (allows it or denies it).
This changes the default behaviour of Ruffle on desktop to not allowing
javascript calls.
Closes#9316.
The stage alignment settings viewport_scale_factor should *not* be
applied to `Stage.transform.matrix`, which is only ever changed
as a result of explicit modification from ActionScript. Instead,
alignment and scaling are performed a separate step, which is
transparent to ActionScript.
I've implemented this through a new `viewport_matrix` field,
which is used during stage rendering and mouse coordinate
transformation.
This makes Stage3D instances properly scale - previously, they
would render unscaled. The linux standalone Flash Player doesn't
seem to use HiDPI mode, so I didn't realize that this was a bug
until now.
In the process of implementing this, I discovered and fixed a bug
with how we handle changing the viewport size under winit.
Calling `self.window.set_inner_size` does not immediately take
effect (at least on X11) - calling `self.window.inner_size()`
will report the old size until the next resize event.
Since build our Stage matrices from `self.window.inner_size()`
(and start running the SWF) immediately after `RuffleEvent::OnMetadata`,
we would run a few SWF frames with an incorrect viewport size. This
is visible to SWFs that have the scale mode set to "noScale", and
could break SWFs that expect the initial viewport size to be
the movie size. I've fixed this by delaying SWF execution until
we get a Resize event (if `self.window.inner_size()` does not
immediately report the size we set).
`build_output_stream` now takes in a `timeout` parameter - I've
passed in `None` to keep the current behavior.
cpal addded lots of new `SampleFormat` enum values. For now, I'm
just returning an error if we encounter any of them - a quick test
showed that desktop audio is still working on my Linux machine.