Complete milestone 09 world integration gate (#75)
Some checks failed
Native code generation / deterministic (push) Failing after 8m37s
Imaging and meshing gate / native (push) Successful in 5m24s
Native Rust workspace compile / compile (push) Failing after 6m15s

This commit is contained in:
2026-08-10 21:19:43 +00:00
parent 55424dbd7f
commit fdda05b53f
18 changed files with 767 additions and 82 deletions

View File

@@ -784,9 +784,10 @@ impl InventoryManager {
pub(crate) fn native_new(client: Option<Arc<GridClient>>) -> Result<Self, Error> {
let client = client.ok_or(Error::ArgumentNull)?;
let initial_store = Inventory::new_with_grid_client(Arc::clone(&client))?;
let inner = Arc::new(InventoryManagerInner {
client: client.native_weak_handle(),
store: RwLock::new(None),
store: RwLock::new(Some(initial_store)),
disposed: AtomicBool::new(false),
callback_position: AtomicU32::new(0),
request_position: AtomicU64::new(0),
@@ -1914,10 +1915,9 @@ impl InventoryManager {
.await?
.ok_or(Error::InvalidOperation)?;
let uri = Uri(format!(
"{}/category/{}?tid={}",
"{}/category/{}",
cap.0.trim_end_matches('/'),
folder_id,
UUID::random()?
folder_id
));
let payload = OSD::Map(HashMap::from([(
"links".to_owned(),
@@ -4397,6 +4397,103 @@ fn parse_task_inventory_values(
}
impl InventoryManager {
pub(crate) async fn native_upload_thumbnail(
&self,
inventory_id: UUID,
task_id: UUID,
j2c_image_data: Vec<u8>,
cancellation_token: Option<CancellationToken>,
progress: Option<
Box<dyn libremetaverse_types::compat::IProgress<crate::HttpCapsClientProgressReport>>,
>,
) -> Result<Option<Option<UUID>>, Error> {
if inventory_id == UUID::zero()
|| j2c_image_data.is_empty()
|| j2c_image_data.len() > crate::asset_models::MAX_ASSET_BYTES
{
return Err(Error::Argument);
}
let token = cancellation_token.unwrap_or_default();
token.throw_if_cancellation_requested()?;
let client = self.client()?;
let Some(simulator) = client.native_network()?.current_sim() else {
return Ok(Some(None));
};
let Some(uri) = self
.wait_for_capability(&simulator, "InventoryThumbnailUpload", &token)
.await?
else {
return Ok(Some(None));
};
let inventory_store = self.native_store();
let known_local_folder = task_id == UUID::zero()
&& inventory_store
.as_ref()
.and_then(|store| {
store
.get_value_or_default_with_uuid_a7c63fbe::<InventoryFolder>(inventory_id)
.ok()
.flatten()
})
.is_some();
let metadata = if known_local_folder {
HashMap::from([("category_id".to_owned(), OSD::UUID(inventory_id))])
} else {
let mut metadata = HashMap::from([("item_id".to_owned(), OSD::UUID(inventory_id))]);
if task_id != UUID::zero() {
metadata.insert("task_id".to_owned(), OSD::UUID(task_id));
}
metadata
};
let payload = OSDParser::serialize_llsd_xml_bytes(OSD::Map(metadata))?;
let (metadata_response, metadata_body) = client
.native_http_caps_client()
.post_with_uri_string_bytes_cancellation_token_i_progress(
uri,
"application/llsd+xml".into(),
payload,
token.clone(),
None,
)
.await?;
if !(200..300).contains(&metadata_response.status_code) {
return Ok(Some(None));
}
let metadata: serde_json::Value =
serde_json::from_slice(&metadata_body).map_err(|_| Error::Argument)?;
let Some(uploader) = metadata.get("uploader").and_then(serde_json::Value::as_str) else {
return Ok(Some(None));
};
let (upload_response, upload_body) = client
.native_http_caps_client()
.post_with_uri_string_bytes_cancellation_token_i_progress(
Uri(uploader.to_owned()),
"image/x-j2c".into(),
j2c_image_data,
token,
progress,
)
.await?;
if !(200..300).contains(&upload_response.status_code) {
return Ok(Some(None));
}
let result: serde_json::Value =
serde_json::from_slice(&upload_body).map_err(|_| Error::Argument)?;
if result.get("state").and_then(serde_json::Value::as_str) != Some("complete") {
return Ok(Some(None));
}
let asset_id = result
.get("new_asset")
.or_else(|| result.get("new_asset_id"))
.and_then(serde_json::Value::as_str)
.map(|id| UUID::new_with_string(id.to_owned()))
.transpose()?;
Ok(Some(asset_id))
}
pub(crate) async fn native_update_material_inventory(
&self,
material: crate::assets::AssetMaterial,