2024-01-31 04:25:07 +00:00
|
|
|
use std::io::Read;
|
2024-10-04 02:35:59 +00:00
|
|
|
use rbx_dom_weak::WeakDom;
|
2024-01-31 04:25:07 +00:00
|
|
|
|
|
|
|
mod rbx;
|
2024-03-13 20:34:06 +00:00
|
|
|
mod mesh;
|
2024-01-31 01:41:16 +00:00
|
|
|
mod primitives;
|
2024-01-31 04:25:07 +00:00
|
|
|
|
2024-03-13 20:34:06 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-04 02:35:59 +00:00
|
|
|
pub struct Model{
|
|
|
|
dom:WeakDom,
|
|
|
|
}
|
|
|
|
impl Model{
|
|
|
|
fn new(dom:WeakDom)->Self{
|
|
|
|
Self{dom}
|
|
|
|
}
|
|
|
|
pub fn into_place(self)->(Place,roblox_emulator::place::Services){
|
|
|
|
let (dom,services)=roblox_emulator::place::new_place_with_instances_in_workspace(self.dom);
|
|
|
|
(Place{dom},services)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl AsRef<WeakDom> for Model{
|
|
|
|
fn as_ref(&self)->&WeakDom{
|
|
|
|
&self.dom
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Place{
|
|
|
|
dom:WeakDom,
|
|
|
|
}
|
|
|
|
impl Place{
|
|
|
|
pub fn run_scripts(&mut self,services:roblox_emulator::place::Services){
|
2024-09-18 01:27:56 +00:00
|
|
|
let runner=roblox_emulator::runner::Runner::new().unwrap();
|
2024-10-04 02:35:52 +00:00
|
|
|
let context=roblox_emulator::context::Context::from_mut(&mut self.dom);
|
|
|
|
let scripts=context.scripts();
|
|
|
|
let runnable=runner.runnable_context(context,services).unwrap();
|
|
|
|
for script in scripts{
|
|
|
|
if let Err(e)=runnable.run_script(script){
|
2024-09-21 22:09:40 +00:00
|
|
|
println!("runner error: {e}");
|
2024-09-18 01:27:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-10-04 02:35:59 +00:00
|
|
|
impl AsRef<WeakDom> for Place{
|
|
|
|
fn as_ref(&self)->&WeakDom{
|
|
|
|
&self.dom
|
|
|
|
}
|
|
|
|
}
|
2024-02-14 05:27:28 +00:00
|
|
|
|
2024-01-31 04:25:07 +00:00
|
|
|
#[derive(Debug)]
|
2024-02-14 05:27:28 +00:00
|
|
|
pub enum ReadError{
|
2024-01-31 04:25:07 +00:00
|
|
|
RbxBinary(rbx_binary::DecodeError),
|
|
|
|
RbxXml(rbx_xml::DecodeError),
|
|
|
|
Io(std::io::Error),
|
|
|
|
UnknownFileFormat,
|
|
|
|
}
|
2024-02-14 05:27:28 +00:00
|
|
|
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{}
|
2024-01-31 04:25:07 +00:00
|
|
|
|
2024-10-04 02:35:59 +00:00
|
|
|
pub fn read<R:Read>(input:R)->Result<Model,ReadError>{
|
2024-01-31 04:25:07 +00:00
|
|
|
let mut buf=std::io::BufReader::new(input);
|
2024-02-14 05:27:28 +00:00
|
|
|
let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?;
|
2024-01-31 04:25:07 +00:00
|
|
|
match &peek[0..8]{
|
2024-10-04 02:35:59 +00:00
|
|
|
b"<roblox!"=>rbx_binary::from_reader(buf).map(Model::new).map_err(ReadError::RbxBinary),
|
|
|
|
b"<roblox "=>rbx_xml::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxXml),
|
2024-02-14 05:27:28 +00:00
|
|
|
_=>Err(ReadError::UnknownFileFormat),
|
2024-01-31 04:25:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-14 05:27:28 +00:00
|
|
|
//ConvertError
|
|
|
|
|
2024-03-13 20:34:06 +00:00
|
|
|
pub fn convert<AcquireRenderConfigId,AcquireMeshId>(
|
2024-10-04 02:35:59 +00:00
|
|
|
dom:impl AsRef<WeakDom>,
|
2024-03-13 20:34:06 +00:00
|
|
|
acquire_render_config_id:AcquireRenderConfigId,
|
|
|
|
acquire_mesh_id:AcquireMeshId
|
|
|
|
)->rbx::PartialMap1
|
|
|
|
where
|
|
|
|
AcquireRenderConfigId:FnMut(Option<&str>)->strafesnet_common::model::RenderConfigId,
|
|
|
|
AcquireMeshId:FnMut(&str)->strafesnet_common::model::MeshId,
|
|
|
|
{
|
2024-10-04 02:35:59 +00:00
|
|
|
rbx::convert(&dom.as_ref(),acquire_render_config_id,acquire_mesh_id)
|
2024-09-18 01:27:56 +00:00
|
|
|
}
|