Implement Lua Scene loading

This commit is contained in:
Nobody 2022-02-02 20:42:41 +05:00
parent 9b088aaf80
commit 2cd0c7d840
7 changed files with 312 additions and 3 deletions

4
.gitignore vendored
View File

@ -22,5 +22,5 @@ Cargo.lock
# Local database
database.db3*
# JSON files
/json/
# Data files
/data/

View File

@ -9,6 +9,7 @@ edition = "2018"
kcp = { path = "../kcp" }
mhycrypt = { path = "../mhycrypt" }
proto = { path = "../proto" }
lua_serde = { path = "../lua_serde" }
packet-processor-macro = { path = "packet-processor-macro" }
packet-processor = { path = "packet-processor" }

View File

@ -0,0 +1,122 @@
use std::collections::HashMap;
use std::result::Result;
use lua_serde::from_file;
use super::scene_config::Group;
use super::scene_config::Block;
use super::scene_config::Scene;
#[derive(Debug)]
struct InternalSceneData {
pub scene_id: u32,
pub scene: Scene,
pub blocks: HashMap<u32,InternalBlockData>,
}
#[derive(Debug)]
struct InternalBlockData {
pub scene_id: u32,
pub block_id: u32,
pub block: Block,
pub groups: HashMap<u32,InternalGroupData>,
}
#[derive(Debug)]
struct InternalGroupData {
pub scene_id: u32,
pub block_id: u32,
pub group_id: u32,
pub group: Group,
// No extra data here
}
pub struct LuaManager {
scenes_data: HashMap<u32,InternalSceneData>,
}
// TODO: Hack-y stuff!
macro_rules! scene_name { () => ("{}/Scene/{}/scene{}.lua")}
macro_rules! block_name { () => ("{}/Scene/{}/scene{}_block{}.lua")}
macro_rules! group_name { () => ("{}/Scene/{}/scene{}_group{}.lua")}
impl LuaManager {
pub fn new(directory: &str) -> LuaManager {
let scenes_to_load = vec![3]; // TODO!
let scenes = Self::load_scenes(directory, &scenes_to_load);
LuaManager {
scenes_data: scenes,
}
}
fn load_scenes(directory: &str, scenes_to_load: &Vec<u32>) -> HashMap<u32,InternalSceneData> {
scenes_to_load
.iter()
.map(|scene_id| (*scene_id, Self::load_scene(directory, *scene_id)))
.collect()
}
fn load_scene(directory: &str, scene_id: u32) -> InternalSceneData {
let filename = format!(scene_name!(), directory, scene_id, scene_id);
let scene: Scene = from_file(&filename).unwrap(); // TODO: error handling!
let blocks = scene.blocks
.iter()
.map(|(key, block_id)| (*block_id, Self::load_block(directory, scene_id, *block_id)))
.collect();
InternalSceneData {
scene_id,
scene,
blocks,
}
}
fn load_block(directory: &str, scene_id: u32, block_id: u32) -> InternalBlockData {
let filename = format!(block_name!(), directory, scene_id, scene_id, block_id);
let block: Block = from_file(&filename).unwrap(); // TODO: error handling!
let groups = if false
{
// TODO: should be this! But some groups are missing
block.groups
.iter()
.map(|(key, group_info)| (group_info.id, Self::load_group(directory, scene_id, block_id, group_info.id).unwrap() /* Unwrap to make compiler happy*/))
.collect()
} else {
let (groups, errors): (Vec<_>, Vec<_>) = block.groups
.iter()
.map(|(key, group_info)| (group_info.id, Self::load_group(directory, scene_id, block_id, group_info.id)))
.partition(|(group_id, result)| result.is_ok());
let groups = groups.into_iter().map(|(group_id, result)| (group_id, result.unwrap())).collect();
let errors: Vec<_> = errors.into_iter().map(|(group_id, result)| (group_id, result.unwrap_err())).collect();
println!("Missing groups: {:?}", errors);
groups
};
InternalBlockData {
scene_id,
block_id,
block,
groups,
}
}
fn load_group(directory: &str, scene_id: u32, block_id: u32, group_id: u32) -> Result<InternalGroupData, std::io::Error> {
let filename = format!(group_name!(), directory, scene_id, scene_id, group_id);
//let group: Group = from_file(&filename).unwrap(); // TODO: error handling!
let group: Group = from_file(&filename)?;
Ok(InternalGroupData {
scene_id,
block_id,
group_id,
group,
})
}
}

4
src/luamanager/mod.rs Normal file
View File

@ -0,0 +1,4 @@
mod lua_manager;
mod scene_config;
pub use self::lua_manager::LuaManager;

View File

@ -0,0 +1,178 @@
use std::collections::HashMap;
use serde::Deserialize;
// sceneX.lua
#[derive(Deserialize, PartialEq, Debug)]
pub struct Vector<T> {
#[serde(default)]
pub x: T,
#[serde(default)]
pub y: T,
#[serde(default)]
pub z: T,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct BlockRect {
pub min: Vector<f32>,
pub max: Vector<f32>,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct SceneConfig {
pub born_rot: Vector<f32>,
pub born_pos: Vector<f32>,
pub begin_pos: Vector<f32>,
pub size: Vector<f32>,
#[serde(default)]
pub die_y: f32,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Scene {
pub blocks: HashMap<u32,u32>,
#[serde(default)]
pub block_rects: HashMap<u32,BlockRect>,
#[serde(default)]
pub routes_config: HashMap<u32,String>,
#[serde(default)]
pub dummy_points: HashMap<u32,String>,
pub scene_config: SceneConfig,
}
// sceneX_blockY.lua
#[derive(Deserialize, PartialEq, Debug)]
pub struct Block {
pub groups: HashMap<u32,GroupInfo>,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct GroupInfo {
pub is_replaceable: Option<ComplicatedBool>,
#[serde(default)]
pub dynamic_load: bool,
pub id: u32,
pub area: Option<u32>,
pub pos: Vector<f32>,
pub business: Option<Business>,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct ComplicatedBool {
pub version: u32,
pub value: bool,
pub new_bin_only: bool,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Business {
pub r#type: u32,
}
// sceneX_groupZ.lua
#[derive(Deserialize, PartialEq, Debug)]
pub struct Group {
pub init_config: Option<GroupInitConfig>,
#[serde(default)]
pub suites: HashMap<u32,Suite>,
#[serde(default)]
pub npcs: HashMap<u32,Npc>,
#[serde(default)]
pub variables: HashMap<u32,Variable>,
#[serde(default)]
pub triggers: HashMap<u32,u32>,
#[serde(default)]
pub regions: HashMap<u32,u32>,
#[serde(default)]
pub gadgets: HashMap<u32,Gadget>,
#[serde(default)]
pub monsters: HashMap<u32,Monster>,
// MovePlatform - Function???
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Suite {
pub rand_weight: u32,
#[serde(default)]
pub npcs: HashMap<u32,u32>,
// Variables?
#[serde(default)]
pub triggers: HashMap<u32,u32>,
#[serde(default)]
pub regions: HashMap<u32,u32>,
#[serde(default)]
pub gadgets: HashMap<u32,u32>,
#[serde(default)]
pub monsters: HashMap<u32,u32>,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct GroupInitConfig {
pub end_suite: Option<u32>,
//#[serde(default)]
pub rand_suite: bool,
pub suite: u32,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Variable {
pub name: String,
pub value: u32,
pub no_refresh: bool,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Monster {
pub rot: Vector<f32>,
pub pos: Vector<f32>,
pub config_id: u32,
pub level: u32,
pub monster_id: u32,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Npc {
pub rot: Vector<f32>,
pub pos: Vector<f32>,
pub config_id: u32,
pub npc_id: u32,
pub area_id: Option<u32>,
pub room: Option<u32>,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct Gadget {
pub rot: Vector<f32>,
pub pos: Vector<f32>,
pub config_id: u32,
pub level: u32,
pub gadget_id: u32,
#[serde(default)]
pub drop_count: u32,
pub explore: Option<ExploreInfo>,
#[serde(default)]
pub isOneoff: bool,
pub area_id: Option<u32>,
#[serde(default)]
pub persistent: bool,
pub chest_drop_id: Option<u32>,
#[serde(default)]
pub start_route: bool,
#[serde(default)]
pub is_use_point_array: bool,
}
#[derive(Deserialize, PartialEq, Debug)]
pub struct ExploreInfo {
pub exp: u32,
pub name: String,
}

View File

@ -9,11 +9,13 @@ mod server;
mod utils;
mod dbmanager;
mod jsonmanager;
mod luamanager;
use server::NetworkServer;
use server::DispatchServer;
use dbmanager::DatabaseManager;
use jsonmanager::JsonManager;
use luamanager::LuaManager;
fn main() {
pretty_env_logger::init();

View File

@ -9,6 +9,7 @@ use crate::server::IpcMessage;
use crate::DatabaseManager;
use crate::JsonManager;
use crate::LuaManager;
use crate::server::LoginManager;
use std::sync::Arc;
@ -24,8 +25,9 @@ pub struct GameServer {
impl GameServer {
pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer {
let db = Arc::new(DatabaseManager::new("sqlite://./database.db3"));
let jm = Arc::new(JsonManager::new("./json"));
let jm = Arc::new(JsonManager::new("./data/json"));
let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone());
let lum = Arc::new(LuaManager::new("./data/lua"));
let gs = GameServer {
packets_to_process_rx: packets_to_process_rx,