rbx-dom: guard rail ustr footguns
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use std::io::Read;
|
||||
use rbx_dom_weak::ustr;
|
||||
use rbxassetid::{RobloxAssetId,RobloxAssetIdParseErr};
|
||||
use strafesnet_common::model::Mesh;
|
||||
use strafesnet_deferred_loader::{loader::Loader,texture::Texture};
|
||||
@@ -7,6 +6,11 @@ use strafesnet_deferred_loader::{loader::Loader,texture::Texture};
|
||||
use crate::data::RobloxMeshBytes;
|
||||
use crate::rbx::RobloxPartDescription;
|
||||
|
||||
// disallow non-static lifetimes
|
||||
fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
rbx_dom_weak::ustr(s)
|
||||
}
|
||||
|
||||
fn read_entire_file(path:impl AsRef<std::path::Path>)->Result<Vec<u8>,std::io::Error>{
|
||||
let mut file=std::fs::File::open(path)?;
|
||||
let mut data=Vec::new();
|
||||
@@ -172,12 +176,12 @@ impl Loader for MeshLoader{
|
||||
return Err(MeshError::MissingInstance);
|
||||
};
|
||||
if physics_data.is_empty(){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&ustr("PhysicsData")){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&static_ustr("PhysicsData")){
|
||||
physics_data=data.as_ref();
|
||||
}
|
||||
}
|
||||
if mesh_data.is_empty(){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&ustr("MeshData")){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&static_ustr("MeshData")){
|
||||
mesh_data=data.as_ref();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::loader::MeshIndex;
|
||||
use crate::primitives::{self,CubeFace,CubeFaceDescription,WedgeFaceDescription,CornerWedgeFaceDescription,FaceDescription,Primitives};
|
||||
use rbx_dom_weak::ustr;
|
||||
use strafesnet_common::aabb::Aabb;
|
||||
use strafesnet_common::map;
|
||||
use strafesnet_common::model;
|
||||
@@ -14,6 +13,11 @@ use strafesnet_deferred_loader::deferred_loader::{RenderConfigDeferredLoader,Mes
|
||||
use strafesnet_deferred_loader::mesh::Meshes;
|
||||
use strafesnet_deferred_loader::texture::{RenderConfigs,Texture};
|
||||
|
||||
// disallow non-static lifetimes
|
||||
fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
rbx_dom_weak::ustr(s)
|
||||
}
|
||||
|
||||
fn class_is_a(class: &str, superclass: &str) -> bool {
|
||||
if class==superclass {
|
||||
return true
|
||||
@@ -424,10 +428,10 @@ fn get_texture_description<'a>(
|
||||
Some(rbx_dom_weak::types::Variant::Color3(decal_color3)),
|
||||
Some(rbx_dom_weak::types::Variant::Float32(decal_transparency)),
|
||||
)=(
|
||||
decal.properties.get(&ustr("Texture")),
|
||||
decal.properties.get(&ustr("Face")),
|
||||
decal.properties.get(&ustr("Color3")),
|
||||
decal.properties.get(&ustr("Transparency")),
|
||||
decal.properties.get(&static_ustr("Texture")),
|
||||
decal.properties.get(&static_ustr("Face")),
|
||||
decal.properties.get(&static_ustr("Color3")),
|
||||
decal.properties.get(&static_ustr("Transparency")),
|
||||
)else{
|
||||
println!("Decal is missing a required property");
|
||||
continue;
|
||||
@@ -446,10 +450,10 @@ fn get_texture_description<'a>(
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_u)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_v)),
|
||||
) = (
|
||||
decal.properties.get(&ustr("OffsetStudsU")),
|
||||
decal.properties.get(&ustr("OffsetStudsV")),
|
||||
decal.properties.get(&ustr("StudsPerTileU")),
|
||||
decal.properties.get(&ustr("StudsPerTileV")),
|
||||
decal.properties.get(&static_ustr("OffsetStudsU")),
|
||||
decal.properties.get(&static_ustr("OffsetStudsV")),
|
||||
decal.properties.get(&static_ustr("StudsPerTileU")),
|
||||
decal.properties.get(&static_ustr("StudsPerTileV")),
|
||||
)
|
||||
{
|
||||
let (size_u,size_v)=match cube_face{
|
||||
@@ -547,12 +551,12 @@ pub fn convert<'a>(
|
||||
Some(rbx_dom_weak::types::Variant::Color3uint8(color3)),
|
||||
Some(rbx_dom_weak::types::Variant::Bool(can_collide)),
|
||||
) = (
|
||||
object.properties.get(&ustr("CFrame")),
|
||||
object.properties.get(&ustr("Size")),
|
||||
object.properties.get(&ustr("Velocity")),
|
||||
object.properties.get(&ustr("Transparency")),
|
||||
object.properties.get(&ustr("Color")),
|
||||
object.properties.get(&ustr("CanCollide")),
|
||||
object.properties.get(&static_ustr("CFrame")),
|
||||
object.properties.get(&static_ustr("Size")),
|
||||
object.properties.get(&static_ustr("Velocity")),
|
||||
object.properties.get(&static_ustr("Transparency")),
|
||||
object.properties.get(&static_ustr("Color")),
|
||||
object.properties.get(&static_ustr("CanCollide")),
|
||||
)
|
||||
{
|
||||
let model_transform=planar64_affine3_from_roblox(cf,size);
|
||||
@@ -571,7 +575,7 @@ pub fn convert<'a>(
|
||||
|
||||
//TODO: also detect "CylinderMesh" etc here
|
||||
let shape=match object.class.as_str(){
|
||||
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get(&ustr("Shape")){
|
||||
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get(&static_ustr("Shape")){
|
||||
Shape::Primitive(shape.to_u32().try_into().expect("Funky roblox PartType"))
|
||||
}else{
|
||||
panic!("Part has no Shape!");
|
||||
@@ -645,9 +649,9 @@ pub fn convert<'a>(
|
||||
Some(rbx_dom_weak::types::Variant::Content(texture_content)),
|
||||
)=(
|
||||
// mesh must exist
|
||||
object.properties.get(&ustr("MeshContent")),
|
||||
object.properties.get(&static_ustr("MeshContent")),
|
||||
// texture is allowed to be none
|
||||
object.properties.get(&ustr("TextureContent")),
|
||||
object.properties.get(&static_ustr("TextureContent")),
|
||||
){
|
||||
let mesh_asset_id=get_content_url(mesh_content).expect("MeshPart Mesh is not a Uri");
|
||||
let texture_asset_id=get_content_url(texture_content);
|
||||
@@ -662,13 +666,13 @@ pub fn convert<'a>(
|
||||
let mut content="";
|
||||
let mut mesh_data:&[u8]=&[];
|
||||
let mut physics_data:&[u8]=&[];
|
||||
if let Some(rbx_dom_weak::types::Variant::ContentId(asset_id))=object.properties.get(&ustr("AssetId")){
|
||||
if let Some(rbx_dom_weak::types::Variant::ContentId(asset_id))=object.properties.get(&static_ustr("AssetId")){
|
||||
content=asset_id.as_ref();
|
||||
}
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&ustr("MeshData")){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&static_ustr("MeshData")){
|
||||
mesh_data=data.as_ref();
|
||||
}
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&ustr("PhysicsData")){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&static_ustr("PhysicsData")){
|
||||
physics_data=data.as_ref();
|
||||
}
|
||||
let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object,size);
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
use rbx_dom_weak::{types::Ref,ustr,InstanceBuilder,WeakDom};
|
||||
use rbx_dom_weak::{types::Ref,InstanceBuilder,WeakDom};
|
||||
|
||||
// disallow non-static lifetimes
|
||||
fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
rbx_dom_weak::ustr(s)
|
||||
}
|
||||
|
||||
pub fn class_is_a(class:&str,superclass:&str)->bool{
|
||||
class==superclass
|
||||
@@ -70,8 +75,8 @@ impl Context{
|
||||
{
|
||||
//Lowercase and upper case workspace property!
|
||||
let game=self.dom.root_mut();
|
||||
game.properties.insert(ustr("workspace"),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert(ustr("Workspace"),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert(static_ustr("workspace"),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert(static_ustr("Workspace"),rbx_types::Variant::Ref(workspace));
|
||||
}
|
||||
self.dom.insert(game,InstanceBuilder::new("Lighting"));
|
||||
|
||||
|
||||
@@ -2,10 +2,15 @@ use std::collections::{hash_map::Entry,HashMap};
|
||||
|
||||
use mlua::{FromLua,FromLuaMulti,IntoLua,IntoLuaMulti};
|
||||
use rbx_types::Ref;
|
||||
use rbx_dom_weak::{ustr,Ustr,InstanceBuilder,WeakDom};
|
||||
use rbx_dom_weak::{Ustr,InstanceBuilder,WeakDom};
|
||||
|
||||
use crate::runner::vector3::Vector3;
|
||||
|
||||
// disallow non-static lifetimes
|
||||
fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
rbx_dom_weak::ustr(s)
|
||||
}
|
||||
|
||||
pub fn set_globals(lua:&mlua::Lua,globals:&mlua::Table)->Result<(),mlua::Error>{
|
||||
//class functions store
|
||||
lua.set_app_data(ClassMethodsStore::default());
|
||||
@@ -58,7 +63,7 @@ fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->S
|
||||
pub fn get_name_source(lua:&mlua::Lua,script:Instance)->Result<(String,String),mlua::Error>{
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=script.get(dom)?;
|
||||
let source=match instance.properties.get(&ustr("Source")){
|
||||
let source=match instance.properties.get(&static_ustr("Source")){
|
||||
Some(rbx_dom_weak::types::Variant::String(s))=>s.clone(),
|
||||
_=>Err(mlua::Error::external("Missing script.Source"))?,
|
||||
};
|
||||
@@ -208,7 +213,9 @@ impl mlua::UserData for Instance{
|
||||
});
|
||||
methods.add_meta_function(mlua::MetaMethod::Index,|lua,(this,index):(Instance,mlua::String)|{
|
||||
let index_str=&*index.to_str()?;
|
||||
let index_ustr=ustr(index_str);
|
||||
let Some(index_ustr)=Ustr::from_existing(index_str)else{
|
||||
return Ok(mlua::Value::Nil)
|
||||
};
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=this.get(dom)?;
|
||||
//println!("__index t={} i={index:?}",instance.name);
|
||||
@@ -262,11 +269,12 @@ impl mlua::UserData for Instance{
|
||||
})
|
||||
});
|
||||
methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(Instance,mlua::String,mlua::Value)|{
|
||||
let index_str=&*index.to_str()?;
|
||||
let Some(index_ustr)=Ustr::from_existing(index_str)else{
|
||||
return Ok(())
|
||||
};
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=this.get_mut(dom)?;
|
||||
//println!("__newindex t={} i={index:?} v={value:?}",instance.name);
|
||||
let index_str=&*index.to_str()?;
|
||||
let index_ustr=ustr(index_str);
|
||||
let db=rbx_reflection_database::get();
|
||||
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
||||
let property=db.superclasses_iter(class).find_map(|cls|
|
||||
@@ -462,7 +470,7 @@ fn find_virtual_property(
|
||||
let virtual_property=class_virtual_properties.get(index)?;
|
||||
|
||||
//Get source property
|
||||
let variant=properties.get(&ustr(virtual_property.property))?;
|
||||
let variant=properties.get(&static_ustr(virtual_property.property))?;
|
||||
|
||||
//Transform Source property with provided function
|
||||
(virtual_property.pointer)(variant)
|
||||
|
||||
@@ -3,11 +3,16 @@ use std::io::{Cursor,Read,Seek};
|
||||
use std::collections::HashSet;
|
||||
use clap::{Args,Subcommand};
|
||||
use anyhow::Result as AResult;
|
||||
use rbx_dom_weak::{ustr,Instance};
|
||||
use rbx_dom_weak::Instance;
|
||||
use strafesnet_deferred_loader::deferred_loader::LoadFailureMode;
|
||||
use rbxassetid::RobloxAssetId;
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
// disallow non-static lifetimes
|
||||
fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
rbx_dom_weak::ustr(s)
|
||||
}
|
||||
|
||||
const DOWNLOAD_LIMIT:usize=16;
|
||||
|
||||
#[derive(Subcommand)]
|
||||
@@ -102,8 +107,8 @@ SurfaceAppearance.RoughnessMapContent
|
||||
WrapLayer.ReferenceMeshContent
|
||||
*/
|
||||
|
||||
fn accumulate_content(content_list:&mut HashSet<RobloxAssetId>,object:&Instance,property:&str){
|
||||
let Some(rbx_dom_weak::types::Variant::Content(content))=object.properties.get(&ustr(property))else{
|
||||
fn accumulate_content(content_list:&mut HashSet<RobloxAssetId>,object:&Instance,property:&'static str){
|
||||
let Some(rbx_dom_weak::types::Variant::Content(content))=object.properties.get(&static_ustr(property))else{
|
||||
println!("property={} does not exist for class={}",property,object.class.as_str());
|
||||
return;
|
||||
};
|
||||
@@ -117,8 +122,8 @@ fn accumulate_content(content_list:&mut HashSet<RobloxAssetId>,object:&Instance,
|
||||
};
|
||||
content_list.insert(asset_id);
|
||||
}
|
||||
fn accumulate_content_id(content_list:&mut HashSet<RobloxAssetId>,object:&Instance,property:&str){
|
||||
let Some(rbx_dom_weak::types::Variant::ContentId(content))=object.properties.get(&ustr(property))else{
|
||||
fn accumulate_content_id(content_list:&mut HashSet<RobloxAssetId>,object:&Instance,property:&'static str){
|
||||
let Some(rbx_dom_weak::types::Variant::ContentId(content))=object.properties.get(&static_ustr(property))else{
|
||||
println!("property={} does not exist for class={}",property,object.class.as_str());
|
||||
return;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user