Implement event configs, more interactions work

Implement interact event-action configurations.
More interactions work now, for more transitions, we just need to generate more configs (soon)
NOTE: this commit BREAKS your nap_gameserver.toml. To fix it, you have to add 'event_config_path' property into [assets] section of your config.
This commit is contained in:
xeon 2024-07-26 22:44:44 +03:00
parent c710716fa1
commit cbe169fe1a
12 changed files with 251 additions and 66 deletions

View file

@ -0,0 +1,98 @@
[
{
"event_id": 10000001,
"actions": [
{
"$type": "SwitchSection",
"section_id": 2,
"transform": "Workshop_PlayerPos_FromStreet",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000002,
"actions": [
{
"$type": "SwitchSection",
"section_id": 3,
"transform": "Garage_PlayerPos_FromStreet",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000003,
"actions": [
{
"$type": "SwitchSection",
"section_id": 1,
"transform": "Street_PlayerPos_FromWorkshop",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000004,
"actions": [
{
"$type": "SwitchSection",
"section_id": 1,
"transform": "Garage_PlayerPos_FromWorkshop",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000005,
"actions": [
{
"$type": "SwitchSection",
"section_id": 1,
"transform": "Street_PlayerPos_FromGarage",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000006,
"actions": [
{
"$type": "SwitchSection",
"section_id": 1,
"transform": "Workshop_PlayerPos_FromGarage",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000016,
"actions": [
{
"$type": "SwitchSection",
"section_id": 1,
"transform": "Garage_PlayerPos_FromStreet2",
"camera_x": 1,
"camera_y": 6000
}
]
},
{
"event_id": 10000017,
"actions": [
{
"$type": "SwitchSection",
"section_id": 1,
"transform": "Street_PlayerPos_FromGarage2",
"camera_x": 1,
"camera_y": 6000
}
]
}
]

View file

@ -7,6 +7,7 @@ version.workspace = true
# Serialization
serde.workspace = true
serde_json.workspace = true
prost.workspace = true
# Util
paste.workspace = true
@ -14,3 +15,6 @@ thiserror.workspace = true
# Tracing
tracing.workspace = true
# Internal
proto.workspace = true

View file

@ -0,0 +1,41 @@
use paste::paste;
use serde::Deserialize;
macro_rules! actions {
($($name:ident;)*) => {
paste! {
$(
mod [<$name:snake>];
pub use [<$name:snake>]::[<Config $name>];
)*
#[derive(Deserialize, Debug)]
#[serde(tag = "$type")]
pub enum ActionConfig {
$(
$name([<Config $name>]),
)*
}
impl ActionConfig {
pub fn to_protocol(&self) -> ::proto::ActionInfo {
use ::prost::Message;
match self {
$(
Self::$name(config) => ::proto::ActionInfo {
body: config.to_protocol().encode_to_vec(),
action_type: ::proto::ActionType::$name.into(),
..Default::default()
},
)*
}
}
}
}
};
}
actions! {
SwitchSection;
}

View file

@ -0,0 +1,21 @@
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct ConfigSwitchSection {
pub section_id: u32,
pub transform: String,
pub camera_x: u32,
pub camera_y: u32,
}
impl ConfigSwitchSection {
pub fn to_protocol(&self) -> ::proto::ActionSwitchSection {
::proto::ActionSwitchSection {
section: self.section_id,
transform: self.transform.clone(),
camera_x: self.camera_x,
camera_y: self.camera_y,
..Default::default()
}
}
}

29
nap_data/src/event/mod.rs Normal file
View file

@ -0,0 +1,29 @@
use std::sync::OnceLock;
use serde::Deserialize;
use crate::{action::ActionConfig, DataLoadError};
const INTERACT_CONFIG_JSON: &str = "Interacts.json";
static EVENT_GRAPHS: OnceLock<Vec<EventGraphConfig>> = OnceLock::new();
#[derive(Deserialize, Debug)]
pub struct EventGraphConfig {
pub event_id: u32,
pub actions: Vec<ActionConfig>,
}
pub(crate) fn load_event_graphs(path: &str) -> Result<(), DataLoadError> {
let data = std::fs::read_to_string(format!("{path}/{INTERACT_CONFIG_JSON}"))
.map_err(|err| DataLoadError::IoError(err))?;
let event_graphs = serde_json::from_str::<Vec<EventGraphConfig>>(&data)
.map_err(|err| DataLoadError::FromJsonError(String::from("EventGraphCollection"), err))?;
EVENT_GRAPHS.set(event_graphs).unwrap();
Ok(())
}
pub fn interacts() -> std::slice::Iter<'static, EventGraphConfig> {
EVENT_GRAPHS.get().unwrap().iter()
}

View file

@ -1,3 +1,5 @@
pub mod action;
pub mod event;
pub mod tables;
use std::{collections::HashMap, sync::OnceLock};
@ -8,6 +10,7 @@ use thiserror::Error;
#[derive(Serialize, Deserialize)]
pub struct AssetsConfig {
pub filecfg_path: String,
pub event_config_path: String,
pub usm_keys_path: String,
}
@ -23,6 +26,7 @@ static USM_KEY_MAP: OnceLock<HashMap<u32, u64>> = OnceLock::new();
pub fn init_data(config: &AssetsConfig) -> Result<(), DataLoadError> {
tables::load_tables(&config.filecfg_path)?;
event::load_event_graphs(&config.event_config_path)?;
if let Err(err) = load_usm_keys(&config.usm_keys_path) {
tracing::warn!("failed to load USM keys, in-game cutscenes will not work! Reason: {err}");
USM_KEY_MAP.set(HashMap::new()).unwrap();

View file

@ -19,6 +19,7 @@ impl Default for NapGSConfig {
database_credentials: DatabaseCredentials::default(),
assets: AssetsConfig {
filecfg_path: String::from("assets/FileCfg"),
event_config_path: String::from("assets/EventConfig"),
usm_keys_path: String::from("assets/VideoUSMEncKeys.json"),
},
}

View file

@ -10,7 +10,7 @@ pub async fn on_run_event_graph(
session
.notify(UpdateEventGraphScNotify {
owner_type: req.owner_type,
hlopenbmegp: req.hlopenbmegp,
tag: req.tag,
ddiamibnibg: req.ddiamibnibg,
npc_interaction: ENPCInteraction::OnInteract.to_string(),
ppabhkhbalm: true,

View file

@ -1,4 +1,7 @@
use data::tables::{ProcedureConfigID, SectionConfigID, TrainingQuestID};
use data::{
event,
tables::{ProcedureConfigID, SectionConfigID, TrainingQuestID},
};
use super::core::NetError;
@ -209,33 +212,16 @@ pub async fn on_interact_with_unit(
_player: &mut Player,
req: InteractWithUnitCsReq,
) -> NetResult<InteractWithUnitScRsp> {
use prost::Message;
use std::collections::HashMap;
tracing::info!("interact: {req:?}");
if req.interaction == 10000001 {
if let Some(graph) = event::interacts().find(|e| e.event_id == req.interaction as u32) {
session
.notify(SyncEventInfoScNotify {
owner_id: req.interaction as u32,
npc_interaction: ENPCInteraction::OnInteract.to_string(),
iddogdegagd: 1,
ddiamibnibg: 1,
hlopenbmegp: 1,
tag: req.unit_tag as u32,
owner_type: EventGraphOwnerType::SceneUnit.into(),
nheonpmbhcm: HashMap::from([(String::from("Radius"), 2000)]),
action_list: vec![ActionInfo {
body: ActionSwitchSection {
section: 2,
transform: String::from("Workshop_PlayerPos_FromStreet"),
camera_x: 1,
camera_y: 6000,
..Default::default()
}
.encode_to_vec(),
action_type: ActionType::SwitchSection.into(),
jdefffbinme: 1,
}],
action_list: graph.actions.iter().map(|a| a.to_protocol()).collect(),
..Default::default()
})
.await?;

View file

@ -114,6 +114,7 @@ impl Display for WeatherType {
}
}
#[allow(dead_code)]
#[derive(Debug, Clone, Copy)]
#[repr(u32)]
pub enum ENPCInteraction {

View file

@ -30,7 +30,7 @@ impl SceneUnit {
pub fn protocol_info(&self) -> SceneUnitProtocolInfo {
SceneUnitProtocolInfo {
is_interactable: !self.interacts.is_empty(),
tag: self.tag,
npc_id: self.tag,
interacts_info: self
.interacts
.iter()

View file

@ -1143,7 +1143,7 @@ pub struct Hpgaamcpfbc {
pub struct Aglckohdnkf {
#[xor(1068)]
#[prost(uint32, tag = "3")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(string, tag = "13")]
pub mlafgjjebbh: ::prost::alloc::string::String,
}
@ -2076,7 +2076,7 @@ pub struct Baedodlakel {
pub retcode: i32,
#[xor(7171)]
#[prost(uint32, tag = "1")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(2553)]
@ -2522,7 +2522,7 @@ pub struct Oiefichdomd {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Oiodkicpcbj {
#[prost(uint32, tag = "1")]
pub tag: u32,
pub npc_id: u32,
#[prost(uint32, tag = "2")]
pub interaction: u32,
}
@ -4440,7 +4440,7 @@ pub struct Gaghopjgnln {
pub retcode: i32,
#[xor(3602)]
#[prost(uint32, tag = "1")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(884)]
@ -4971,7 +4971,7 @@ pub struct Cfjiokcllmb {
pub struct Cpdiompfalg {
#[xor(7750)]
#[prost(uint32, tag = "4")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(1381)]
@ -5179,7 +5179,7 @@ pub struct RunEventGraphCsReq {
pub section_id: u32,
#[xor(3165)]
#[prost(uint32, tag = "15")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(933)]
@ -5879,7 +5879,7 @@ pub struct Eeoafhlgled {
pub struct Bffehemeicp {
#[xor(15922)]
#[prost(uint32, tag = "8")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(string, tag = "1")]
pub akchnobciej: ::prost::alloc::string::String,
#[prost(enumeration = "Jiedoddkipa", tag = "15")]
@ -6464,7 +6464,7 @@ pub struct SyncEventInfoScNotify {
pub eigemncjncc: u32,
#[xor(6757)]
#[prost(uint32, tag = "3")]
pub hlopenbmegp: u32,
pub tag: u32,
#[xor(12957)]
#[prost(uint32, tag = "6")]
pub ddiamibnibg: u32,
@ -6551,7 +6551,7 @@ pub struct Mbanldjmddn {
pub struct Famlaihncme {
#[xor(2772)]
#[prost(uint32, tag = "6")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(enumeration = "Mlnfloilgco", tag = "1")]
pub r#type: i32,
#[prost(string, tag = "13")]
@ -6746,7 +6746,7 @@ pub struct Kmehddnlfdn {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Dclkbepdchf {
#[prost(int32, tag = "1")]
pub tag: i32,
pub npc_id: i32,
#[prost(int32, tag = "2")]
pub interaction: i32,
#[prost(string, tag = "3")]
@ -8782,7 +8782,7 @@ pub struct Aoanhebnpjh {
pub bdhckehljcc: u32,
#[xor(11060)]
#[prost(uint32, tag = "7")]
pub tag: u32,
pub npc_id: u32,
#[xor(7244)]
#[prost(int32, tag = "3")]
pub score: i32,
@ -10937,7 +10937,7 @@ pub struct Hbkggckobgi {
pub struct Oajmdokhakn {
#[xor(8493)]
#[prost(uint32, tag = "7")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[derive(proto_gen::XorFields)]
@ -12191,7 +12191,7 @@ pub struct Boempcpfihm {
#[prost(int32, tag = "4")]
pub boanjgbnpff: i32,
#[prost(int32, tag = "5")]
pub tag: i32,
pub npc_id: i32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(1457)]
@ -13074,7 +13074,7 @@ pub struct Koiibmmeipn {
pub struct Ijeobbndlnc {
#[xor(13571)]
#[prost(uint32, tag = "9")]
pub hlopenbmegp: u32,
pub tag: u32,
#[xor(4626)]
#[prost(int32, tag = "2")]
pub retcode: i32,
@ -13910,7 +13910,7 @@ pub struct Kdhhapcnglm {
pub struct Gkdmnpgifpl {
#[xor(1938)]
#[prost(uint32, tag = "6")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(string, tag = "2")]
pub bbmjejifioj: ::prost::alloc::string::String,
}
@ -14719,7 +14719,7 @@ pub struct UpdateEventGraphScNotify {
pub gainclnemhc: u32,
#[xor(13729)]
#[prost(uint32, tag = "4")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(bool, tag = "13")]
pub ppabhkhbalm: bool,
#[prost(string, tag = "14")]
@ -15781,7 +15781,7 @@ pub struct Ldnfncjekle {
pub struct Kbmmaoocgkl {
#[xor(13122)]
#[prost(uint32, tag = "5")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[derive(proto_gen::XorFields)]
@ -16883,7 +16883,7 @@ pub struct Ingogjpccpb {
pub struct SceneUnitProtocolInfo {
#[xor(5788)]
#[prost(uint32, tag = "12")]
pub tag: u32,
pub npc_id: u32,
#[xor(2998)]
#[prost(uint32, tag = "15")]
pub gdflohpaopn: u32,
@ -17427,7 +17427,7 @@ pub struct Palpgoemaam {
pub retcode: i32,
#[xor(12673)]
#[prost(uint32, tag = "7")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(830)]
@ -17538,7 +17538,7 @@ pub struct Limolgnaacb {
pub struct Gjgneogccia {
#[xor(7036)]
#[prost(uint32, tag = "10")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(2993)]
@ -17681,7 +17681,7 @@ pub struct Ojpkokdacgg {
pub eigemncjncc: u32,
#[xor(7288)]
#[prost(uint32, tag = "6")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(string, repeated, tag = "13")]
pub bgcopembnij: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
@ -17731,7 +17731,7 @@ pub struct EnterSectionCsReq {
pub section_id: u32,
#[xor(148)]
#[prost(uint32, tag = "7")]
pub hlopenbmegp: u32,
pub tag: u32,
#[xor(13454)]
#[prost(uint32, tag = "14")]
pub deooedngagp: u32,
@ -18213,7 +18213,7 @@ pub struct Ipijdhhpbci {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Daofcbfkcji {
#[prost(int32, tag = "1")]
pub tag: i32,
pub npc_id: i32,
#[prost(int32, tag = "2")]
pub eokhlbdimgk: i32,
#[prost(int32, tag = "3")]
@ -18567,7 +18567,7 @@ pub struct Nmnghdcdpji {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Jcepnfchmkm {
#[prost(int32, tag = "1")]
pub tag: i32,
pub npc_id: i32,
#[prost(string, tag = "2")]
pub apklojloigc: ::prost::alloc::string::String,
#[prost(string, repeated, tag = "3")]
@ -19722,7 +19722,7 @@ pub struct Gnjgeaihgjm {
pub jjokgjkcjma: ::std::collections::HashMap<u32, bool>,
#[xor(5583)]
#[prost(uint32, tag = "6")]
pub tag: u32,
pub npc_id: u32,
#[xor(8431)]
#[prost(int32, tag = "5")]
pub retcode: i32,
@ -19759,7 +19759,7 @@ pub struct Ndljgkedcnp {
#[prost(int32, tag = "4")]
pub boanjgbnpff: i32,
#[prost(int32, tag = "5")]
pub tag: i32,
pub npc_id: i32,
}
#[derive(proto_gen::CmdID)]
#[derive(proto_gen::XorFields)]
@ -21479,7 +21479,7 @@ pub struct Keepnkfcnoc {
pub struct Chepdnkmgnl {
#[xor(9491)]
#[prost(uint32, tag = "13")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(enumeration = "Lhkfpefffll", tag = "11")]
pub iegloobhlll: i32,
}
@ -22048,7 +22048,7 @@ pub struct Bbpnnjafolo {
pub struct Peifkmnegih {
#[xor(13941)]
#[prost(uint32, tag = "8")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(812)]
@ -23225,7 +23225,7 @@ pub struct Piffkdmahmh {
pub struct Hhjneklblkj {
#[xor(7341)]
#[prost(uint32, tag = "12")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(3188)]
@ -23332,7 +23332,7 @@ pub struct Dcjdimilijl {
pub struct Jocpngokpcm {
#[xor(3725)]
#[prost(uint32, tag = "15")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(5206)]
@ -23596,7 +23596,7 @@ pub struct Dglhplgglfe {
#[prost(string, tag = "1")]
pub aflpmeafbad: ::prost::alloc::string::String,
#[prost(int32, tag = "2")]
pub tag: i32,
pub npc_id: i32,
#[prost(int32, tag = "3")]
pub ddmcefolplg: i32,
#[prost(bool, tag = "4")]
@ -23711,7 +23711,7 @@ pub struct Ikfciogcbka {
pub iijjpdfadgf: ::prost::alloc::string::String,
#[xor(2568)]
#[prost(uint32, tag = "8")]
pub hlopenbmegp: u32,
pub tag: u32,
#[xor(2049)]
#[prost(uint32, tag = "7")]
pub gdclnbdjmdd: u32,
@ -25407,7 +25407,7 @@ pub struct Ecegenamnmo {
pub owner_id: u32,
#[xor(5092)]
#[prost(uint32, tag = "6")]
pub hlopenbmegp: u32,
pub tag: u32,
#[xor(635)]
#[prost(uint32, tag = "3")]
pub section_id: u32,
@ -26962,7 +26962,7 @@ pub struct Ibapndpfkgg {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Epfaaflihgo {
#[prost(message, optional, tag = "1")]
pub tag: ::core::option::Option<StringEntry>,
pub npc_id: ::core::option::Option<StringEntry>,
#[prost(string, tag = "2")]
pub apklojloigc: ::prost::alloc::string::String,
#[prost(string, repeated, tag = "3")]
@ -28616,7 +28616,7 @@ pub struct Mbminkaklna {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Fooinfahhjg {
#[prost(uint32, tag = "1")]
pub tag: u32,
pub npc_id: u32,
#[prost(uint32, tag = "2")]
pub interaction: u32,
}
@ -28628,7 +28628,7 @@ pub struct Dagkncdciab {
#[prost(string, tag = "1")]
pub aflpmeafbad: ::prost::alloc::string::String,
#[prost(message, optional, tag = "2")]
pub tag: ::core::option::Option<StringEntry>,
pub npc_id: ::core::option::Option<StringEntry>,
#[prost(int32, tag = "3")]
pub ddmcefolplg: i32,
#[prost(bool, tag = "4")]
@ -29099,7 +29099,7 @@ pub struct Fcdfjopfekh {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Hklkphimdcd {
#[prost(uint32, tag = "1")]
pub tag: u32,
pub npc_id: u32,
#[prost(bool, tag = "2")]
pub bpagmdoephl: bool,
#[prost(message, repeated, tag = "3")]
@ -29342,7 +29342,7 @@ pub struct Dbmckgncdga {
pub jocebljmdfk: bool,
#[xor(4805)]
#[prost(uint32, tag = "12")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[derive(proto_gen::XorFields)]
@ -30831,7 +30831,7 @@ pub struct Cpoiohebdph {
#[prost(uint32, tag = "1")]
pub ngejdpkcanl: u32,
#[prost(uint32, tag = "2")]
pub hlopenbmegp: u32,
pub tag: u32,
#[prost(int64, tag = "3")]
pub clmligkfkfa: i64,
#[prost(message, optional, tag = "4")]
@ -31870,7 +31870,7 @@ pub struct Aeemabfcakl {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Omplblbbflb {
#[prost(int32, tag = "1")]
pub tag: i32,
pub npc_id: i32,
#[prost(int32, tag = "2")]
pub eokhlbdimgk: i32,
#[prost(int32, tag = "3")]
@ -32320,7 +32320,7 @@ pub struct Leildpdhhdj {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Oflcipncgff {
#[prost(message, optional, tag = "1")]
pub tag: ::core::option::Option<StringEntry>,
pub npc_id: ::core::option::Option<StringEntry>,
#[prost(bool, tag = "2")]
pub ihgicanfioc: bool,
#[prost(message, repeated, tag = "3")]
@ -33335,7 +33335,7 @@ pub struct Aojdpeneoac {
pub struct Loepnpaebfn {
#[xor(9149)]
#[prost(uint32, tag = "5")]
pub hlopenbmegp: u32,
pub tag: u32,
#[xor(6526)]
#[prost(int32, tag = "1")]
pub retcode: i32,
@ -33817,7 +33817,7 @@ pub struct Ldffgpohghg {}
pub struct Kdlhoagklkj {
#[xor(8861)]
#[prost(uint32, tag = "9")]
pub hlopenbmegp: u32,
pub tag: u32,
}
#[derive(proto_gen::CmdID)]
#[cmdid(2875)]