Implement remaining TestClient service commands (#94)
Some checks failed
Native code generation / deterministic (push) Successful in 18m19s
Imaging and meshing gate / native (push) Failing after 4m28s
Native Rust workspace compile / compile (push) Failing after 12m58s

This commit is contained in:
2026-08-11 13:10:27 +00:00
parent 374d7958f1
commit 21f85a1b58
13 changed files with 3300 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
//! Native `TestClient` shell, registry, and first-wave command groups.
mod inventory;
mod services;
mod world;
use crate::commands::TEST_CLIENT_COMMANDS;
@@ -135,6 +136,34 @@ pub const IMPLEMENTED_TEST_CLIENT_COMMANDS: &[&str] = &[
"ShowEffectsCommand",
"SleepCommand",
"WaitForLoginCommand",
"BotsCommand",
"CloneProfileCommand",
"GenericMessageCommand",
"PlayAnimationCommand",
"TouchCommand",
"WhoCommand",
"Key2NameCommand",
"SearchClassifiedsCommand",
"SearchEventsCommand",
"SearchGroupsCommand",
"SearchLandCommand",
"SearchPeopleCommand",
"SearchPlacesCommand",
"ShowEventDetailsCommand",
"FriendsCommand",
"MapFriendCommand",
"ActivateGroupCommand",
"GroupMembersCommand",
"GroupRolesCommand",
"GroupsCommand",
"InviteGroupCommand",
"JoinGroupCommand",
"LeaveGroupCommand",
"DilationCommand",
"NetstatsCommand",
"RegionInfoCommand",
"StatsCommand",
"UptimeCommand",
];
#[must_use]
@@ -153,7 +182,7 @@ pub fn pending_test_client_commands() -> Vec<&'static str> {
version,
about = "Run the native LibreMetaverse multi-client command shell",
long_about = None,
after_help = "Owned commands include @, debug, echomaster, help, im, imgroup, load, login, logpacket, logout, md5, quit, say, setmaster, setmasterkey, shout, showeffects, sleep, waitforlogin, whisper, plus the inventory, appearance, asset, movement, object, parcel, estate, and grid groups. Run `help` or `help COMMAND` inside the shell for the complete command registry."
after_help = "Owned commands include @, debug, echomaster, help, im, imgroup, load, login, logpacket, logout, md5, quit, say, setmaster, setmasterkey, shout, showeffects, sleep, waitforlogin, and whisper. All non-voice inventory, appearance, asset, movement, object, parcel, estate, grid, social, directory, and statistics commands are also native. Run `help` or `help COMMAND` inside the shell for the complete command registry."
)]
#[allow(clippy::struct_excessive_bools)]
struct Cli {
@@ -296,7 +325,7 @@ enum ClientEvent {
type BackendFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
type InventoryFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
trait ClientBackend: Send + Sync + inventory::Backend + world::Backend {
trait ClientBackend: Send + Sync + inventory::Backend + services::Backend + world::Backend {
fn id(&self) -> UUID;
fn name(&self) -> String;
fn connected(&self) -> bool;
@@ -332,6 +361,7 @@ struct LiveBackend {
subscriptions: Mutex<Vec<Subscription>>,
inventory_state: Mutex<inventory::State>,
world_state: Mutex<world::State>,
services_state: Mutex<services::State>,
closed: AtomicBool,
}
@@ -393,6 +423,7 @@ impl LiveBackend {
subscriptions: Mutex::new(Vec::new()),
inventory_state: Mutex::new(inventory::State::new(account_policy)),
world_state: Mutex::new(world::State::new(account_policy, get_textures)),
services_state: Mutex::new(services::State::new(account_policy)),
closed: AtomicBool::new(false),
});
backend.install(&events, &dropped);
@@ -512,6 +543,7 @@ impl LiveBackend {
},
)));
world::install_live(self, &mut subscriptions);
services::install_live(self, &mut subscriptions);
*lock(&self.subscriptions) = subscriptions;
}
}
@@ -680,6 +712,7 @@ struct FakeBackend {
group_members: Arc<Mutex<HashSet<UUID>>>,
inventory_state: Mutex<inventory::State>,
world_state: Mutex<world::State>,
services_state: Mutex<services::State>,
}
impl FakeBackend {
@@ -700,6 +733,7 @@ impl FakeBackend {
group_members,
inventory_state: Mutex::new(inventory::State::new(policy)),
world_state: Mutex::new(world::State::new(policy, get_textures)),
services_state: Mutex::new(services::State::new(policy)),
}
}
@@ -820,10 +854,13 @@ impl ProgramOutput {
enum CommandCategory {
Appearance,
Communication,
Friends,
Groups,
Inventory,
Movement,
Objects,
Parcel,
Search,
Simulator,
TestClient,
Other,
@@ -838,6 +875,7 @@ enum CommandHandler {
Im,
ImGroup,
Inventory(inventory::Command),
Services(services::Command),
World(world::Command),
Load,
Login,
@@ -999,6 +1037,7 @@ fn built_in_commands() -> HashMap<String, CommandDefinition> {
.into_iter()
.chain(communication_commands())
.chain(inventory::commands())
.chain(services::commands())
.chain(world::commands())
.map(|(name, description, category, handler)| {
(
@@ -1780,6 +1819,9 @@ async fn execute_client_command(
CommandHandler::Inventory(command) => {
inventory::execute(client.backend.as_ref(), *command, args, from, cancellation).await
}
CommandHandler::Services(command) => {
services::execute(client.backend.as_ref(), *command, args, cancellation).await
}
CommandHandler::World(command) => {
world::execute(client.backend.as_ref(), *command, args, cancellation).await
}
@@ -2367,6 +2409,10 @@ async fn run_fake_event_directive(
result.map_err(|reason| ProgramError::InvalidInput { line, reason })?;
return Ok(());
}
if let Some(result) = services::apply_fake_directive(manager, fields) {
result.map_err(|reason| ProgramError::InvalidInput { line, reason })?;
return Ok(());
}
match fields {
["chat", client, source, name, message] => {
let event = ClientEvent::Chat {
@@ -2670,6 +2716,7 @@ mod tests {
assert!(TEST_CLIENT_COMMANDS.contains(command));
assert!(!pending.contains(command));
}
assert_eq!(pending, ["ParcelVoiceInfo", "VoiceAcountCommand"]);
}
#[test]

File diff suppressed because it is too large Load Diff