99 lines
5.4 KiB
Markdown
99 lines
5.4 KiB
Markdown
# Native TestClient command shell
|
|
|
|
The `test-client` binary is a native Rust multi-client shell. It does not load
|
|
the former C# executable or start a CLR process. The command registry owns the
|
|
implemented system, communication, inventory, appearance, asset, movement,
|
|
object, parcel, estate, grid, agent, friends, groups, directory, and statistics
|
|
commands. `pending_test_client_commands()` now reports only the two explicitly
|
|
owned voice-native adapters (`ParcelVoiceInfo` and `VoiceAcountCommand`).
|
|
|
|
## Social, directory, and statistics behavior
|
|
|
|
Directory searches use native correlated, paged result streams and retain the
|
|
upstream 20-second response bound. Group cache, member, and role requests are
|
|
correlated with their native events and preserve the upstream timeouts. Friend
|
|
mapping, UUID/name resolution, event details, and group operations propagate
|
|
shell cancellation.
|
|
|
|
`who` maintains a live coarse-location roster and resolves display names;
|
|
`bots` also tracks source UUIDs from decoded viewer-effect packets. Profile
|
|
cloning combines the AgentProfile capability with the matching legacy interests
|
|
reply to replace profile text, images, URL, interests, and picks before joining
|
|
and activating the target's public groups. `play list` exposes all 135 built-in
|
|
animations from the pinned source catalog and also accepts arbitrary animation
|
|
asset UUIDs. Statistics come from each simulator's thread-safe native counters.
|
|
Directory and collection results are bounded at 65,535 entries.
|
|
|
|
## World command behavior
|
|
|
|
Movement commands use `AgentManager` movement updates, autopilot, teleport,
|
|
sit, stand, flight, and home APIs. Timed movement is limited to 60 seconds and
|
|
checks cancellation while sending updates. `follow` retains the selected
|
|
avatar and refreshes autopilot whenever a coarse-location update moves it;
|
|
`follow off` cancels autopilot. Region crossing is bounded to 60 seconds.
|
|
|
|
Object queries snapshot the current simulator caches before filtering.
|
|
Searches and parcel/map results are capped at 65,535 entries. Linkset export
|
|
requires ownership, sorts serialized LLSD deterministically, limits a linkset
|
|
to 10,000 primitives, and downloads each unique texture as both JPEG 2000 and
|
|
TGA. Import accepts only a bounded LLSD array, waits for each native rez event,
|
|
applies primitive properties, links children, and restores root rotation and
|
|
permissions. Individual asset and terrain files are limited to 64 MiB. Regular
|
|
expressions are limited in source and compiled size.
|
|
|
|
`textures on` downloads the textures already visible in the current simulator
|
|
and subscribes newly observed primitives for deduplicated native asset-cache
|
|
requests. `--gettextures` enables that subscription at login. Parcel, grid,
|
|
wind, owner, selection, covenant, and terrain commands use their corresponding
|
|
native managers and propagate cancellation through request/reply waits.
|
|
|
|
## Live-operation gates
|
|
|
|
Read-only queries need no privilege flag. Every movement, teleport, derez,
|
|
permission, import, tree, and terrain mutation requires both
|
|
`--allow-live-mutations` at process startup and `--confirm` on the command.
|
|
Import and terrain upload additionally require `--allow-spending`; estate
|
|
terrain download/upload additionally require `--allow-estate-actions`.
|
|
Consequently the default invocation cannot move an avatar, alter or create an
|
|
object, upload an asset, or invoke an estate-owner action.
|
|
|
|
Profile cloning, generic messages, animation starts, touches, group activation,
|
|
invitations, joins, and leaves use the same two-part mutation gate. Read-only
|
|
friend, group, directory, region, uptime, dilation, and statistics commands do
|
|
not require a gate. Profile cloning and direct group joins additionally require
|
|
`--allow-spending`, because an open group can charge an enrollment fee and the
|
|
client cannot safely infer that fee before every UUID-based join.
|
|
|
|
Output paths reject parent-directory traversal. Timeouts, cancellation, file
|
|
limits, result limits, and linkset limits apply equally to live and fake-grid
|
|
runs. Passwords and login secrets continue to pass through the shell's common
|
|
redaction path.
|
|
|
|
## Offline verification
|
|
|
|
Fake scripts can seed the same command layer with `!world-region`,
|
|
`!world-avatar`, `!world-prim`, `!world-parcel`, `!world-parcel-owner`,
|
|
`!world-parcel-object`, `!world-grid-region`, `!world-layer`,
|
|
`!world-agent-location`, `!world-estate`, `!world-asset`, and `!world-syntax`
|
|
tab-separated directives. These fixtures never open a network connection.
|
|
|
|
The service layer additionally accepts `!service-avatar`, `!service-friend`,
|
|
`!service-group`, `!service-group-result`, `!service-group-member`,
|
|
`!service-group-role`, `!service-person`, `!service-classified`,
|
|
`!service-event`, `!service-event-info`, `!service-land`, `!service-place`,
|
|
`!service-sim`, `!service-animation`, and `!service-utilization[-row]` fixtures.
|
|
|
|
Run the issue-focused compatibility gate with:
|
|
|
|
```text
|
|
cargo test -p libremetaverse-programs --test test_client_world_cli
|
|
cargo test -p libremetaverse-programs --test test_client_services_cli
|
|
```
|
|
|
|
The world gate drives every command owned by the movement/object/land/grid
|
|
issue, checks the exact fake backend calls, round-trips a linkset through
|
|
import, and validates generated assets. The services gate drives every one of
|
|
the 28 remaining non-voice commands in a single offline session, verifies the
|
|
destructive-operation guards, and proves the pending inventory contains only
|
|
the two explicitly owned voice adapters.
|