feat: stabilize OpenSim interactions and landmarks
Some checks failed
CI / rust-skia (Rust only) (push) Has been cancelled
CI / required (push) Has been cancelled

This commit is contained in:
2026-08-21 22:46:10 +02:00
parent adf5165033
commit e4e84dcdcb
27 changed files with 536 additions and 101 deletions

View File

@@ -1012,7 +1012,7 @@ fn communication_commands() -> [CommandEntry; 6] {
),
(
"im",
"Instant message someone. Usage: im [firstname] [lastname] [message]",
"Instant message someone. Usage: im [firstname] [lastname] [message] | im [avatar-uuid] [message]",
CommandCategory::Communication,
CommandHandler::Im,
),
@@ -1878,15 +1878,28 @@ async fn execute_communication_command(
}
}
CommandHandler::Im => {
if args.len() < 3 {
return "Usage: im [firstname] [lastname] [message]".into();
if args.is_empty() {
return "Usage: im [firstname] [lastname] [message] | im [avatar-uuid] [message]"
.into();
}
let name = format!("{} {}", args[0], args[1]);
let message = bounded_message(&args[2..].join(" "));
let target = match client.backend.resolve_avatar(&name, cancellation).await {
Ok(Some(target)) => target,
Ok(None) => return format!("Name lookup for {name} failed"),
Err(error) => return format!("Name lookup for {name} failed: {error}"),
let (target, message) = if let Ok(target) = UUID::new_with_string(args[0].clone()) {
if args.len() < 2 {
return "Usage: im [firstname] [lastname] [message] | im [avatar-uuid] [message]"
.into();
}
(target, bounded_message(&args[1..].join(" ")))
} else {
if args.len() < 3 {
return "Usage: im [firstname] [lastname] [message] | im [avatar-uuid] [message]"
.into();
}
let name = format!("{} {}", args[0], args[1]);
let target = match client.backend.resolve_avatar(&name, cancellation).await {
Ok(Some(target)) => target,
Ok(None) => return format!("Name lookup for {name} failed"),
Err(error) => return format!("Name lookup for {name} failed: {error}"),
};
(target, bounded_message(&args[2..].join(" ")))
};
match client.backend.instant_message(target, &message) {
Ok(()) => format!("Instant Messaged {target} with message: {message}"),

View File

@@ -452,6 +452,7 @@ enum Movement {
Follow(Option<(UUID, Vector3)>),
GoHome,
TeleportRegion(String, Vector3),
TeleportRegionHandle(u64, Vector3),
TeleportLandmark(UUID),
Jump,
AutoPilot { local: Vector3, global: [f64; 3] },
@@ -904,11 +905,12 @@ async fn goto<B: Backend + ?Sized>(
.collect::<Vec<_>>(),
"Usage: goto sim/x/y/z --confirm",
)?;
let movement = parts[0].parse::<u64>().map_or_else(
|_| Movement::TeleportRegion(parts[0].into(), position),
|handle| Movement::TeleportRegionHandle(handle, position),
);
backend
.world_mutate(
Mutation::Movement(Movement::TeleportRegion(parts[0].into(), position)),
cancellation,
)
.world_mutate(Mutation::Movement(movement), cancellation)
.await?;
Ok(format!("Teleported to {}", parts[0]))
}
@@ -2210,6 +2212,12 @@ fn apply_fake_movement(
backend.record(format!("CALL teleport-region {name} {position:?}"));
"Teleport complete".into()
}
Movement::TeleportRegionHandle(handle, position) => {
state.fake.region_handle = handle;
state.fake.position = position;
backend.record(format!("CALL teleport-region-handle {handle} {position:?}"));
"Teleport complete".into()
}
Movement::TeleportLandmark(id) => {
backend.record(format!("CALL teleport-landmark {id}"));
"Teleport complete".into()
@@ -3188,6 +3196,22 @@ async fn live_movement(
Err(format!("Teleport failed: {}", agent.teleport_message()))
}
}
Movement::TeleportRegionHandle(handle, position) => {
let agent = live_agent(backend)?;
let success = agent
.teleport_with_u_int64_vector3_cancellation_token(
handle,
position,
Some(cancellation),
)
.await
.map_err(|_| "Teleport failed")?;
if success {
Ok("Teleport complete".into())
} else {
Err(format!("Teleport failed: {}", agent.teleport_message()))
}
}
Movement::TeleportLandmark(id) => {
let agent = live_agent(backend)?;
if agent

View File

@@ -128,6 +128,7 @@ fn scripted_terminal_exercises_registry_communication_system_and_remote_auth() {
shout loud\n\
@ Alice Bot\n\
im Target Resident private hello\n\
im {TARGET} private by uuid\n\
imgroup {GROUP} group hello\n\
echomaster\n\
showeffects on\n\
@@ -161,6 +162,7 @@ fn scripted_terminal_exercises_registry_communication_system_and_remote_auth() {
"[Alice Bot] CALL chat channel=7 type=Normal hello world",
"[Bob Bot] CALL chat channel=7 type=Normal hello world",
"[Alice Bot] CALL instant-message 22222222-3333-4444-5555-666666666666 private hello",
"[Alice Bot] CALL instant-message 22222222-3333-4444-5555-666666666666 private by uuid",
"[Alice Bot] CALL group-chat-join 33333333-4444-5555-6666-777777777777",
"[Alice Bot] CALL group-instant-message 33333333-4444-5555-6666-777777777777 group hello",
"[Alice Bot] CALL chat channel=0 type=Normal echo this",

View File

@@ -142,6 +142,7 @@ fn fake_grid_exercises_every_owned_world_command() {
forward 0 --confirm\n\
gohome --confirm\n\
goto Test Region/128/128/25 --confirm\n\
goto {HANDLE}/129/129/26 --confirm\n\
goto_landmark {LANDMARK} --confirm\n\
jump --confirm\n\
left 0 --confirm\n\
@@ -236,6 +237,7 @@ fn fake_grid_exercises_every_owned_world_command() {
"CALL movement-forward duration-ms=0",
"CALL teleport-home",
"CALL teleport-region Test Region",
"CALL teleport-region-handle 4294967298000",
"CALL teleport-landmark 50000000-0000-0000-0000-000000000001",
"CALL movement-jump",
"CALL movement-left duration-ms=0",