150 lines
3.7 KiB
Rust
150 lines
3.7 KiB
Rust
use std::io::Read;
|
|
use rbx_dom_weak::WeakDom;
|
|
use roblox_emulator::context::Context;
|
|
use strafesnet_deferred_loader::deferred_loader::{LoadFailureMode,MeshDeferredLoader,RenderConfigDeferredLoader};
|
|
|
|
mod rbx;
|
|
mod mesh;
|
|
mod union;
|
|
pub mod loader;
|
|
mod primitives;
|
|
|
|
pub mod data{
|
|
pub struct RobloxMeshBytes(Vec<u8>);
|
|
impl RobloxMeshBytes{
|
|
pub fn new(bytes:Vec<u8>)->Self{
|
|
Self(bytes)
|
|
}
|
|
pub(crate) fn cursor(self)->std::io::Cursor<Vec<u8>>{
|
|
std::io::Cursor::new(self.0)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Model{
|
|
dom:WeakDom,
|
|
}
|
|
impl Model{
|
|
fn new(dom:WeakDom)->Self{
|
|
Self{dom}
|
|
}
|
|
pub fn to_snf(&self,failure_mode:LoadFailureMode)->Result<strafesnet_common::map::CompleteMap,LoadError>{
|
|
to_snf(self,failure_mode)
|
|
}
|
|
}
|
|
impl AsRef<WeakDom> for Model{
|
|
fn as_ref(&self)->&WeakDom{
|
|
&self.dom
|
|
}
|
|
}
|
|
|
|
pub struct Place{
|
|
context:Context,
|
|
}
|
|
impl Place{
|
|
pub fn new(dom:WeakDom)->Result<Self,roblox_emulator::context::ServicesError>{
|
|
let context=Context::from_place(dom)?;
|
|
Ok(Self{
|
|
context,
|
|
})
|
|
}
|
|
pub fn run_scripts(&mut self){
|
|
let Place{context}=self;
|
|
let runner=roblox_emulator::runner::Runner::new().unwrap();
|
|
let scripts=context.scripts();
|
|
let runnable=runner.runnable_context(context).unwrap();
|
|
for script in scripts{
|
|
if let Err(e)=runnable.run_script(script){
|
|
println!("runner error: {e}");
|
|
}
|
|
}
|
|
}
|
|
pub fn to_snf(&self,failure_mode:LoadFailureMode)->Result<strafesnet_common::map::CompleteMap,LoadError>{
|
|
to_snf(self,failure_mode)
|
|
}
|
|
}
|
|
impl AsRef<WeakDom> for Place{
|
|
fn as_ref(&self)->&WeakDom{
|
|
self.context.as_ref()
|
|
}
|
|
}
|
|
impl From<Model> for Place{
|
|
fn from(model:Model)->Self{
|
|
let context=Context::from_model(model.dom);
|
|
Self{
|
|
context,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum ReadError{
|
|
RbxBinary(rbx_binary::DecodeError),
|
|
RbxXml(rbx_xml::DecodeError),
|
|
Io(std::io::Error),
|
|
UnknownFileFormat,
|
|
}
|
|
impl std::fmt::Display for ReadError{
|
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
write!(f,"{self:?}")
|
|
}
|
|
}
|
|
impl std::error::Error for ReadError{}
|
|
|
|
pub fn read<R:Read>(input:R)->Result<Model,ReadError>{
|
|
let mut buf=std::io::BufReader::new(input);
|
|
let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?;
|
|
match peek.get(0..8){
|
|
Some(b"<roblox!")=>rbx_binary::from_reader(buf).map(Model::new).map_err(ReadError::RbxBinary),
|
|
Some(b"<roblox ")=>rbx_xml::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxXml),
|
|
_=>Err(ReadError::UnknownFileFormat),
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum LoadError{
|
|
Texture(loader::TextureError),
|
|
Mesh(loader::MeshError),
|
|
}
|
|
impl std::fmt::Display for LoadError{
|
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
write!(f,"{self:?}")
|
|
}
|
|
}
|
|
impl std::error::Error for LoadError{}
|
|
impl From<loader::TextureError> for LoadError{
|
|
fn from(value:loader::TextureError)->Self{
|
|
Self::Texture(value)
|
|
}
|
|
}
|
|
impl From<loader::MeshError> for LoadError{
|
|
fn from(value:loader::MeshError)->Self{
|
|
Self::Mesh(value)
|
|
}
|
|
}
|
|
|
|
fn to_snf(dom:impl AsRef<WeakDom>,failure_mode:LoadFailureMode)->Result<strafesnet_common::map::CompleteMap,LoadError>{
|
|
let dom=dom.as_ref();
|
|
|
|
let mut texture_deferred_loader=RenderConfigDeferredLoader::new();
|
|
let mut mesh_deferred_loader=MeshDeferredLoader::new();
|
|
|
|
let map_step1=rbx::convert(
|
|
dom,
|
|
&mut texture_deferred_loader,
|
|
&mut mesh_deferred_loader,
|
|
);
|
|
|
|
let mut mesh_loader=loader::MeshLoader::new();
|
|
let meshpart_meshes=mesh_deferred_loader.into_meshes(&mut mesh_loader,failure_mode).map_err(LoadError::Mesh)?;
|
|
|
|
let map_step2=map_step1.add_meshpart_meshes_and_calculate_attributes(meshpart_meshes);
|
|
|
|
let mut texture_loader=loader::TextureLoader::new();
|
|
let render_configs=texture_deferred_loader.into_render_configs(&mut texture_loader,failure_mode).map_err(LoadError::Texture)?;
|
|
|
|
let map=map_step2.add_render_configs_and_textures(render_configs);
|
|
|
|
Ok(map)
|
|
}
|