Both the Server Admin Plugins page and the Desktop Extension Settings section
now render every settingsSchema field type (string/password/number/boolean/
select), load current values from the settings API, and save partial updates.
Password inputs leave the stored secret untouched unless a new value is typed.
Backs ctx.ui.openExternal for client plugins. Only http(s) URLs are opened,
through the configured opener plugin, so a plugin cannot launch arbitrary
local protocol handlers.
launch_process accepts optional LaunchOverrides and applies them after the
manifest/handler launch command is resolved: executable replacement, wrapper
bin/args prepended around the game command, appended arguments, merged
environment, and a working-directory override. All fields are additive, so a
plugin that sends none is byte-for-byte unaffected. launch_game forwards the
overrides through the new Option parameter. Unit tests cover each merge rule.
Client plugin contexts gain registerRunnerProvider (game:runner), launchGame,
library queries, host ui helpers, and a local event bus. executeLaunchPipeline
now resolves LaunchOverrides from pre-launch hooks and applicable runner
providers (skipping unavailable/non-matching ones) and forwards them to the
launch closure, which the library view passes to the native launch_game
command. Adds the plugin_open_external host command for ctx.ui.openExternal.
Extract the resolved-uninstaller execution into run_uninstaller_command and
add hermetic tests: the uninstaller runs with the managed install directory
as its working directory, and a non-zero exit is reported as a status
(non-fatal) instead of a ProcessError so directory removal proceeds.
Runs after pre-launch:network and right before the game process spawns so
plugins can act on state finalized by the network stage (e.g. drop-gse
refreshing custom_broadcasts.txt with freshly assigned ZeroTier mesh
addresses). The stage participates in reverse-order rollback like the other
pre-launch stages.
Server:
- Verify client.sidecars during bundle verification (fail-closed on
missing files, sha256 mismatch, unallowlisted names, path escape)
- Manifest spread ships sidecars through plugin discovery
Desktop:
- plugin_sidecar_stage Tauri command: fetch the platform target from the
client asset route, verify sha256, stage into the per-plugin app-data
bin dir with 0755, atomic rename, symlink refusal, allowlist gating
- plugin_sidecar_clear removes staged binaries at unregister
- plugin_system_run resolution falls back to the staged bin dir after
PATH and well-known dirs, still gated by client.commands
- detectSidecarPlatform picks os/arch targets for the host; staging
failures are non-fatal (PATH/TypeScript fallback intact)
Ref Heretek-Games/drop#87
- scan the installed directory and resolve the launch target via the
server after an installer-based setup completes, with a scored picker
fallback when confidence is low
- include the install dir and a preempt-scan hint on pipeline completion
- optionally identify the adopted binary with the GameBox plugin
- When an allowlisted bare command fails to spawn (not on PATH), retry from
platform well-known installation directories (Linux /usr|/usr/local sbin,
/opt/ZeroTier/One; macOS ZeroTier & Homebrew dirs; Windows ZeroTier
Program Files/ProgramData dirs). Only plain, non-symlink, executable files
match the exact allowlisted name, preserving the bare-name security model
- Mount the topbar:status plugin slot in the header so global plugin status
indicators (e.g. mesh connection state) are rendered
Resolve the 6 open SonarCloud issues scoped to desktop/main code on
develop:
- workshop planner sorts mod paths and missing entries with
localeCompare comparators instead of default sort (S2871, bug class).
- WebRTC ICE config fetch moves to module scope; the composable only
needed it for createPeer and closed over nothing (S7721).
- remote plugin loader keeps the root-capabilities fallback in its own
statement instead of a nested ternary (S3358).
- browser-mode invoke fallback prefers the nullish coalescing
operator (S6606).
- Store Scanner SPI store union keeps its known-store literals
suggestible by widening with (string & {}) instead of plain string,
which swallowed them (S6571).
- big-picture keyboard navigation moves to a window keydown listener
so the tiles container does not pose as an interactive element
(Web:S6842); arrow tiles are natively focusable and the listener
makes arrow navigation reach files without a prior container click.
- declare known-folders dep and serde/derive used by the crate
instead of relying on feature unification with the app crate
- un-gate the Platform import so it is in scope on every target
- drop unused rustix::path::Arg import (rustix path module is
feature-gated and unavailable natively on windows)
- replace Component::as_str (does not exist on std) with an
as_os_str().to_str() match, falling back to the raw OsStr
- regen Cargo.lock
- README upgrade example no longer calls the nonexistent encode_downgrade; it
converts back to the old model and encodes that using the real API
- add log dev-dependency so attribute-macro-generated doctests compile
- Encode/Decode trait examples use the default bincode_1_3 codec and now run
in the default doctest suite (5 pass, was 1 pass/9 ignored)
- feature-gated codec examples stay ignored with the reason documented in
codec/mod.rs; verified they compile with all three codecs enabled
* Fix Install in the missing-dependency modal
The "Missing required dependency" modal calls download_game without
enableUpdates, but the command requires it, so clicking Install fails with:
invalid args `enableUpdates` for command `download_game`: command
download_game missing required key enableUpdates
Pass it the same way the library page does: true when installing the
latest version.
* Update DependencyRequiredModal.vue
---------
Co-authored-by: DecDuck <[email protected]>
Resolve the desktop workspace lints surfaced by clippy --all-targets
--all-features -- -D warnings: redundant references in formatting macros,
collapsible ifs, irregular format braces, a legacy std::usize import,
deprecated constants, unused nightly features, and a MutexGuard held across
the await inside send!. Allow too_many_arguments on the two pipeline runners
with a rationale.
Refs #67
- Run cargo +nightly fmt across desktop/src-tauri (37 files) and
libraries/native_model (fmt drift).
- Mark the feature-gated/outdated native_model doc examples as ignore so
cargo test --doc passes (they reference optional codec features and a
removed encode_downgrade helper); the default bincode_1_3 example still runs.
Refs #67
RUSTSEC-2026-0285 affects rustls 0.23.43 (TLS 1.3 handshake accepted across
encryption levels); 0.23.45 is the fixed release. chacha20 0.10.1 is yanked.
Update all three lockfiles and silence the shared deny.toml's expected
unmatched diagnostics (advisory ignore only matches native_model; the license
allow list is a cross-crate superset, so drop the unused bzip2-1.0.6 entry).
Closes#64
Phase 2 / #18 handheld power management:
- New power crate: PowerPolicy/PowerState/PowerDecision with a pure
decide() and a Linux sysfs battery reader (parse_linux_power_state +
read_linux_power_state).
- download_power_decision Tauri command maps the current battery state to
allow/throttle/pause for the download manager (unrestricted when
unknown).
- 5 tests (mains/charging, thresholds, clamping, validation, sysfs
parsing); clippy clean and cargo check -p drop-app passes.
Phase 3 / #19 NAT traversal (client half):
- internal/webrtc/peer.ts wraps the webview RTCPeerConnection: offer/
answer/ICE flow over a data channel, plus pure signaling/ICE helpers.
- useWebRtc composable fetches ICE config and builds a peer; the
fetch_ice_config Tauri command performs the authenticated GET.
- Desktop tests cover the pure helpers (11 total); typecheck/lint clean
and cargo check -p drop-app passes.
Completes the rich-presence loop for #20:
- Tauri commands report_presence / clear_presence call the authenticated
client presence API and no-op quietly when unauthenticated.
- The library page reports in-game with the game id after a successful
launch and back online when the game is stopped.
Phase 4 / #20 community hubs (screenshot galleries):
- ObjectHandler.setPermissions replaces an object's permission list.
- ScreenshotManager gains getPublicAllByGame and setVisibility, which
synchronize object permissions (owner read; anonymous:read when public)
with the screenshot's visibility.
- Public GET /api/v1/community/:gameid/screenshots and owner-only
POST /api/v1/client/screenshots/:id/visibility.
- Desktop community page renders the gallery via the existing object
asset protocol; new fetch_game_screenshots Tauri command.
- 2 tests for the permission mapping.
Phase 2 / #18 Drop Input:
- New input::uinput module: state_to_events maps sticks/triggers/dpad to
ABS events and emits every button's pressed/released state each frame.
- UinputBackend opens /dev/uinput, configures EV_KEY/EV_ABS bits and axis
ranges, creates the device, pushes input_event frames with SYN_REPORT,
and destroys the device. create() surfaces the OS error when /dev/uinput
is unavailable rather than faking a device.
- supported_backends() now reports Uinput on Linux alongside the Null
fallback; BackendKind docs updated.
- 4 new tests (axis scaling/clamping, button+release/dpad, pre-create
push error); 10 total.
Completes the forums UI for #20:
- Tauri commands fetch_forum_threads / fetch_forum_thread read the public
community API and deserialize into camelCase views.
- community.vue loads reviews and threads together and renders a
discussion section with an inline thread view.
- Registered the new commands alongside fetch_game_reviews.
Phase 1 / #17 remaining shader pre-caching work:
- shader_cache::stage_shader_caches restores packaged *.dxvk-cache files
into the install directory before launch, preserving a locally warmed
cache unless overwrite is requested.
- docs/implementation/shader-cache-format.md defines the manifest/pack
format shared with the drop-gamebox community index, including SHA-256
verification and trust notes.
- 1 new test (cache-only filtering, preserve, overwrite).
plugin_game_check_anticheat hardcoded EAC/BattlEye/Vanguard/Denuvo names in
the generic client host. Replace it with plugin_game_find_files, which
returns installed paths matching caller-supplied patterns, and drop the
AntiCheatReport/checkAntiCheat SPI so that domain knowledge lives in the
plugin (e.g. drop-gse) rather than core.
plugin_subscribe emits a Tauri event named plugin:event, but subscribe()
listened with window.addEventListener and expected a DOM CustomEvent, so
plugin WebSocket messages never reached their listeners. Register a real
Tauri listener for plugin:event (payload {channel,data}) in the Tauri host
and keep the DOM CustomEvent path as the browser/dev fallback.
Expose the shared serverWs bridge as a manager-level readonly member so
useAchievementToasts can subscribe via the typed ClientPluginWebSocket
instead of reaching for the per-plugin context field. Narrow the remaining
noUncheckedIndexedAccess findings in the manager and its tests.
- Add BackendKind/supported_backends() and a NullBackend that returns a clear
BackendUnavailable error when /dev/uinput or ViGEm is missing, so the missing
native driver is surfaced instead of silently no-op'ing.
- Pure toast queue (enqueue/dedupe/dismiss/expire) with tests.
- useAchievementToasts() subscribes to the core unlock channel; a toast
component renders the overlay notifications.
- Add a payment webhook dispatcher + public /api/v1/commerce/webhook/:gateway
route that resolves the plugin-registered PaymentGateway and verifies its
signature inside handleWebhook.
- Add collectStoreGames() aggregating every StoreScanner SPI result with
per-store failure isolation, plus a useStoreImport() composable.
- Add the shader_cache crate: DXVK/VKD3D *.dxvk-cache discovery across the
install dir and Proton/UMU prefix, plus collision-safe collection, tested
with tempfiles.
- Expose list_shader_caches/export_shader_caches Tauri commands; the community
index lives in the drop-gamebox plugin.
- Add cloud_saves::provision with platform asset resolution, GitHub release
tag parsing, tar.gz/raw extraction, and executable install, unit-tested.
- Add a provision_ludusavi Tauri command and run a best-effort provisioning
task on startup, mirroring the managed 7z/innoextract tools.