Compare commits

...

6 commits

Author SHA1 Message Date
5586f4cae1 Implement skins unlock/dress/undress 2025-03-20 20:13:48 +03:00
42fdc33849 Fixed HDD commissions | Reverted flatc expect (#6)
Reviewed-on: #6
Co-authored-by: traffic95 <traffic95@xeondev.com>
Co-committed-by: traffic95 <traffic95@xeondev.com>
2025-03-18 21:50:55 +00:00
8f606a8256 Add property calculations (#5)
Reviewed-on: #5
Co-authored-by: traffic95 <traffic95@xeondev.com>
Co-committed-by: traffic95 <traffic95@xeondev.com>
2025-03-18 20:44:22 +00:00
520bc2dc3b Implement Beginner Procedure 2025-03-14 23:28:27 +03:00
f89b49f903 dispatch-server: unhardcode cdn_conf_ext and load res versions from configuration file 2025-03-13 18:16:48 +03:00
de4bf109ed Adjust protocol structs naming 2025-03-12 19:01:55 +03:00
86 changed files with 20420 additions and 7990 deletions

2
Cargo.lock generated
View file

@ -3652,6 +3652,7 @@ dependencies = [
"serde_json",
"thiserror 2.0.11",
"tokio",
"toml",
"tracing",
"tracing-subscriber",
"trigger-cryptography",
@ -3749,6 +3750,7 @@ version = "0.0.1"
dependencies = [
"num_enum",
"prost",
"trigger-fileconfig",
]
[[package]]

View file

@ -6,6 +6,7 @@
"UnlockAllHollow",
"UnlockAllHollowBuff",
"UnlockAllCafeItem",
"UnlockAllAvatarSkin",
"finishquest 1 0",
"finishquest 3 0",
"addquest 5 4030136"

View file

@ -1,7 +1,10 @@
use std::collections::HashMap;
use trigger_protocol::DungeonEquipInfo;
pub struct AvatarUnit {
pub avatar_id: u32,
pub properties: HashMap<u32, i32>,
}
pub struct BuddyUnit {
@ -29,6 +32,7 @@ impl Dungeon {
.iter()
.map(|unit| AvatarUnitInfo {
avatar_id: unit.avatar_id,
properties: unit.properties.clone(),
})
.collect(),
buddy_list: self

View file

@ -1,4 +1,5 @@
mod dungeon;
mod property_util;
pub use dungeon::*;
pub mod scene;
@ -28,7 +29,7 @@ impl GameState {
} => Self {
filecfg,
scene: Scene::Fight(FightScene {
event_id: Self::get_scene_event_id(filecfg, *quest_id, (*play_type).into()),
scene_id: Self::get_scene_id(filecfg, *quest_id, (*play_type).into()),
play_type: (*play_type).into(),
perform: ScenePerform {
time: String::from("Morning"),
@ -39,17 +40,20 @@ impl GameState {
quest_id: *quest_id,
avatar_list: avatar_id_list
.iter()
.map(|&avatar_id| AvatarUnit { avatar_id })
.map(|&avatar_id| AvatarUnit {
avatar_id,
properties: property_util::calculate_for_avatar(
avatar_id,
filecfg,
dungeon_equip,
),
})
.collect(),
buddy_list: vec![BuddyUnit {
buddy_type: 0,
buddy_id: 50001,
}],
inner_quests: vec![Self::get_scene_event_id(
filecfg,
*quest_id,
(*play_type).into(),
)],
inner_quests: vec![Self::get_scene_id(filecfg, *quest_id, (*play_type).into())],
equip: dungeon_equip.clone(),
},
},
@ -61,7 +65,7 @@ impl GameState {
dungeon_equip,
} => Self {
scene: Scene::Rally(RallyScene {
event_id: Self::get_scene_event_id(filecfg, *quest_id, (*play_type).into()),
scene_id: Self::get_scene_id(filecfg, *quest_id, (*play_type).into()),
perform: ScenePerform {
time: String::from("Morning"),
weather: String::from("SunShine"),
@ -71,17 +75,20 @@ impl GameState {
quest_id: *quest_id,
avatar_list: avatar_id_list
.iter()
.map(|&avatar_id| AvatarUnit { avatar_id })
.map(|&avatar_id| AvatarUnit {
avatar_id,
properties: property_util::calculate_for_avatar(
avatar_id,
filecfg,
dungeon_equip,
),
})
.collect(),
buddy_list: vec![BuddyUnit {
buddy_type: 0,
buddy_id: 50001,
}],
inner_quests: vec![Self::get_scene_event_id(
filecfg,
*quest_id,
(*play_type).into(),
)],
inner_quests: vec![Self::get_scene_id(filecfg, *quest_id, (*play_type).into())],
equip: dungeon_equip.clone(),
},
filecfg,
@ -90,7 +97,7 @@ impl GameState {
})
}
fn get_scene_event_id(filecfg: &NapFileCfg, quest_id: u32, play_type: ELocalPlayType) -> u32 {
fn get_scene_id(filecfg: &NapFileCfg, quest_id: u32, play_type: ELocalPlayType) -> u32 {
match play_type {
ELocalPlayType::TrainingRoom => 19800014,
ELocalPlayType::ArchiveBattle => filecfg
@ -120,7 +127,7 @@ impl GameState {
debug!(
"the battle is over, quest_id: {}, event_id: {}",
self.dungeon.quest_id,
self.scene.get_event_id()
self.scene.get_scene_id()
);
vec![

View file

@ -0,0 +1,717 @@
use std::collections::HashMap;
use trigger_fileconfig::{
AvatarBattleTemplate, AvatarLevelAdvanceTemplate, AvatarPassiveSkillTemplate, NapFileCfg,
WeaponLevelTemplate, WeaponStarTemplate, WeaponTemplate,
};
use trigger_logic::{battle::EPropertyType, skill::EAvatarSkillType};
use trigger_protocol::{Avatar, DungeonEquipInfo, Equip, Weapon};
struct AvatarFileCfg<'a> {
pub avatar_battle_template: AvatarBattleTemplate<'a>,
pub avatar_passive_skill_templates: Vec<AvatarPassiveSkillTemplate<'a>>,
pub avatar_level_advances: Vec<AvatarLevelAdvanceTemplate<'a>>,
}
struct WeaponFileCfg<'a> {
pub weapon_template: WeaponTemplate<'a>,
pub weapon_level_template: WeaponLevelTemplate<'a>,
pub weapon_star_template: WeaponStarTemplate<'a>,
}
const BEN_AVATAR_ID: u32 = 1121;
const BEN_CORE_PASSIVE_PERCENTAGE: [i32; 7] = [40, 46, 52, 60, 66, 72, 80];
pub fn calculate_for_avatar(
avatar_id: u32,
filecfg: &'static NapFileCfg,
dungeon_equip: &DungeonEquipInfo,
) -> HashMap<u32, i32> {
let mut calculated_properties = HashMap::<_, _>::new();
let Some(player_avatar) = dungeon_equip
.avatar_list
.iter()
.find(|a| (*a).id == avatar_id)
else {
return calculated_properties;
};
let Some(avatar_file_cfg) = get_avatar_filecfg(avatar_id, filecfg) else {
return calculated_properties;
};
insert_avatar_battle_template_properties(&avatar_file_cfg, &mut calculated_properties);
insert_avatar_battle_level_advance_properties(
&avatar_file_cfg,
player_avatar,
&mut calculated_properties,
);
perform_avatar_growth_promotion_calculations(player_avatar, &mut calculated_properties);
add_avatar_passive_skill_properties(
&avatar_file_cfg,
player_avatar,
&mut calculated_properties,
);
let player_weapon = dungeon_equip
.weapon_list
.iter()
.find(|w| w.uid == player_avatar.cur_weapon_uid);
if player_weapon.is_some() {
match get_weapon_filecfg(player_weapon.unwrap(), filecfg) {
Some(weapon_file_cfg) => {
add_weapon_template_properties(&weapon_file_cfg, &mut calculated_properties);
}
None => {}
};
}
let player_dressed_equip_uids: Vec<u32> = player_avatar
.dressed_equip_list
.iter()
.map(|de| de.equip_uid)
.collect();
let player_equips: Vec<&Equip> = dungeon_equip
.equip_list
.iter()
.filter(|e| player_dressed_equip_uids.contains(&e.uid))
.collect();
if player_equips.len() > 0 {
add_player_equip_properties(&player_equips, filecfg, &mut calculated_properties);
add_equipment_suit_properties(&player_equips, filecfg, &mut calculated_properties);
}
calculate_final_properties(&mut calculated_properties);
add_ben_core_passive(avatar_id, player_avatar, &mut calculated_properties);
remove_custom_properties(&mut calculated_properties);
set_battle_properties(&mut calculated_properties);
calculated_properties
}
fn get_avatar_filecfg(
avatar_id: u32,
filecfg: &'static NapFileCfg,
) -> Option<AvatarFileCfg<'static>> {
let Some(avatar_battle_template) = filecfg
.avatar_battle_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.id() == avatar_id as i32)
else {
return None;
};
let avatar_passive_skill_templates: Vec<AvatarPassiveSkillTemplate> = filecfg
.avatar_passive_skill_template_tb()
.data()
.unwrap()
.iter()
.filter(|tmpl| tmpl.avatar_id() == avatar_id as i32)
.collect();
if avatar_passive_skill_templates.len() == 0 {
return None;
}
let avatar_level_advances: Vec<AvatarLevelAdvanceTemplate> = filecfg
.avatar_level_advance_template_tb()
.data()
.unwrap()
.iter()
.filter(|tmpl| tmpl.avatar_id() == avatar_id as i32)
.collect();
if avatar_level_advances.len() == 0 {
return None;
}
Some(AvatarFileCfg {
avatar_battle_template,
avatar_passive_skill_templates,
avatar_level_advances,
})
}
fn insert_avatar_battle_template_properties(
avatar_file_cfg: &AvatarFileCfg,
properties: &mut HashMap<u32, i32>,
) {
properties.insert(
EPropertyType::HpMaxBase.into(),
avatar_file_cfg.avatar_battle_template.hp_max(),
);
properties.insert(
EPropertyType::HpMaxGrowth.into(),
avatar_file_cfg.avatar_battle_template.health_growth(),
);
properties.insert(
EPropertyType::AtkBase.into(),
avatar_file_cfg.avatar_battle_template.attack(),
);
properties.insert(
EPropertyType::AtkGrowth.into(),
avatar_file_cfg.avatar_battle_template.attack_growth(),
);
properties.insert(
EPropertyType::BreakStunBase.into(),
avatar_file_cfg.avatar_battle_template.break_stun(),
);
properties.insert(
EPropertyType::DefBase.into(),
avatar_file_cfg.avatar_battle_template.defence(),
);
properties.insert(
EPropertyType::DefGrowth.into(),
avatar_file_cfg.avatar_battle_template.defence_growth(),
);
properties.insert(
EPropertyType::CritBase.into(),
avatar_file_cfg.avatar_battle_template.crit(),
);
properties.insert(
EPropertyType::CritDmgBase.into(),
avatar_file_cfg.avatar_battle_template.crit_damage(),
);
properties.insert(
EPropertyType::PenBase.into(),
avatar_file_cfg.avatar_battle_template.pen_rate(),
);
properties.insert(
EPropertyType::PenValueBase.into(),
avatar_file_cfg.avatar_battle_template.pen_delta(),
);
properties.insert(
EPropertyType::SpRecoverBase.into(),
avatar_file_cfg.avatar_battle_template.sp_recover(),
);
properties.insert(
EPropertyType::ElementMysteryBase.into(),
avatar_file_cfg.avatar_battle_template.element_mystery(),
);
properties.insert(
EPropertyType::ElementAbnormalPowerBase.into(),
avatar_file_cfg
.avatar_battle_template
.element_abnormal_power(),
);
}
fn insert_avatar_battle_level_advance_properties(
avatar_file_cfg: &AvatarFileCfg,
player_avatar: &Avatar,
properties: &mut HashMap<u32, i32>,
) {
let Some(avatar_level_advance) = avatar_file_cfg
.avatar_level_advances
.iter()
.find(|tmpl| tmpl.id() == player_avatar.rank as i32)
else {
properties.insert(EPropertyType::HpMaxAdvance.into(), 0);
properties.insert(EPropertyType::AtkAdvance.into(), 0);
properties.insert(EPropertyType::DefAdvance.into(), 0);
return;
};
properties.insert(
EPropertyType::HpMaxAdvance.into(),
avatar_level_advance.hp_max(),
);
properties.insert(
EPropertyType::AtkAdvance.into(),
avatar_level_advance.attack(),
);
properties.insert(
EPropertyType::DefAdvance.into(),
avatar_level_advance.defence(),
);
}
fn perform_avatar_growth_promotion_calculations(
player_avatar: &Avatar,
properties: &mut HashMap<u32, i32>,
) {
properties.insert(
EPropertyType::HpMaxBase.into(),
properties.get(&EPropertyType::HpMaxBase.into()).unwrap()
+ (((player_avatar.level - 1) as f32
* *properties.get(&EPropertyType::HpMaxGrowth.into()).unwrap() as f32)
/ 10000f32) as i32
+ properties.get(&EPropertyType::HpMaxAdvance.into()).unwrap(),
);
properties.insert(
EPropertyType::AtkBase.into(),
properties.get(&EPropertyType::AtkBase.into()).unwrap()
+ (((player_avatar.level - 1) as f32
* *properties.get(&EPropertyType::AtkGrowth.into()).unwrap() as f32)
/ 10000f32) as i32
+ properties.get(&EPropertyType::AtkAdvance.into()).unwrap(),
);
properties.insert(
EPropertyType::DefBase.into(),
properties.get(&EPropertyType::DefBase.into()).unwrap()
+ (((player_avatar.level - 1) as f32
* *properties.get(&EPropertyType::DefGrowth.into()).unwrap() as f32)
/ 10000f32) as i32
+ properties.get(&EPropertyType::DefAdvance.into()).unwrap(),
);
}
fn add_avatar_passive_skill_properties(
avatar_file_cfg: &AvatarFileCfg,
player_avatar: &Avatar,
properties: &mut HashMap<u32, i32>,
) {
let passive_skill_level = player_avatar
.skill_type_level
.iter()
.find(|s| s.skill_type == EAvatarSkillType::CoreSkill as u32)
.unwrap()
.level;
avatar_file_cfg
.avatar_passive_skill_templates
.iter()
.find(|a| a.unlock_passive_skill_level() == passive_skill_level as i32)
.map(|tmpl| tmpl.propertys().unwrap())
.unwrap()
.iter()
.for_each(|p| {
properties.insert(
p.property() as u32,
properties.get(&(p.property() as u32)).unwrap_or(&0) + p.value(),
);
});
}
fn get_weapon_filecfg(
player_weapon: &Weapon,
filecfg: &'static NapFileCfg,
) -> Option<WeaponFileCfg<'static>> {
let Some(weapon_template) = filecfg
.weapon_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.item_id() == player_weapon.id as i32)
else {
return None;
};
let Some(weapon_level_template) = filecfg
.weapon_level_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.level() == player_weapon.level as i32)
else {
return None;
};
let Some(weapon_star_template) = filecfg
.weapon_star_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.star() == player_weapon.star as i32)
else {
return None;
};
Some(WeaponFileCfg {
weapon_template,
weapon_level_template,
weapon_star_template,
})
}
fn add_weapon_template_properties(
weapon_file_cfg: &WeaponFileCfg,
properties: &mut HashMap<u32, i32>,
) {
let base_property = weapon_file_cfg.weapon_template.base_property().unwrap();
let base_property_value = base_property.value()
+ (base_property.value() as f32 * weapon_file_cfg.weapon_level_template.rate() as f32
/ 10000f32) as i32
+ (base_property.value() as f32 * weapon_file_cfg.weapon_star_template.star_rate() as f32
/ 10000f32) as i32;
properties.insert(
base_property.property() as u32,
*properties
.get(&(base_property.property() as u32))
.unwrap_or(&0)
+ base_property_value,
);
let rand_property = weapon_file_cfg.weapon_template.rand_property().unwrap();
let rand_property_value = rand_property.value()
+ (rand_property.value() as f32 * weapon_file_cfg.weapon_star_template.rand_rate() as f32
/ 10000f32) as i32;
properties.insert(
rand_property.property() as u32,
*properties
.get(&(rand_property.property() as u32))
.unwrap_or(&0)
+ rand_property_value,
);
}
fn add_player_equip_properties(
player_equips: &Vec<&Equip>,
filecfg: &'static NapFileCfg,
properties: &mut HashMap<u32, i32>,
) {
player_equips.iter().for_each(|pe| {
let equip_rarity = (pe.id / 10) % 10;
let property_rate = filecfg
.equipment_level_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.rarity() == equip_rarity as i32 && tmpl.level() == pe.level as i32)
.map(|tmpl| tmpl.property_rate())
.unwrap_or(1);
pe.propertys.iter().for_each(|p| {
properties.insert(
p.key,
properties.get(&p.key).unwrap_or(&0)
+ p.base_value as i32
+ (p.base_value as f32 * property_rate as f32 / 10000f32) as i32,
);
});
pe.sub_propertys.iter().for_each(|p| {
properties.insert(
p.key,
properties.get(&p.key).unwrap_or(&0)
+ (p.base_value as f32 * p.add_value as f32) as i32,
);
});
});
}
fn add_equipment_suit_properties(
player_equips: &Vec<&Equip>,
filecfg: &'static NapFileCfg,
properties: &mut HashMap<u32, i32>,
) {
let mut suit_counts = HashMap::<i32, i32>::new();
player_equips.iter().for_each(|pe| {
let suit_id = pe.id as i32 / 100 * 100;
suit_counts.insert(suit_id, *suit_counts.get(&suit_id).unwrap_or(&0) + 1);
});
suit_counts.iter().for_each(|sc| {
let Some(equipment_suit_template) = filecfg
.equipment_suit_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.id() == *sc.0)
else {
return;
};
if equipment_suit_template.primary_condition() <= *sc.1 {
equipment_suit_template
.primary_suit_propertys()
.unwrap()
.iter()
.for_each(|p| {
properties.insert(
p.property() as u32,
properties.get(&(p.property() as u32)).unwrap_or(&0) + p.value(),
);
});
}
});
}
fn calculate_final_properties(properties: &mut HashMap<u32, i32>) {
properties.insert(
EPropertyType::HpMax.into(),
properties.get(&EPropertyType::HpMaxBase.into()).unwrap()
+ (*properties.get(&EPropertyType::HpMaxBase.into()).unwrap() as f32
* *properties
.get(&EPropertyType::HpMaxRatio.into())
.unwrap_or(&0) as f32
/ 10000f32)
.ceil() as i32
+ properties
.get(&EPropertyType::HpMaxDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::Atk.into(),
properties.get(&EPropertyType::AtkBase.into()).unwrap()
+ (*properties.get(&EPropertyType::AtkBase.into()).unwrap() as f32
* *properties
.get(&EPropertyType::AtkRatio.into())
.unwrap_or(&0) as f32
/ 10000f32) as i32
+ properties
.get(&EPropertyType::AtkDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::BreakStun.into(),
properties
.get(&EPropertyType::BreakStunBase.into())
.unwrap()
+ (*properties
.get(&EPropertyType::BreakStunBase.into())
.unwrap() as f32
* *properties
.get(&EPropertyType::BreakStunRatio.into())
.unwrap_or(&0) as f32
/ 10000f32) as i32
+ properties
.get(&EPropertyType::BreakStunDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::Def.into(),
properties.get(&EPropertyType::DefBase.into()).unwrap()
+ (*properties.get(&EPropertyType::DefBase.into()).unwrap() as f32
* *properties
.get(&EPropertyType::DefRatio.into())
.unwrap_or(&0) as f32
/ 10000f32) as i32
+ properties
.get(&EPropertyType::DefDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::Crit.into(),
properties.get(&EPropertyType::CritBase.into()).unwrap()
+ properties
.get(&EPropertyType::CritDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::CritDmg.into(),
properties.get(&EPropertyType::CritDmgBase.into()).unwrap()
+ properties
.get(&EPropertyType::CritDmgDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::Pen.into(),
properties.get(&EPropertyType::PenBase.into()).unwrap()
+ properties
.get(&EPropertyType::PenDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::PenValue.into(),
properties.get(&EPropertyType::PenValueBase.into()).unwrap()
+ properties
.get(&EPropertyType::PenValueDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::SpRecover.into(),
properties
.get(&EPropertyType::SpRecoverBase.into())
.unwrap()
+ (*properties
.get(&EPropertyType::SpRecoverBase.into())
.unwrap() as f32
* *properties
.get(&EPropertyType::SpRecoverRatio.into())
.unwrap_or(&0) as f32
/ 10000f32) as i32
+ properties
.get(&EPropertyType::SpRecoverDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::ElementMystery.into(),
properties
.get(&EPropertyType::ElementMysteryBase.into())
.unwrap()
+ properties
.get(&EPropertyType::ElementMysteryDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::ElementAbnormalPower.into(),
properties
.get(&EPropertyType::ElementAbnormalPowerBase.into())
.unwrap()
+ (*properties
.get(&EPropertyType::ElementAbnormalPowerBase.into())
.unwrap() as f32
* *properties
.get(&EPropertyType::ElementAbnormalPowerRatio.into())
.unwrap_or(&0) as f32
/ 10000f32) as i32
+ properties
.get(&EPropertyType::ElementAbnormalPowerDelta.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioPhysics.into(),
properties
.get(&EPropertyType::AddedDamageRatioPhysics1.into())
.unwrap_or(&0)
+ properties
.get(&EPropertyType::AddedDamageRatioPhysics3.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioFire.into(),
properties
.get(&EPropertyType::AddedDamageRatioFire1.into())
.unwrap_or(&0)
+ properties
.get(&EPropertyType::AddedDamageRatioFire3.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioIce.into(),
properties
.get(&EPropertyType::AddedDamageRatioIce1.into())
.unwrap_or(&0)
+ properties
.get(&EPropertyType::AddedDamageRatioIce3.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioElec.into(),
properties
.get(&EPropertyType::AddedDamageRatioElec1.into())
.unwrap_or(&0)
+ properties
.get(&EPropertyType::AddedDamageRatioElec3.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioEther.into(),
properties
.get(&EPropertyType::AddedDamageRatioEther1.into())
.unwrap_or(&0)
+ properties
.get(&EPropertyType::AddedDamageRatioEther3.into())
.unwrap_or(&0),
);
}
fn add_ben_core_passive(
avatar_id: u32,
player_avatar: &Avatar,
properties: &mut HashMap<u32, i32>,
) {
if avatar_id != BEN_AVATAR_ID {
return;
}
let core_level = player_avatar
.skill_type_level
.iter()
.find(|sl| sl.skill_type == EAvatarSkillType::CoreSkill as u32)
.unwrap()
.level as usize;
let def_atk_bonus = match core_level {
1..=7 => {
*properties.get(&EPropertyType::Def.into()).unwrap_or(&0)
* BEN_CORE_PASSIVE_PERCENTAGE[core_level - 1]
/ 100
}
_ => 0,
};
properties.insert(
EPropertyType::Atk.into(),
*properties.get(&EPropertyType::Atk.into()).unwrap_or(&0) + def_atk_bonus,
);
}
fn remove_custom_properties(properties: &mut HashMap<u32, i32>) {
properties.remove(&EPropertyType::HpMaxGrowth.into());
properties.remove(&EPropertyType::AtkGrowth.into());
properties.remove(&EPropertyType::DefGrowth.into());
properties.remove(&EPropertyType::HpMaxAdvance.into());
properties.remove(&EPropertyType::AtkAdvance.into());
properties.remove(&EPropertyType::DefAdvance.into());
}
fn set_battle_properties(properties: &mut HashMap<u32, i32>) {
properties.insert(
EPropertyType::Hp.into(),
*properties.get(&EPropertyType::HpMax.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::HpMaxBattle.into(),
*properties.get(&EPropertyType::HpMax.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::AtkBattle.into(),
*properties.get(&EPropertyType::Atk.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::BreakStunBattle.into(),
*properties
.get(&EPropertyType::BreakStun.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::DefBattle.into(),
*properties.get(&EPropertyType::Def.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::CritBattle.into(),
*properties.get(&EPropertyType::Crit.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::CritDmgBattle.into(),
*properties.get(&EPropertyType::CritDmg.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::PenRatioBattle.into(),
*properties.get(&EPropertyType::Pen.into()).unwrap_or(&0),
);
properties.insert(
EPropertyType::PenDeltaBattle.into(),
*properties
.get(&EPropertyType::PenValue.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::SpRecoverBattle.into(),
*properties
.get(&EPropertyType::SpRecover.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::ElementMysteryBattle.into(),
*properties
.get(&EPropertyType::ElementMystery.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::ElementAbnormalPowerBattle.into(),
*properties
.get(&EPropertyType::ElementAbnormalPower.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioPhysicsBattle.into(),
*properties
.get(&EPropertyType::AddedDamageRatioPhysics.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioFireBattle.into(),
*properties
.get(&EPropertyType::AddedDamageRatioFire.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioIceBattle.into(),
*properties
.get(&EPropertyType::AddedDamageRatioIce.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioElecBattle.into(),
*properties
.get(&EPropertyType::AddedDamageRatioElec.into())
.unwrap_or(&0),
);
properties.insert(
EPropertyType::AddedDamageRatioEtherBattle.into(),
*properties
.get(&EPropertyType::AddedDamageRatioEther.into())
.unwrap_or(&0),
);
}

View file

@ -3,19 +3,19 @@ use trigger_logic::scene::ELocalPlayType;
use super::ScenePerform;
pub struct FightScene {
pub event_id: u32,
pub scene_id: u32,
pub play_type: ELocalPlayType,
pub perform: ScenePerform,
}
impl FightScene {
pub fn get_protocol_scene_info(&self) -> trigger_protocol::SceneInfo {
pub fn get_protocol_scene_data(&self) -> trigger_protocol::SceneData {
use trigger_protocol::*;
SceneInfo {
SceneData {
scene_type: 3,
local_play_type: self.play_type.into(),
event_id: self.event_id, // or maybe it's actually scene_id ?
scene_id: self.scene_id,
fight_scene_info: Some(FightSceneInfo {
level_perform_info: Some(LevelPerformInfo {
time: self.perform.time.clone(),

View file

@ -15,17 +15,17 @@ pub enum Scene {
}
impl Scene {
pub fn get_protocol_scene_info(&self) -> trigger_protocol::SceneInfo {
pub fn get_protocol_scene_data(&self) -> trigger_protocol::SceneData {
match self {
Self::Fight(scene) => scene.get_protocol_scene_info(),
Self::Rally(scene) => scene.get_protocol_scene_info(),
Self::Fight(scene) => scene.get_protocol_scene_data(),
Self::Rally(scene) => scene.get_protocol_scene_data(),
}
}
pub fn get_event_id(&self) -> u32 {
pub fn get_scene_id(&self) -> u32 {
match self {
Self::Fight(scene) => scene.event_id,
Self::Rally(scene) => scene.event_id,
Self::Fight(scene) => scene.scene_id,
Self::Rally(scene) => scene.scene_id,
}
}

View file

@ -5,18 +5,18 @@ use trigger_logic::scene::ELocalPlayType;
use super::ScenePerform;
pub struct RallyScene {
pub event_id: u32,
pub scene_id: u32,
pub perform: ScenePerform,
}
impl RallyScene {
pub fn get_protocol_scene_info(&self) -> trigger_protocol::SceneInfo {
pub fn get_protocol_scene_data(&self) -> trigger_protocol::SceneData {
use trigger_protocol::*;
SceneInfo {
SceneData {
scene_type: 7,
local_play_type: ELocalPlayType::RallyLongFight.into(),
event_id: self.event_id, // or maybe it's actually scene_id ?
scene_id: self.scene_id,
rally_scene_info: Some(RallySceneInfo {
level_perform_info: Some(LevelPerformInfo {
time: self.perform.time.clone(),

View file

@ -10,7 +10,7 @@ use trigger_sv::{
net::ServerType,
};
use crate::{logic::GameState, session::BattleSession, AppState};
use crate::{AppState, logic::GameState, session::BattleSession};
pub async fn handle_message(state: &'static AppState, packet: trigger_sv::message::NetworkPacket) {
match packet.opcode {
@ -67,8 +67,8 @@ async fn on_change_game_state(
);
let enter_scene_notify = EnterSceneScNotify {
scene_info: Some(game_state.scene.get_protocol_scene_info()),
dungeon_info: Some(game_state.dungeon.get_protocol_dungeon_info()),
scene: Some(game_state.scene.get_protocol_scene_data()),
dungeon: Some(game_state.dungeon.get_protocol_dungeon_info()),
};
session.game_state = Some(game_state);

View file

@ -1,5 +1,5 @@
use trigger_encoding::Decodeable;
use trigger_protocol::{util::ProtocolUnit, ClientCmdID, EndBattleCsReq};
use trigger_protocol::{ClientCmdID, EndBattleCsReq, util::ProtocolUnit};
use trigger_sv::message::GameStateCallback;
use super::BattleSession;

View file

@ -9,6 +9,7 @@ axum.workspace = true
serde.workspace = true
serde_json.workspace = true
toml.workspace = true
base64.workspace = true
tracing.workspace = true

View file

@ -1,7 +1,7 @@
use std::net::SocketAddr;
use std::{collections::HashMap, net::SocketAddr};
use serde::Deserialize;
use trigger_sv::config::TomlConfig;
use trigger_sv::config::{ConfigurationLoadError, TomlConfig};
#[derive(Deserialize)]
pub struct NetworkSetting {
@ -37,6 +37,29 @@ pub struct DispatchConfig {
pub bound_server: BoundRegionSetting,
}
#[derive(Deserialize)]
pub struct ResVersionConfig {
pub design_data_url: String,
pub design_data_revision: String,
pub design_data_files: String,
pub game_res_url: String,
pub game_res_branch: String,
pub game_audio_revision: String,
pub game_res_revision: String,
pub game_res_files: String,
pub silence_url: String,
pub silence_revision: String,
pub silence_files: String,
}
impl ResVersionConfig {
pub fn load_version_map_from_file(
path: &str,
) -> Result<HashMap<String, Self>, ConfigurationLoadError> {
Ok(toml::from_str(&std::fs::read_to_string(path)?)?)
}
}
impl TomlConfig for DispatchConfig {
const DEFAULT_TOML: &str = include_str!("../dispatch.default.toml");
}

View file

@ -1,10 +1,11 @@
use std::{
collections::HashMap,
process::ExitCode,
sync::{LazyLock, OnceLock},
};
use axum::{routing::get, Router};
use config::DispatchConfig;
use axum::{Router, routing::get};
use config::{DispatchConfig, ResVersionConfig};
use tokio::net::TcpListener;
use tracing::error;
use trigger_sv::{
@ -19,11 +20,12 @@ mod query_dispatch;
mod query_gateway;
const CONFIG_FILE: &str = "dispatch.toml";
const RES_CONFIG_FILE: &str = "res_versions.toml";
#[derive(Clone)]
struct AppState {
pub config: &'static DispatchConfig,
pub environment: &'static ServerEnvironmentConfiguration,
pub res_versions: HashMap<String, ResVersionConfig>,
}
#[tokio::main]
@ -41,9 +43,16 @@ async fn main() -> ExitCode {
print_banner();
logging::init_tracing(tracing::Level::DEBUG);
let res_versions = ResVersionConfig::load_version_map_from_file(RES_CONFIG_FILE)
.unwrap_or_else(|err| {
error!("failed to load {RES_CONFIG_FILE}: {err}");
die();
});
let state = APP_STATE.get_or_init(|| AppState {
config: &CONFIG,
environment: &ENVIRONMENT,
res_versions,
});
let app = Router::new()
@ -52,11 +61,10 @@ async fn main() -> ExitCode {
.route(query_gateway::ROUTE_ENDPOINT, get(query_gateway::process))
.with_state(state);
let Ok(listener) = TcpListener::bind(CONFIG.network.http_addr).await.inspect_err(|err| {
let listener = TcpListener::bind(CONFIG.network.http_addr).await.unwrap_or_else(|err| {
error!("TcpListener::bind failed. Is another instance of the server already running? Error: {err}");
}) else {
die();
};
});
axum::serve(listener, app).await.unwrap_or_else(|err| {
error!("axum::serve failed: {err}");

View file

@ -1,8 +1,8 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use crate::{
data::{QueryDispatchRsp, ServerListInfo},
AppState,
data::{QueryDispatchRsp, ServerListInfo},
};
pub const ROUTE_ENDPOINT: &str = "/query_dispatch";

View file

@ -1,20 +1,20 @@
use axum::{
Json,
extract::{Query, State},
response::IntoResponse,
Json,
};
use base64::{display::Base64Display, engine::general_purpose::STANDARD, Engine};
use base64::{Engine, display::Base64Display, engine::general_purpose::STANDARD};
use serde::{Deserialize, Serialize, Serializer};
use tracing::debug;
use trigger_cryptography::rsa;
use trigger_sv::config::RsaSetting;
use crate::{
AppState,
data::{
CdnConfExt, CdnDesignData, CdnGameRes, CdnSilenceData, RegionExtension, RegionSwitchFunc,
ServerDispatchData, ServerGateway,
},
AppState,
};
pub const ROUTE_ENDPOINT: &str = "/query_gateway";
@ -30,13 +30,15 @@ pub enum QueryGatewayError {
InvalidRsaVer(u32),
#[error("invalid dispatch seed, expected: {0}, got: {1}")]
InvalidDispatchSeed(&'static str, String),
#[error("ResVersionConfig for {0} is not defined")]
MissingResVersionConfig(String),
}
impl QueryGatewayError {
pub fn retcode(&self) -> i32 {
match self {
Self::InvalidRsaVer(_) => 74,
Self::InvalidDispatchSeed(_, _) => 75,
Self::InvalidDispatchSeed(_, _) | Self::MissingResVersionConfig(_) => 75,
}
}
@ -71,6 +73,7 @@ impl IntoResponse for Response {
#[derive(Deserialize)]
pub struct QueryGatewayParam {
pub version: String,
pub rsa_ver: u32,
pub seed: String,
}
@ -118,6 +121,13 @@ fn internal_process(
QueryGatewayError::InvalidDispatchSeed(&state.config.bound_server.seed, param.seed),
))?;
let res_version = state.res_versions.get(&param.version).ok_or_else(|| {
(
rsa,
QueryGatewayError::MissingResVersionConfig(param.version),
)
})?;
let server = &state.config.bound_server;
Ok(Response {
@ -127,7 +137,10 @@ fn internal_process(
msg: String::with_capacity(0),
region_name: Borrowed(&server.name),
title: Borrowed(&server.title),
client_secret_key: Owned(base64::engine::general_purpose::STANDARD.encode(&state.environment.security.static_key.seed_buf)),
client_secret_key: Owned(
base64::engine::general_purpose::STANDARD
.encode(&state.environment.security.static_key.seed_buf),
),
cdn_check_url: String::with_capacity(0),
gateway: Some(ServerGateway {
ip: Borrowed(&server.addr),
@ -137,23 +150,22 @@ fn internal_process(
force_update_url: String::new(),
stop_jump_url: String::new(),
cdn_conf_ext: Some(CdnConfExt {
// TODO: unhardcode this
design_data: CdnDesignData {
base_url: Borrowed("https://autopatchos.zenlesszonezero.com/design_data/1.6_live/output_6898738_6ffe812558/client/"),
data_revision: Borrowed("6898738"),
md5_files: Borrowed(r#"[{"fileName": "data_version", "fileSize": 2065, "fileMD5": "16970197844668905690"}]"#),
base_url: Borrowed(&res_version.design_data_url),
data_revision: Borrowed(&res_version.design_data_revision),
md5_files: Borrowed(&res_version.design_data_files),
},
game_res: CdnGameRes {
audio_revision: Borrowed("6898738"),
base_url: Borrowed("https://autopatchos.zenlesszonezero.com/game_res/1.6_live/output_6898738_6ffe812558/client/"),
branch: Borrowed("beta_live"),
md5_files: Borrowed(r#"[{"fileName": "res_version", "fileSize": 1167660, "fileMD5": "8072678507435758384"}, {"fileName": "audio_version", "fileSize": 15447, "fileMD5": "5401804085122358755"}, {"fileName": "base_revision", "fileSize": 4, "fileMD5": "4524394692449115962"}]"#),
res_revision: Borrowed("6898738"),
audio_revision: Borrowed(&res_version.game_audio_revision),
base_url: Borrowed(&res_version.game_res_url),
branch: Borrowed(&res_version.game_res_branch),
md5_files: Borrowed(&res_version.game_res_files),
res_revision: Borrowed(&res_version.game_res_revision),
},
silence_data: CdnSilenceData {
base_url: Borrowed("https://autopatchos.zenlesszonezero.com/design_data/1.6_live/output_6898738_6ffe812558/client_silence/"),
md5_files: Borrowed(r#"[{"fileName": "silence_version", "fileSize": 130, "fileMD5": "2077712550601860122"}]"#),
silence_revision: Borrowed("6898738"),
base_url: Borrowed(&res_version.silence_url),
md5_files: Borrowed(&res_version.silence_files),
silence_revision: Borrowed(&res_version.silence_revision),
},
pre_download: None,
}),
@ -174,7 +186,7 @@ fn internal_process(
url_check_nap: String::new(),
url_check_sdk: String::new(),
}),
}
},
})
}

View file

@ -1,10 +1,3 @@
pub const MALE_AVATAR_ID: u32 = 2011;
pub const FEMALE_AVATAR_ID: u32 = 2021;
pub fn is_player_avatar(id: u32) -> bool {
id == MALE_AVATAR_ID || id == FEMALE_AVATAR_ID
}
pub fn is_valid_talent_switch(v: &[bool]) -> bool {
v.len() == 6
&& v[0..3]

View file

@ -1,11 +1,11 @@
use tracing::{debug, warn};
use trigger_logic::quest::EQuestType;
use trigger_protocol::{util::ProtocolUnit, AvatarSync, CafeSync, ItemSync, PlayerSyncScNotify};
use trigger_protocol::{AvatarSync, CafeSync, ItemSync, PlayerSyncScNotify, util::ProtocolUnit};
use trigger_sv::gm_command::GMCommand;
use crate::AppState;
use super::{player::AvatarPropertyChanges, NapPlayer};
use super::{NapPlayer, player::AvatarPropertyChanges};
pub struct CommandContext<'player> {
pub player: &'player mut NapPlayer,
@ -72,9 +72,36 @@ pub async fn execute_command(context: &mut CommandContext<'_>, command: &GMComma
GMCommand::UnlockAllHollow => gm_unlock_all_hollow(context).await,
GMCommand::UnlockAllHollowBuff => gm_unlock_all_hollow_buff(context).await,
GMCommand::UnlockAllCafeItem => gm_unlock_all_cafe_item(context).await,
GMCommand::UnlockAllAvatarSkin => gm_unlock_all_avatar_skin(context).await,
}
}
async fn gm_unlock_all_avatar_skin(context: &mut CommandContext<'_>) {
context
.player
.item_model
.add_or_use_materials(
&context
.state
.filecfg
.avatar_skin_base_template_tb()
.data()
.unwrap()
.iter()
.map(|tmpl| (tmpl.id() as u32, 1).into())
.collect::<Vec<_>>(),
)
.await;
context.add_notify(PlayerSyncScNotify {
item_sync: Some(ItemSync {
material_list: context.player.item_model.get_protocol_material_list(),
..Default::default()
}),
..Default::default()
});
}
async fn gm_unlock_all_hollow(context: &mut CommandContext<'_>) {
context
.player

View file

@ -4,6 +4,7 @@ pub mod dungeon_util;
pub mod equip_util;
pub mod gm_util;
mod player;
pub mod scene;
pub mod scene_util;
pub use player::NapPlayer;

View file

@ -101,7 +101,18 @@ impl ItemModel {
.transaction::<_, (), DbErr>(|txn| {
Box::pin(async move {
for model in updated_models {
model.update(txn).await?;
material::Entity::insert(model)
.on_conflict(
OnConflict::new()
.exprs([
Expr::col(material::Column::OwnerPlayerUid),
Expr::col(material::Column::Id),
])
.update_column(material::Column::Num)
.to_owned(),
)
.exec(txn)
.await?;
}
Ok(())
@ -185,3 +196,9 @@ impl ItemModel {
.collect()
}
}
impl From<(u32, i32)> for MaterialDelta {
fn from((id, num): (u32, i32)) -> Self {
Self { id, num }
}
}

View file

@ -6,10 +6,10 @@ use quest::QuestModel;
use ramen::RamenModel;
use role::RoleModel;
use scene::SceneModel;
use trigger_database::{entity::*, prelude::*, DatabaseConnection};
use trigger_database::{DatabaseConnection, entity::*, prelude::*};
use trigger_fileconfig::NapFileCfg;
use trigger_logic::scene::ESceneType;
use trigger_protocol::PlayerBasicInfo;
use trigger_logic::{scene::ESceneType, template_ext::TemplateExt};
use trigger_protocol::PlayerInfo;
use trigger_sv::message::GameStateData;
use yorozuya::YorozuyaModel;
@ -62,11 +62,8 @@ impl NapPlayer {
player_uid,
};
let Some((player_basic_info, is_new_player)) =
player_util::load_player_basic_info(database, player_uid, create_if_not_exists).await
else {
return None;
};
let (player_basic_info, is_new_player) =
player_util::load_player_basic_info(database, player_uid, create_if_not_exists).await?;
let role_model = RoleModel::init(context.clone()).await;
let item_model = ItemModel::init(context.clone()).await;
@ -95,6 +92,28 @@ impl NapPlayer {
})
}
pub fn beginner_procedure_id(&self) -> Option<i32> {
(self.player_basic_info.beginner_procedure_id != -1)
.then_some(self.player_basic_info.beginner_procedure_id)
}
pub async fn advance_beginner_procedure(&mut self, id: i32) {
let active_model = player_basic_info::ActiveModel {
beginner_procedure_id: Set(self
.context
.filecfg
.is_last_procedure(id)
.then_some(-1)
.unwrap_or(id)),
..self.player_basic_info.clone().into()
};
self.player_basic_info = active_model
.update(self.context.database)
.await
.expect("player_basic_info::update failed");
}
pub fn build_state_reentrant_data(&self, scene: &scene_info::Model) -> Option<GameStateData> {
match ESceneType::try_from(scene.scene_type).unwrap() {
ESceneType::Hall => Some(GameStateData::Hall {
@ -106,6 +125,31 @@ impl NapPlayer {
}
}
pub async fn select_role(&mut self, avatar_id: u32) {
let mut active_model: player_basic_info::ActiveModel =
self.player_basic_info.clone().into();
active_model.set(
player_basic_info::Column::AvatarId,
(avatar_id as i32).into(),
);
active_model.set(
player_basic_info::Column::PlayerAvatarId,
(avatar_id as i32).into(),
);
active_model.set(
player_basic_info::Column::ControlAvatarId,
(avatar_id as i32).into(),
);
self.player_basic_info = active_model
.update(self.context.database)
.await
.expect("player_basic_info::update failed");
}
pub async fn set_control_avatars(&mut self, player_avatar_id: u32, control_avatar_id: u32) {
let mut active_model: player_basic_info::ActiveModel =
self.player_basic_info.clone().into();
@ -126,15 +170,17 @@ impl NapPlayer {
.expect("player_basic_info::update failed");
}
pub fn get_protocol_player_basic_info(&self) -> PlayerBasicInfo {
PlayerBasicInfo {
pub fn get_protocol_player_info(&self) -> PlayerInfo {
PlayerInfo {
nick_name: self.player_basic_info.nick_name.clone(),
level: self.player_basic_info.level as u32,
exp: self.player_basic_info.exp as u32,
avatar_id: self.player_basic_info.avatar_id as u32,
player_avatar_id: self.player_basic_info.player_avatar_id as u32,
control_avatar_id: self.player_basic_info.control_avatar_id as u32,
last_enter_world_timestamp: self.scene_model.last_enter_world_timestamp(),
role_create_time: 0,
name_change_times: 1,
portrait_id: 0,
}
}

View file

@ -1,6 +1,6 @@
use trigger_database::DatabaseConnection;
use trigger_database::entity::*;
use trigger_database::prelude::*;
use trigger_database::DatabaseConnection;
pub async fn load_player_basic_info(
db: &DatabaseConnection,
@ -32,9 +32,10 @@ fn create_default_player_basic_info(player_uid: i32) -> player_basic_info::Activ
nick_name: String::from("ReversedRooms"),
level: 60,
exp: 0,
avatar_id: 2021,
player_avatar_id: 2021,
control_avatar_id: 1361,
avatar_id: 0,
player_avatar_id: 0,
control_avatar_id: 0,
beginner_procedure_id: 0,
}
.into()
}

View file

@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
use trigger_database::entity::avatar;
use trigger_database::prelude::*;
use trigger_logic::skill::EAvatarSkillType;
use trigger_logic::{skill::EAvatarSkillType, template_ext::TemplateExt};
use trigger_protocol::{Avatar, AvatarSkillLevel, DressedEquip};
use trigger_sv::time_util;
@ -325,6 +325,36 @@ impl RoleModel {
}
}
pub async fn dress_avatar_skin(&mut self, avatar_id: i32, avatar_skin_id: i32) -> bool {
if avatar_skin_id != 0
&& !self
.context
.filecfg
.skin_targets_avatar(avatar_skin_id, avatar_id)
{
return false;
}
if let Some(avatar) = self.avatar_map.remove(&(avatar_id as u32)) {
let model = avatar::ActiveModel {
avatar_skin_id: Set(avatar_skin_id),
..avatar.into()
};
self.avatar_map.insert(
avatar_id as u32,
model
.update(self.context.database)
.await
.expect("avatar::update failed"),
);
true
} else {
false
}
}
pub fn is_avatar_unlocked(&self, avatar_id: u32) -> bool {
self.avatar_map.contains_key(&avatar_id)
}

View file

@ -138,10 +138,6 @@ impl SceneModel {
.expect("scene_basic_info::find_by_id failed")
}
pub fn last_enter_world_timestamp(&self) -> i64 {
self.player_world_info.last_enter_world_timestamp
}
async fn load_or_create_player_world_info(context: &NapContext) -> player_world_info::Model {
let player_uid = context.player_uid as i32;

View file

@ -0,0 +1,22 @@
use trigger_logic::scene::ESceneType;
#[derive(Debug)]
pub enum ServerlessStateData {
FreshScene { procedure_id: i32 },
}
impl ServerlessStateData {
pub fn protocol_scene_data(&self) -> trigger_protocol::SceneData {
use trigger_protocol::*;
match self {
Self::FreshScene { procedure_id } => SceneData {
scene_type: ESceneType::Fresh.into(),
fresh_scene_info: Some(FreshSceneInfo {
last_procedure_id: *procedure_id as u32,
}),
..Default::default()
},
}
}
}

View file

@ -12,7 +12,7 @@ use tracing::{error, info};
use trigger_database::DatabaseConnection;
use trigger_fileconfig::NapFileCfg;
use trigger_sv::{
config::{load_json_config, ServerEnvironmentConfiguration, TomlConfig},
config::{ServerEnvironmentConfiguration, TomlConfig, load_json_config},
die, logging,
net::{ServerNetworkManager, ServerType},
print_banner,

View file

@ -1,9 +1,9 @@
use std::sync::Arc;
use crate::{
logic::{gm_util, NapPlayer},
session::GameSession,
AppState,
logic::{NapPlayer, gm_util},
session::GameSession,
};
use tokio::sync::Mutex;
use tracing::{debug, info, warn};

View file

@ -32,7 +32,8 @@ mod avatar_module {
.weapon_dress(
request.avatar_id,
request.weapon_uid as i32,
equip_model.is_signature_weapon(request.weapon_uid as i32, request.avatar_id as i32)
equip_model
.is_signature_weapon(request.weapon_uid as i32, request.avatar_id as i32),
)
.await
{
@ -194,4 +195,53 @@ mod avatar_module {
ToggleWeaponShowScRsp { retcode: 1 }
}
pub async fn on_dress_avatar_skin(
context: &mut MessageContext<'_, '_>,
request: DressAvatarSkinCsReq,
) -> DressAvatarSkinScRsp {
let item_model = &context.player.item_model;
if item_model.has_enough_material(request.avatar_skin_id, 1) {
let role_model = &mut context.player.role_model;
if role_model
.dress_avatar_skin(request.avatar_id as i32, request.avatar_skin_id as i32)
.await
{
let avatar_list = role_model.get_protocol_avatar_list(&[request.avatar_id]);
context.add_notify(PlayerSyncScNotify {
avatar_sync: Some(AvatarSync { avatar_list }),
..Default::default()
});
return DressAvatarSkinScRsp { retcode: 0 };
}
}
DressAvatarSkinScRsp { retcode: 1 }
}
pub async fn on_undress_avatar_skin(
context: &mut MessageContext<'_, '_>,
request: UndressAvatarSkinCsReq,
) -> UndressAvatarSkinScRsp {
// Why separate packet, retards?
let role_model = &mut context.player.role_model;
if role_model
.dress_avatar_skin(request.avatar_id as i32, 0)
.await
{
let avatar_list = role_model.get_protocol_avatar_list(&[request.avatar_id]);
context.add_notify(PlayerSyncScNotify {
avatar_sync: Some(AvatarSync { avatar_list }),
..Default::default()
});
return UndressAvatarSkinScRsp { retcode: 0 };
}
UndressAvatarSkinScRsp { retcode: 1 }
}
}

View file

@ -12,11 +12,4 @@ mod battle_event_module {
event_info: Some(BattleEventInfo::default()),
}
}
pub async fn on_report_battle_team(
_context: &mut MessageContext<'_, '_>,
_request: ReportBattleTeamCsReq,
) -> ReportBattleTeamScRsp {
ReportBattleTeamScRsp { retcode: 0 }
}
}

View file

@ -1,35 +0,0 @@
use super::MessageContext;
use trigger_codegen::handlers;
#[handlers]
mod collections_module {
pub async fn on_get_collect_map(
_context: &mut MessageContext<'_, '_>,
_request: GetCollectMapCsReq,
) -> GetCollectMapScRsp {
GetCollectMapScRsp {
retcode: 0,
collect_map: Some(CollectMap::default()),
}
}
pub async fn on_workbench_get_data(
_context: &mut MessageContext<'_, '_>,
_request: WorkbenchGetDataCsReq,
) -> WorkbenchGetDataScRsp {
WorkbenchGetDataScRsp {
retcode: 0,
workbench_data: Some(WorkbenchData::default()),
}
}
pub async fn on_get_abyss_reward_data(
_context: &mut MessageContext<'_, '_>,
_request: GetAbyssRewardDataCsReq,
) -> GetAbyssRewardDataScRsp {
GetAbyssRewardDataScRsp {
retcode: 0,
abyss_reward_data: Some(AbyssRewardData::default()),
}
}
}

View file

@ -1,15 +0,0 @@
use super::MessageContext;
use trigger_codegen::handlers;
#[handlers]
mod fairy_module {
pub async fn on_get_fairy_data(
_context: &mut MessageContext<'_, '_>,
_request: GetFairyDataCsReq,
) -> GetFairyDataScRsp {
GetFairyDataScRsp {
retcode: 0,
data: Some(FairyData::default()),
}
}
}

View file

@ -1,5 +1,5 @@
use trigger_encoding::Encodeable;
use trigger_protocol::{util::ProtocolUnit, ClientCmdID};
use trigger_protocol::{ClientCmdID, util::ProtocolUnit};
use super::GameSession;
use crate::AppState;
@ -13,7 +13,7 @@ modules! {
quest,
abyss,
bangboo,
client_systems,
system,
gacha,
mail,
ramen,
@ -22,10 +22,10 @@ modules! {
reward_buff,
arcade,
daily_challenge,
fairy,
tips,
activity,
land_revive,
collections,
workbench,
perform,
battle_event,
vhs_store,
@ -39,8 +39,9 @@ modules! {
camp_idle,
miniscape_entrust,
fishing_contest,
qa_game,
ridus_got_boo,
qa_game
training
}
client_message_forwarding! {

View file

@ -4,17 +4,16 @@ use trigger_codegen::handlers;
#[handlers]
mod player_module {
use tracing::debug;
use trigger_logic::template_ext::TemplateExt;
use trigger_sv::{net::ServerType, time_util};
use crate::logic::avatar_util;
pub async fn on_get_player_basic_info(
pub async fn on_get_player_info(
context: &mut MessageContext<'_, '_>,
_request: GetPlayerBasicInfoCsReq,
) -> GetPlayerBasicInfoScRsp {
GetPlayerBasicInfoScRsp {
_request: GetPlayerInfoCsReq,
) -> GetPlayerInfoScRsp {
GetPlayerInfoScRsp {
retcode: 0,
basic_info: Some(context.player.get_protocol_player_basic_info()),
player_info: Some(context.player.get_protocol_player_info()),
}
}
@ -39,6 +38,34 @@ mod player_module {
}
}
pub async fn on_select_role(
context: &mut MessageContext<'_, '_>,
request: SelectRoleCsReq,
) -> SelectRoleScRsp {
if let Some(procedure_id) = context.player.beginner_procedure_id() {
if context
.state
.filecfg
.procedure_allows_select_role(procedure_id + 1)
&& context
.state
.filecfg
.is_player_avatar(request.avatar_id as i32)
{
context.player.select_role(request.avatar_id).await;
context.add_notify(PlayerSyncScNotify {
player_info: Some(context.player.get_protocol_player_info()),
..Default::default()
});
return SelectRoleScRsp { retcode: 0 };
}
}
SelectRoleScRsp { retcode: 1 }
}
pub async fn on_get_authkey(
context: &mut MessageContext<'_, '_>,
request: GetAuthkeyCsReq,
@ -69,8 +96,14 @@ mod player_module {
context: &mut MessageContext<'_, '_>,
request: SwitchRoleCsReq,
) -> SwitchRoleScRsp {
if avatar_util::is_player_avatar(request.player_avatar_id)
&& (avatar_util::is_player_avatar(request.control_avatar_id)
if context
.state
.filecfg
.is_player_avatar(request.player_avatar_id as i32)
&& (context
.state
.filecfg
.is_player_avatar(request.control_avatar_id as i32)
|| context
.player
.role_model
@ -89,7 +122,7 @@ mod player_module {
.await;
context.add_notify(PlayerSyncScNotify {
basic_info: Some(context.player.get_protocol_player_basic_info()),
player_info: Some(context.player.get_protocol_player_info()),
..Default::default()
});

View file

@ -75,35 +75,6 @@ mod quest_module {
}
}
pub async fn on_begin_training_course_battle(
context: &mut MessageContext<'_, '_>,
request: BeginTrainingCourseBattleCsReq,
) {
let scene_model = &mut context.player.scene_model;
let scene_info = scene_model.create_scene_info(ESceneType::Fight).await;
let dungeon_equip =
dungeon_util::build_dungeon_equip_info(&context.player, &request.avatar_id_list);
context
.session
.change_game_state(
context.request_id,
BeginTrainingCourseBattleScRsp { retcode: 0 },
GameStateData::Fight {
play_type: ELocalPlayType::TrainingRoom.into(),
quest_id: request.quest_id,
buddy_id: request.buddy_id,
avatar_id_list: request.avatar_id_list,
dungeon_equip,
},
&scene_info,
context.player,
true,
)
.await;
}
pub async fn on_begin_archive_battle_quest(
context: &mut MessageContext<'_, '_>,
request: BeginArchiveBattleQuestCsReq,

View file

@ -4,11 +4,29 @@ use trigger_codegen::handlers;
#[handlers]
mod scene_module {
use tracing::debug;
use trigger_logic::scene::ESceneType;
use trigger_logic::scene::{ELocalPlayType, ESceneType};
use trigger_sv::{
message::{AvailableServerProtocolMessage, GameStateData},
net::ServerType,
};
use crate::logic::scene_util;
use crate::logic::{dungeon_util, scene::ServerlessStateData, scene_util};
pub async fn on_enter_world(context: &mut MessageContext<'_, '_>, _request: EnterWorldCsReq) {
if let Some(procedure_id) = context.player.beginner_procedure_id() {
debug!("entering beginner procedure, id: {procedure_id}");
context
.session
.load_serverless_state(
ServerlessStateData::FreshScene { procedure_id },
context.request_id,
EnterWorldScRsp::default(),
)
.await;
return;
}
let scene_model = &mut context.player.scene_model;
let scene_to_enter = match scene_model.get_current_scene().await {
@ -23,7 +41,6 @@ mod scene_module {
};
let scene_to_enter = if scene_to_enter.is_none() {
// TODO: first scene to be created should be the 'Fresh' scene (beginner procedure)
debug!(
"player with uid {} has no scene to enter, default hall scene will be created",
context.session.player_uid
@ -88,6 +105,35 @@ mod scene_module {
}
}
pub async fn on_enter_training_room(
context: &mut MessageContext<'_, '_>,
request: EnterTrainingRoomCsReq,
) {
let scene_model = &mut context.player.scene_model;
let scene_info = scene_model.create_scene_info(ESceneType::Fight).await;
let dungeon_equip =
dungeon_util::build_dungeon_equip_info(&context.player, &request.avatar_id_list);
context
.session
.change_game_state(
context.request_id,
EnterTrainingRoomScRsp { retcode: 0 },
GameStateData::Fight {
play_type: ELocalPlayType::TrainingRoom.into(),
quest_id: request.quest_id,
buddy_id: request.buddy_id,
avatar_id_list: request.avatar_id_list,
dungeon_equip,
},
&scene_info,
context.player,
true,
)
.await;
}
pub async fn on_leave_cur_scene(
context: &mut MessageContext<'_, '_>,
_request: LeaveCurSceneCsReq,
@ -119,6 +165,104 @@ mod scene_module {
.await;
}
pub async fn on_advance_beginner_procedure(
context: &mut MessageContext<'_, '_>,
request: AdvanceBeginnerProcedureCsReq,
) {
let rsp = if let Some(procedure_id) = context.player.beginner_procedure_id() {
if request.procedure_id == procedure_id + 1 {
context
.player
.advance_beginner_procedure(request.procedure_id)
.await;
let rsp = AdvanceBeginnerProcedureScRsp {
retcode: 0,
next_procedure_id: request.procedure_id,
};
if context.player.beginner_procedure_id().is_none() {
// Beginner procedure finished, enter the hall scene now
let scene_model = &mut context.player.scene_model;
let scene = scene_model.create_scene_info(ESceneType::Hall).await;
scene_model.set_default_scene(&scene).await;
context
.session
.change_game_state(
context.request_id,
rsp,
context.player.build_state_reentrant_data(&scene).unwrap(),
&scene,
context.player,
false,
)
.await;
None
} else {
Some(rsp)
}
} else {
debug!(
"invalid procedure transition (from: {}, to: {})",
procedure_id, request.procedure_id
);
Some(AdvanceBeginnerProcedureScRsp {
retcode: 1,
..Default::default()
})
}
} else {
Some(AdvanceBeginnerProcedureScRsp {
retcode: 1,
..Default::default()
})
};
if let Some(rsp) = rsp {
context
.session
.network_mgr
.send_to(
ServerType::GateServer,
0,
AvailableServerProtocolMessage {
session_id: context.session.id,
ack_request_id: context.request_id,
notifies: Vec::new(),
response: Some(rsp.into()),
},
)
.await;
}
}
pub async fn on_beginnerbattle_begin(
_context: &mut MessageContext<'_, '_>,
request: BeginnerbattleBeginCsReq,
) -> BeginnerbattleBeginScRsp {
BeginnerbattleBeginScRsp {
retcode: 0,
battle_uid: request.battle_id as i64,
}
}
pub async fn on_beginnerbattle_rebegin(
_context: &mut MessageContext<'_, '_>,
_request: BeginnerbattleRebeginCsReq,
) -> BeginnerbattleRebeginScRsp {
BeginnerbattleRebeginScRsp { retcode: 0 }
}
pub async fn on_beginnerbattle_end(
_context: &mut MessageContext<'_, '_>,
_request: BeginnerbattleEndCsReq,
) -> BeginnerbattleEndScRsp {
BeginnerbattleEndScRsp { retcode: 0 }
}
pub async fn on_active_hollow_check_point(
_context: &mut MessageContext<'_, '_>,
request: ActiveHollowCheckPointCsReq,

View file

@ -93,24 +93,30 @@ mod client_systems_module {
PlayerOperationScRsp { retcode: 0 }
}
pub async fn on_get_tips_info(
pub async fn on_get_system_settings(
_context: &mut MessageContext<'_, '_>,
_request: GetTipsInfoCsReq,
) -> GetTipsInfoScRsp {
GetTipsInfoScRsp {
request: GetSystemSettingsCsReq,
) -> GetSystemSettingsScRsp {
GetSystemSettingsScRsp {
retcode: 0,
tips_info: Some(TipsInfo::default()),
r#type: request.r#type,
settings: Some(SystemSettings {
systems: Vec::new(),
switch_of_qte: false,
switch_of_story_mode: false,
}),
player_settings_map: HashMap::new(),
}
}
pub async fn on_get_client_systems_data(
pub async fn on_get_unlock_data(
context: &mut MessageContext<'_, '_>,
_request: GetClientSystemsDataCsReq,
) -> GetClientSystemsDataScRsp {
GetClientSystemsDataScRsp {
_request: GetUnlockDataCsReq,
) -> GetUnlockDataScRsp {
GetUnlockDataScRsp {
retcode: 0,
data: Some(ClientSystemsData {
unlock_data: Some(UnlockData {
data: Some(UnlockData {
unlock: Some(UnlockInfo {
unlocked_list: context
.state
.filecfg
@ -122,7 +128,7 @@ mod client_systems_module {
.collect(),
..Default::default()
}),
post_girl_data: Some(PostGirlData {
post_girl: Some(PostGirlInfo {
post_girl_item_list: context
.state
.filecfg
@ -138,7 +144,7 @@ mod client_systems_module {
selected_post_girl_id_list: vec![3510028],
show_random_selected: false,
}),
music_player_data: Some(MusicPlayerData {
music_player: Some(MusicPlayerInfo {
music_list: context
.state
.filecfg
@ -153,7 +159,7 @@ mod client_systems_module {
})
.collect(),
}),
teleport_data: Some(TeleportData {
teleport: Some(TeleportUnlockInfo {
unlocked_list: context
.state
.filecfg
@ -179,6 +185,18 @@ mod client_systems_module {
}
}
pub async fn on_end_newbie(
_context: &mut MessageContext<'_, '_>,
request: EndNewbieCsReq,
) -> EndNewbieScRsp {
debug!("EndNewbie({})", request.group_id);
EndNewbieScRsp {
retcode: 0,
group_id: 0,
}
}
pub async fn on_get_trashbin_hermit_data(
_context: &mut MessageContext<'_, '_>,
_request: GetTrashbinHermitDataCsReq,

View file

@ -0,0 +1,32 @@
use super::MessageContext;
use trigger_codegen::handlers;
#[handlers]
mod tips_module {
use std::collections::HashMap;
pub async fn on_get_tips_data(
_context: &mut MessageContext<'_, '_>,
_request: GetTipsDataCsReq,
) -> GetTipsDataScRsp {
GetTipsDataScRsp {
retcode: 0,
data: Some(TipsData {
tips: Some(TipsInfo {
tips_list: Vec::new(),
tips_group_list: Vec::new(),
}),
fairy: Some(FairyInfo {
fairy_groups: HashMap::new(),
fairy_record_list: Vec::new(),
}),
popup_window: Some(PopupWindowInfo {
popup_window_list: Vec::new(),
}),
loading_page_tips: Some(LoadingPageTipsInfo {
unlocked_list: Vec::new(),
}),
}),
}
}
}

View file

@ -0,0 +1,19 @@
use super::MessageContext;
use trigger_codegen::handlers;
#[handlers]
mod training_module {
use tracing::info;
pub async fn on_start_training(
_context: &mut MessageContext<'_, '_>,
request: StartTrainingCsReq,
) -> StartTrainingScRsp {
info!("{request:?}");
StartTrainingScRsp {
retcode: 0,
training_uid: 1000000,
}
}
}

View file

@ -0,0 +1,45 @@
use super::MessageContext;
use trigger_codegen::handlers;
#[handlers]
mod workbench_module {
pub async fn on_get_workbench_data(
_context: &mut MessageContext<'_, '_>,
_request: GetWorkbenchDataCsReq,
) -> GetWorkbenchDataScRsp {
GetWorkbenchDataScRsp {
retcode: 0,
workbench_data: Some(WorkbenchData {
workbench_app_list: vec![1, 2, 3, 4, 5],
clue_data: Some(ClueData::default()),
}),
}
}
pub async fn on_get_partner_data(
_context: &mut MessageContext<'_, '_>,
_request: GetPartnerDataCsReq,
) -> GetPartnerDataScRsp {
GetPartnerDataScRsp {
retcode: 0,
partner_data: Some(PartnerData::default()),
}
}
pub async fn on_get_abyss_reward_data(
_context: &mut MessageContext<'_, '_>,
_request: GetAbyssRewardDataCsReq,
) -> GetAbyssRewardDataScRsp {
GetAbyssRewardDataScRsp {
retcode: 0,
abyss_reward_data: Some(AbyssRewardData::default()),
}
}
pub async fn on_unlock_clue_item(
_context: &mut MessageContext<'_, '_>,
_request: UnlockClueItemCsReq,
) -> UnlockClueItemScRsp {
UnlockClueItemScRsp { retcode: 0 }
}
}

View file

@ -15,7 +15,7 @@ use trigger_sv::{
net::{ServerNetworkManager, ServerType},
};
use crate::logic::{scene_util, NapPlayer};
use crate::logic::{NapPlayer, scene::ServerlessStateData, scene_util};
pub mod message;
@ -50,6 +50,31 @@ impl GameSession {
}
}
pub async fn load_serverless_state(
&self,
state_data: ServerlessStateData,
ack_request_id: u32,
response: impl Into<ProtocolUnit>,
) {
let enter_scene_notify = trigger_protocol::EnterSceneScNotify {
scene: Some(state_data.protocol_scene_data()),
dungeon: None,
};
self.network_mgr
.send_to(
ServerType::GateServer,
0,
AvailableServerProtocolMessage {
session_id: self.id,
ack_request_id,
notifies: vec![enter_scene_notify.into()],
response: Some(response.into()),
},
)
.await;
}
pub async fn change_game_state(
&self,
ack_request_id: u32,

View file

@ -12,10 +12,10 @@ use trigger_sv::{
};
use crate::{
AppState,
net::{Connection, NetPacket},
session::SessionState,
util::BinExt,
AppState,
};
pub async fn handle_message(connection: &Connection, state: &'static AppState, packet: NetPacket) {
@ -41,20 +41,33 @@ pub async fn handle_message(connection: &Connection, state: &'static AppState, p
on_keep_alive(
connection,
state,
KeepAliveNotify::decode(&*packet.body).unwrap_or_default()
).await
KeepAliveNotify::decode(&*packet.body).unwrap_or_default(),
)
.await
}
cmd_id if connection.session.is_logged_in() => {
match trigger_protobuf::pb_to_common_protocol_unit(cmd_id, &packet.body) {
Ok(Some(unit)) => state.network_mgr.send_to(ServerType::GameServer, 0, ForwardClientProtocolMessage {
session_id: connection.session.id,
request_id: head.packet_id,
message: unit,
}).await,
Ok(Some(unit)) => {
state
.network_mgr
.send_to(
ServerType::GameServer,
0,
ForwardClientProtocolMessage {
session_id: connection.session.id,
request_id: head.packet_id,
message: unit,
},
)
.await
}
Ok(None) => warn!("ignoring message with unknown cmd_id: {cmd_id}"),
Err(err) => error!(
"failed to decode a message with cmd_id: {} from {} (player_uid: {}), error: {}",
cmd_id, connection.addr(), connection.session.player_uid(), err
cmd_id,
connection.addr(),
connection.session.player_uid(),
err
),
}
}

View file

@ -1,7 +1,7 @@
use tokio::sync::mpsc;
use tracing::warn;
use crate::{net::NetPacket, AppState};
use crate::{AppState, net::NetPacket};
#[derive(Clone)]
pub struct MessageHandler(mpsc::UnboundedSender<(u64, NetPacket)>);

View file

@ -2,8 +2,8 @@ use std::{
io,
net::SocketAddr,
sync::{
atomic::{AtomicU32, Ordering::SeqCst},
Arc, OnceLock,
atomic::{AtomicU32, Ordering::SeqCst},
},
time::Duration,
};

View file

@ -1,6 +1,6 @@
use std::io::{Cursor, Write};
use byteorder::{WriteBytesExt, BE};
use byteorder::{BE, WriteBytesExt};
use trigger_protobuf::PacketHead;
pub struct NetPacket {

View file

@ -3,7 +3,7 @@ use std::{io, net::SocketAddr};
use tokio::net::TcpListener;
use tracing::info;
use crate::{message_handler::MessageHandler, AppState};
use crate::{AppState, message_handler::MessageHandler};
pub async fn serve(
addr: SocketAddr,

View file

@ -1,6 +1,6 @@
use std::sync::{
atomic::{AtomicI64, Ordering::SeqCst},
OnceLock,
atomic::{AtomicI64, Ordering::SeqCst},
};
use atomic_enum::atomic_enum;

View file

@ -107,6 +107,6 @@ use trigger_protocol::{
};
use trigger_sv::message::GameStateCallback;
use crate::logic::{message::RunEventGraphEvent, GameStateListener};
use crate::logic::{GameStateListener, message::RunEventGraphEvent};
use super::scene_unit::{InteractContainer, SceneUnitTag};

View file

@ -1,6 +1,6 @@
use bevy_ecs::{prelude::*, query::QueryData};
use tracing::warn;
use trigger_fileconfig::{main_city_script::MainCityConfig, NapFileCfg};
use trigger_fileconfig::{NapFileCfg, main_city_script::MainCityConfig};
use crate::logic::save::HallSceneSaveData;

View file

@ -3,13 +3,13 @@ use tracing::{debug, warn};
use trigger_protocol::InteractWithUnitScRsp;
use trigger_sv::message::GameStateCallback;
use crate::logic::{message::InteractWithUnitEvent, GameStateListener};
use crate::logic::{GameStateListener, message::InteractWithUnitEvent};
use super::{
NapResources,
event_graph::{ActionChangeInteractCfgEvent, EventGraph, GraphEvent},
hall::MainCitySection,
scene_unit::{InteractContainer, SceneUnitTag},
NapResources,
};
pub fn tick_change_interact(

View file

@ -8,11 +8,11 @@ use scene::PlayerEnterScene;
use trigger_fileconfig::main_city_script::MainCityConfig;
use super::{
GameStateListener,
message::{
EnterSectionEvent, InteractWithUnitEvent, PlayerMoveEvent, RunEventGraphEvent,
SwitchRoleEvent,
},
GameStateListener,
};
pub mod event_graph;

View file

@ -137,12 +137,12 @@ pub fn notify_enter_scene(
}
listener.add(EnterSceneScNotify {
scene_info: Some(SceneInfo {
scene: Some(SceneData {
scene_type: ESceneType::Hall as u32,
hall_scene_info: Some(hall_scene_info),
..Default::default()
}),
dungeon_info: None,
dungeon: None,
});
}
}

View file

@ -1,8 +1,8 @@
use bevy_ecs::prelude::*;
use crate::logic::{
save::{HallSceneSaveData, MainCityPositionSave},
GameStateListener,
save::{HallSceneSaveData, MainCityPositionSave},
};
use super::{

View file

@ -1,6 +1,6 @@
use bevy_ecs::system::Resource;
use trigger_encoding::Encodeable;
use trigger_protocol::{util::ProtocolUnit, ClientCmdID};
use trigger_protocol::{ClientCmdID, util::ProtocolUnit};
use trigger_sv::{
message::{GameStateCallback, GameStateCallbackMessage},
net::{ServerNetworkManager, ServerType},

View file

@ -2,8 +2,8 @@ use bevy_ecs::event::Event;
use trigger_encoding::Decodeable;
use trigger_logic::scene::Transform;
use trigger_protocol::{
util::ProtocolUnit, ClientCmdID, EnterSectionCsReq, InteractWithUnitCsReq, RunEventGraphCsReq,
SavePosInMainCityCsReq, SwitchRoleCsReq,
ClientCmdID, EnterSectionCsReq, InteractWithUnitCsReq, RunEventGraphCsReq,
SavePosInMainCityCsReq, SwitchRoleCsReq, util::ProtocolUnit,
};
use super::ecs::NapEcs;

View file

@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::mpsc, thread};
use ecs::{scene::PlayerEnterScene, NapEcs};
use ecs::{NapEcs, scene::PlayerEnterScene};
use message::ProtocolEventHandler;
use tracing::debug;
use trigger_protocol::util::ProtocolUnit;
@ -11,8 +11,8 @@ mod listener;
mod message;
pub mod save;
pub use ecs::hall::HallInitData;
pub use ecs::NapResources;
pub use ecs::hall::HallInitData;
pub use listener::GameStateListener;
#[derive(Clone)]

View file

@ -8,9 +8,9 @@ use dashmap::DashMap;
use logic::{GameRunner, NapResources};
use session::HallSession;
use tracing::{error, info};
use trigger_fileconfig::{main_city_script::MainCityConfig, NapFileCfg};
use trigger_fileconfig::{NapFileCfg, main_city_script::MainCityConfig};
use trigger_sv::{
config::{load_json_config, ServerEnvironmentConfiguration, TomlConfig},
config::{ServerEnvironmentConfiguration, TomlConfig, load_json_config},
die, logging,
net::{ServerNetworkManager, ServerType},
print_banner,

View file

@ -5,9 +5,9 @@ use trigger_sv::message::{
};
use crate::{
AppState,
logic::{GameStateListener, HallInitData},
session::HallSession,
AppState,
};
pub async fn handle_message(state: &'static AppState, packet: trigger_sv::message::NetworkPacket) {

View file

@ -1,9 +1,9 @@
use std::borrow::Cow;
use axum::{
Json, Router,
extract::{Query, State},
routing::get,
Json, Router,
};
use serde::{Deserialize, Serialize};
use tokio::net::TcpListener;
@ -64,7 +64,7 @@ async fn gm_api(
return Json(Response {
retcode: 2,
message: Some(Cow::Owned(format!("invalid command format: {err}"))),
})
});
}
};

View file

@ -1,8 +1,8 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
parse_macro_input, Data, DeriveInput, Field, Fields, GenericArgument, PathArguments, Type,
TypePath,
Data, DeriveInput, Field, Fields, GenericArgument, PathArguments, Type, TypePath,
parse_macro_input,
};
pub fn impl_gm_input(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
@ -114,7 +114,7 @@ pub fn impl_gm_input(input: proc_macro::TokenStream) -> proc_macro::TokenStream
fn from_str(input: &str) -> Result<Self, GMInputParseError> {
use GMInputParseError::*;
static CMD_TYPE_MAP: ::std::sync::LazyLock<::std::collections::HashMap<&'static str, #internal_enum_name>> =
static CMD_TYPE_MAP: ::std::sync::LazyLock<::std::collections::HashMap<&'static str, #internal_enum_name>> =
::std::sync::LazyLock::new(|| ::std::collections::HashMap::from([#internal_enum_mapping]));
let mut data = input.split(' ');
@ -165,4 +165,3 @@ fn get_field_sub_type(field: &Field) -> String {
_ => panic!("Unsupported field type"),
}
}

View file

@ -1,6 +1,6 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident};
use syn::{Data, DeriveInput, Fields, Ident, parse_macro_input};
pub fn impl_decodeable(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(item as DeriveInput);

View file

@ -1,6 +1,6 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident};
use syn::{Data, DeriveInput, Fields, Ident, parse_macro_input};
pub fn impl_encodeable(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(item as DeriveInput);

View file

@ -1,6 +1,6 @@
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_macro_input, FnArg, Item, ItemMod, ReturnType};
use quote::{ToTokens, quote};
use syn::{FnArg, Item, ItemMod, ReturnType, parse_macro_input};
pub fn imp(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
const INVALID_FUNCTION_SIGNATURE_MSG: &str = "functions in message handler module should have following signature: fn(&mut MessageContext<'_>, CsReq) -> ScRsp";

View file

@ -1,6 +1,6 @@
use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_macro_input, DeriveInput, Meta, MetaList};
use quote::{ToTokens, quote};
use syn::{DeriveInput, Meta, MetaList, parse_macro_input};
mod commands;
mod decodeable;

View file

@ -1,7 +1,7 @@
#![allow(unused)]
use super::tables::{
LOOKUP_G11, LOOKUP_G13, LOOKUP_G14, LOOKUP_G2, LOOKUP_G3, LOOKUP_G9, LOOKUP_RCON, LOOKUP_SBOX,
LOOKUP_G2, LOOKUP_G3, LOOKUP_G9, LOOKUP_G11, LOOKUP_G13, LOOKUP_G14, LOOKUP_RCON, LOOKUP_SBOX,
LOOKUP_SBOX_INV, SHIFT_ROWS_TABLE, SHIFT_ROWS_TABLE_INV,
};

View file

@ -1,6 +1,6 @@
use rsa::{
pkcs1v15::SigningKey, sha2::Sha256, signature::RandomizedSigner, Pkcs1v15Encrypt,
RsaPrivateKey, RsaPublicKey,
Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey, pkcs1v15::SigningKey, sha2::Sha256,
signature::RandomizedSigner,
};
const RSA_CHUNK_SIZE: usize = 117;

View file

@ -11,6 +11,7 @@ pub struct Model {
pub avatar_id: i32,
pub player_avatar_id: i32,
pub control_avatar_id: i32,
pub beginner_procedure_id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View file

@ -10,10 +10,11 @@ pub use sea_orm::DbErr;
use tracing::error;
pub mod prelude {
pub use sea_orm::entity::prelude::*;
pub use sea_orm::entity::ActiveValue::*;
pub use sea_orm::query::Condition;
pub use sea_orm::TransactionTrait;
pub use sea_orm::entity::ActiveValue::*;
pub use sea_orm::entity::prelude::*;
pub use sea_orm::query::Condition;
pub use sea_orm::sea_query::OnConflict;
}
#[derive(Debug, Deserialize)]

View file

@ -1,4 +1,4 @@
use byteorder::{ReadBytesExt, WriteBytesExt, BE};
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
use std::collections::HashMap;
use std::io::{self, Read, Write};

View file

@ -215,17 +215,32 @@ table EquipmentSuitTemplate {
id: int;
name: string;
primary_condition: int;
primary_suit_propertys: [Property];
unk_3: int;
primary_suit_ability: int;
primary_description: string;
secondary_condition: int;
secondary_suit_propertys: [Property];
unk_7: int;
secondary_suit_ability: int;
secondary_description: string;
suit_item_icon: string;
suit_icon: string;
suit_story: string;
suit_filter_option: string;
suit_icon: string;
suit_item_icon: string;
unk_14: int;
order: int;
unk_16: int;
unk_17: int;
unk_18: int;
unk_19: int;
unk_20: int;
unk_21: int;
primary_suit_propertys: [Property];
unk_23: [int];
unk_24: int;
unk_25: [int];
unk_26: [int];
unk_27: [int];
tag: string;
}
table HollowConfigTemplate {
@ -380,6 +395,196 @@ table ConditionConfigTemplate {
type: int;
}
table ProcedureConfigTemplate {
procedure_id: int;
procedure_type: int;
content_id: string;
jump_tos: [int];
procedure_banks: [string];
procedure_event: string;
}
table AvatarBattleTemplate {
id: int;
unk_1: [int];
unk_2: [int];
unk_3: [int];
unk_4: [int];
unk_5: [int];
unk_6: [int];
unk_7: [int];
unk_8: int;
unk_9: int;
unk_10: int;
avatar_piece_id: int;
unk_12: int;
unk_13: int;
hp_max: int;
health_growth: int;
unk_16: int;
unk_17: int;
unk_18: int;
unk_19: int;
unk_20: int;
attack: int;
attack_growth: int;
defence: int;
defence_growth: int;
crit: int;
crit_damage: int;
crit_res: int;
crit_damage_res: int;
pen_rate: int;
pen_delta: int;
luck: int;
stun: int;
break_stun: int;
element_abnormal_power: int;
sp_bar_point: int;
sp_recover: int;
element_mystery: int;
rbl: int;
rbl_correction_factor: int;
rbl_probability: int;
unk_41: int;
unk_42: int;
unk_43: int;
unk_44: int;
unk_45: int;
unk_46: int;
unk_47: int;
unk_48: int;
unk_49: int;
unk_50: int;
unk_51: int;
unk_52: int;
unk_53: int;
unk_54: int;
unk_55: int;
unk_56: int;
unk_57: int;
unk_58: int;
unk_59: int;
unk_60: int;
unk_61: int;
unk_62: int;
unk_63: int;
unk_64: int;
unk_65: int;
unk_66: int;
tags: [string];
unk_68: [int];
unk_69: [int];
unk_70: int;
unk_71: int;
element: [int];
hit_type: [int];
unk_element_camp: [string];
unk_75: int;
unk_76: short;
}
table AvatarLevelAdvanceTemplate {
avatar_id: int;
id: int;
min_level: int;
max_level: int;
hp_max: int;
unk_5: int;
unk_6: int;
attack: int;
defence: int;
unk_9: int;
unk_10: int;
unk_11: int;
unk_12: int;
unk_13: int;
unk_14: int;
unk_15: int;
unk_16: int;
unk_17: int;
unk_18: [int];
promotion_costs: [RefineCost];
}
table WeaponLevelTemplate {
rarity: int;
level: int;
rate: int;
exp: int;
}
table WeaponStarTemplate {
rarity: int;
star: int;
min_level: int;
max_level: int;
star_rate: int;
rand_rate: int;
unk_6: int;
unk_7: int;
unk_8: int;
unk_9: int;
unk_10: int;
unk_11: int;
unk_12: int;
}
table AvatarPassiveSkillTemplate {
skill_id: int;
avatar_id: int;
min_avatar_level: int;
min_passive_skill_level: int;
unlock_passive_skill_level: int;
unk_5: int;
unk_levelup: string;
unk_7: int;
unk_8: int;
unk_9: int;
unk_10: int;
propertys: [Property];
names: [string];
descriptions: [string];
materials_costs: [RefineCost];
}
table EquipmentLevelTemplate {
rarity: int;
level: int;
property_rate: int;
unk_3: int;
unk_4: int;
unk_5: int;
unk_6: int;
}
table AvatarSkinBaseTemplate {
id: int;
server_only_0: int;
DLFHPHCLIBA: string;
NFIEGMLEEFE: string;
avatar_id: int;
server_only_1: int;
server_only_2: int;
server_only_3: int;
GMBBOEGOEPH: string;
HMIOIBHJGCM: [string];
server_only_4: int;
OEMHKAENMHN: int;
FGJJELBGBBC: string;
FKBJLMBAPDI: int;
server_only_5: int;
server_only_6: int;
server_only_7: int;
server_only_8: int;
server_only_9: int;
DIGLJDFKAMN: string;
BKFKIDCLHKL: int;
FHJDONJMNKP: string;
AHHLKMJEEAE: string;
HPMCPJGPKJB: int;
}
table AvatarBaseTemplateTb {
data: [AvatarBaseTemplate];
}
@ -451,3 +656,35 @@ table TeleportConfigTemplateTb {
table ConditionConfigTemplateTb {
data: [ConditionConfigTemplate];
}
table ProcedureConfigTemplateTb {
data: [ProcedureConfigTemplate];
}
table AvatarBattleTemplateTb {
data: [AvatarBattleTemplate];
}
table AvatarLevelAdvanceTemplateTb {
data: [AvatarLevelAdvanceTemplate];
}
table WeaponLevelTemplateTb {
data: [WeaponLevelTemplate];
}
table WeaponStarTemplateTb {
data: [WeaponStarTemplate];
}
table AvatarPassiveSkillTemplateTb {
data: [AvatarPassiveSkillTemplate];
}
table EquipmentLevelTemplateTb {
data: [EquipmentLevelTemplate];
}
table AvatarSkinBaseTemplateTb {
data: [AvatarSkinBaseTemplate];
}

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
#[allow(dead_code, unused_imports, unsafe_op_in_unsafe_fn)]
#[allow(dead_code, unused_imports, unsafe_op_in_unsafe_fn, non_snake_case)]
#[path = "../gen_flatbuffers/tables_generated.rs"]
mod data;
pub mod main_city_script;
@ -45,6 +45,7 @@ file_cfg! {
WeaponTemplateTb;
EquipmentTemplateTb;
EquipmentSuitTemplateTb;
ProcedureConfigTemplateTb;
UnlockConfigTemplateTb;
PostGirlConfigTemplateTb;
ArchiveFileQuestTemplateTb;
@ -58,4 +59,11 @@ file_cfg! {
BattleGroupConfigTemplateTb;
MusicPlayerConfigTemplateTb;
TeleportConfigTemplateTb;
AvatarBattleTemplateTb;
AvatarLevelAdvanceTemplateTb;
WeaponLevelTemplateTb;
WeaponStarTemplateTb;
AvatarPassiveSkillTemplateTb;
EquipmentLevelTemplateTb;
AvatarSkinBaseTemplateTb;
}

View file

@ -6,3 +6,5 @@ version.workspace = true
[dependencies]
num_enum.workspace = true
prost.workspace = true
trigger-fileconfig.workspace = true

View file

@ -0,0 +1,91 @@
use num_enum::{IntoPrimitive, TryFromPrimitive};
#[repr(u32)]
#[derive(IntoPrimitive, TryFromPrimitive)]
pub enum EPropertyType {
Hp = 1,
HpMax = 111,
Atk = 121,
BreakStun = 122,
Def = 131,
Crit = 201,
CritDmg = 211,
Pen = 231,
PenValue = 232,
SpRecover = 305,
ElementMystery = 312,
ElementAbnormalPower = 314,
AddedDamageRatioPhysics = 315,
AddedDamageRatioFire = 316,
AddedDamageRatioIce = 317,
AddedDamageRatioElec = 318,
AddedDamageRatioEther = 319,
// battle
HpMaxBattle = 1111,
AtkBattle = 1121,
BreakStunBattle = 1122,
DefBattle = 1131,
CritBattle = 1201,
CritDmgBattle = 1211,
PenRatioBattle = 1231,
PenDeltaBattle = 1232,
SpRecoverBattle = 1305,
ElementMysteryBattle = 1312,
ElementAbnormalPowerBattle = 1314,
AddedDamageRatioPhysicsBattle = 1315,
AddedDamageRatioFireBattle = 1316,
AddedDamageRatioIceBattle = 1317,
AddedDamageRatioElecBattle = 1318,
AddedDamageRatioEtherBattle = 1319,
// base
HpMaxBase = 11101,
AtkBase = 12101,
BreakStunBase = 12201,
DefBase = 13101,
CritBase = 20101,
CritDmgBase = 21101,
PenBase = 23101,
PenValueBase = 23201,
SpRecoverBase = 30501,
ElementMysteryBase = 31201,
ElementAbnormalPowerBase = 31401,
// ratio
HpMaxRatio = 11102,
AtkRatio = 12102,
BreakStunRatio = 12202,
DefRatio = 13102,
SpRecoverRatio = 30502,
ElementAbnormalPowerRatio = 31402,
// delta
HpMaxDelta = 11103,
AtkDelta = 12103,
BreakStunDelta = 12203,
DefDelta = 13103,
CritDelta = 20103,
CritDmgDelta = 21103,
PenDelta = 23103,
PenValueDelta = 23203,
SpRecoverDelta = 30503,
ElementMysteryDelta = 31203,
ElementAbnormalPowerDelta = 31403,
// damage ratios 1/3
AddedDamageRatioPhysics1 = 31501,
AddedDamageRatioPhysics3 = 31503,
AddedDamageRatioFire1 = 31601,
AddedDamageRatioFire3 = 31603,
AddedDamageRatioIce1 = 31701,
AddedDamageRatioIce3 = 31703,
AddedDamageRatioElec1 = 31801,
AddedDamageRatioElec3 = 31803,
AddedDamageRatioEther1 = 31901,
AddedDamageRatioEther3 = 31903,
// --- custom
// growth
HpMaxGrowth = 9999_111_0,
AtkGrowth = 9999_121_0,
DefGrowth = 9999_131_0,
// advance
HpMaxAdvance = 9999_111_1,
AtkAdvance = 9999_121_1,
DefAdvance = 9999_131_1,
}

View file

@ -1,5 +1,7 @@
pub mod action_pb;
pub mod battle;
pub mod item;
pub mod quest;
pub mod scene;
pub mod skill;
pub mod template_ext;

View file

@ -21,6 +21,7 @@ pub enum ESceneType {
Fight = 3,
Fresh = 4,
MultiFight = 5,
TrainingRoom = 6,
Rally = 7,
}
@ -106,3 +107,9 @@ impl From<Vec<f64>> for Vector3f {
}
}
}
impl From<ESceneType> for u32 {
fn from(value: ESceneType) -> Self {
i16::from(value) as u32
}
}

View file

@ -0,0 +1,53 @@
use trigger_fileconfig::NapFileCfg;
pub trait TemplateExt {
fn is_player_avatar(&self, avatar_id: i32) -> bool;
fn skin_targets_avatar(&self, avatar_skin_id: i32, avatar_id: i32) -> bool;
fn procedure_allows_select_role(&self, procedure_id: i32) -> bool;
fn is_last_procedure(&self, procedure_id: i32) -> bool;
}
impl TemplateExt for NapFileCfg {
fn is_player_avatar(&self, avatar_id: i32) -> bool {
self.avatar_base_template_tb()
.data()
.unwrap()
.iter()
.find_map(|tmpl| (tmpl.id() == avatar_id && tmpl.camp() == 0).then_some(true))
.unwrap_or(false)
}
fn skin_targets_avatar(&self, avatar_skin_id: i32, avatar_id: i32) -> bool {
self.avatar_skin_base_template_tb()
.data()
.unwrap()
.iter()
.find(|tmpl| tmpl.id() == avatar_skin_id)
.map(|tmpl| tmpl.avatar_id() == avatar_id)
.unwrap_or(false)
}
fn procedure_allows_select_role(&self, procedure_id: i32) -> bool {
self.procedure_config_template_tb()
.data()
.unwrap()
.iter()
.find_map(|tmpl| {
(tmpl.procedure_id() == procedure_id && tmpl.procedure_type() == 4).then_some(true)
})
.unwrap_or(false)
}
fn is_last_procedure(&self, procedure_id: i32) -> bool {
// faggots nuked JumpTos from client data btw!
self.procedure_config_template_tb()
.data()
.unwrap()
.iter()
.max_by_key(|tmpl| tmpl.procedure_id())
.unwrap()
.procedure_id()
== procedure_id
}
}

View file

@ -5,7 +5,7 @@ use std::{
path::Path,
};
use quote::{quote, ToTokens};
use quote::{ToTokens, quote};
use syn::{Field, GenericArgument, Item, PathArguments, Type, TypePath};
fn main() {

View file

@ -10,15 +10,30 @@ pub struct GetRewardBuffDataScRsp {
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(7670)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BeginnerbattleBeginScRsp {
#[xor(8649)]
#[prost(int64, tag = "14")]
pub battle_uid: i64,
#[xor(10326)]
#[prost(int32, tag = "3")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PlayerBasicInfo {
pub struct PlayerInfo {
#[xor(15327)]
#[prost(uint32, tag = "9")]
pub level: u32,
#[xor(3181)]
#[prost(uint32, tag = "8")]
pub name_change_times: u32,
#[xor(3247)]
#[prost(int64, tag = "2")]
pub last_enter_world_timestamp: i64,
pub role_create_time: i64,
#[xor(9120)]
#[prost(uint32, tag = "12")]
pub avatar_id: u32,
@ -28,6 +43,9 @@ pub struct PlayerBasicInfo {
#[xor(8142)]
#[prost(uint32, tag = "1658")]
pub control_avatar_id: u32,
#[xor(13432)]
#[prost(uint32, tag = "7")]
pub portrait_id: u32,
#[prost(string, tag = "11")]
pub nick_name: ::prost::alloc::string::String,
#[xor(9818)]
@ -79,6 +97,15 @@ pub struct Equip {
pub exp: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(3935)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct SelectRoleCsReq {
#[xor(9750)]
#[prost(uint32, tag = "7")]
pub avatar_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(1850)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -112,6 +139,13 @@ pub struct DressedEquip {
pub equip_uid: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct LoadingPageTipsInfo {
#[prost(int32, repeated, tag = "12")]
pub unlocked_list: ::prost::alloc::vec::Vec<i32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(4672)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -137,7 +171,7 @@ pub struct AvatarSkillLevel {
#[cmdid(2764)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetCollectMapCsReq {}
pub struct GetPartnerDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -165,7 +199,7 @@ pub struct EndBattleCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PostGirlData {
pub struct PostGirlInfo {
#[prost(uint32, repeated, tag = "7")]
pub selected_post_girl_id_list: ::prost::alloc::vec::Vec<u32>,
#[prost(message, repeated, tag = "6")]
@ -177,6 +211,35 @@ pub struct PostGirlData {
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetBattleEventInfoCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8419)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SectionEventScNotify {
#[xor(4280)]
#[prost(uint32, tag = "14")]
pub owner_id: u32,
#[xor(11561)]
#[prost(uint32, tag = "1")]
pub tag: u32,
#[prost(enumeration = "ActionType", tag = "10")]
pub action_type: i32,
#[xor(15125)]
#[prost(uint32, tag = "7")]
pub event_graph_uid: u32,
#[prost(enumeration = "EventGraphOwnerType", tag = "9")]
pub owner_type: i32,
#[prost(string, tag = "15")]
pub npc_interaction: ::prost::alloc::string::String,
#[prost(bytes = "vec", tag = "11")]
pub action_data: ::prost::alloc::vec::Vec<u8>,
#[xor(1282)]
#[prost(uint32, tag = "3")]
pub event_id: u32,
#[xor(9535)]
#[prost(uint32, tag = "2")]
pub section_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8379)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -225,9 +288,16 @@ pub struct HallSceneInfo {
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct EnterSceneScNotify {
#[prost(message, optional, tag = "10")]
pub scene_info: ::core::option::Option<SceneInfo>,
pub scene: ::core::option::Option<SceneData>,
#[prost(message, optional, tag = "9")]
pub dungeon_info: ::core::option::Option<DungeonInfo>,
pub dungeon: ::core::option::Option<DungeonInfo>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PerformInfo {
#[prost(uint32, repeated, tag = "11")]
pub perform_id_list: ::prost::alloc::vec::Vec<u32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(499)]
@ -342,12 +412,21 @@ pub struct DressEquipmentCsReq {
pub equip_uid: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(6113)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BeginnerbattleBeginCsReq {
#[xor(12379)]
#[prost(int32, tag = "15")]
pub battle_id: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(6803)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetFairyDataScRsp {
pub struct GetTipsDataScRsp {
#[prost(message, optional, tag = "7")]
pub data: ::core::option::Option<FairyData>,
pub data: ::core::option::Option<TipsData>,
#[xor(3416)]
#[prost(int32, tag = "6")]
pub retcode: i32,
@ -378,6 +457,27 @@ pub struct GetActivityDataScRsp {
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(1970)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BeginnerbattleEndCsReq {
#[xor(322)]
#[prost(int64, tag = "4")]
pub battle_uid: i64,
#[xor(1154)]
#[prost(int32, tag = "11")]
pub battle_id: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(5251)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UnlockClueItemScRsp {
#[xor(379)]
#[prost(int32, tag = "7")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8370)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -478,6 +578,28 @@ pub struct GetBuddyDataScRsp {
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TipsSync {
#[prost(int32, repeated, tag = "13")]
pub tips_group_list: ::prost::alloc::vec::Vec<i32>,
#[prost(uint32, repeated, tag = "6")]
pub popup_window_list: ::prost::alloc::vec::Vec<u32>,
#[prost(int32, repeated, tag = "7")]
pub tips_list: ::prost::alloc::vec::Vec<i32>,
#[prost(map = "int32, enumeration(FairyState)", tag = "4")]
pub fairy_groups: ::std::collections::HashMap<i32, i32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(842)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BeginnerbattleEndScRsp {
#[xor(12999)]
#[prost(int32, tag = "11")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Transform {
#[prost(double, repeated, tag = "1")]
pub position: ::prost::alloc::vec::Vec<f64>,
@ -516,6 +638,24 @@ pub struct EnterSectionCsReq {
pub owner_type: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(9995)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BeginnerbattleRebeginScRsp {
#[xor(9333)]
#[prost(int32, tag = "7")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(7562)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct UndressAvatarSkinCsReq {
#[xor(4218)]
#[prost(uint32, tag = "12")]
pub avatar_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct RallySceneInfo {
@ -530,7 +670,7 @@ pub struct RallySceneInfo {
#[cmdid(4158)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetPlayerBasicInfoCsReq {}
pub struct GetPlayerInfoCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(4021)]
#[derive(trigger_protobuf_derive::XorFields)]
@ -566,9 +706,12 @@ pub struct FinishArchivePerformScRsp {
#[cmdid(6778)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ReportBattleTeamCsReq {
pub struct StartTrainingCsReq {
#[prost(int32, repeated, tag = "3")]
pub avatar_list: ::prost::alloc::vec::Vec<i32>,
#[xor(6606)]
#[prost(int32, tag = "9")]
pub special_training_index: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(744)]
@ -592,10 +735,22 @@ pub struct StartHollowQuestCsReq {
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetWebActivityDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(1149)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct EndTrainingCsReq {
#[xor(15023)]
#[prost(int32, tag = "4")]
pub special_training_index: i32,
#[xor(4240)]
#[prost(int64, tag = "5")]
pub training_uid: i64,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(358)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct WorkbenchGetDataCsReq {}
pub struct GetWorkbenchDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(5494)]
#[derive(trigger_protobuf_derive::XorFields)]
@ -612,6 +767,58 @@ pub struct AbyssGetDataScRsp {
pub abyss_group_list: ::prost::alloc::vec::Vec<AbyssGroup>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(480)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BeginnerbattleRebeginCsReq {
#[xor(3447)]
#[prost(int64, tag = "9")]
pub battle_uid: i64,
#[xor(4358)]
#[prost(int32, tag = "15")]
pub battle_id: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(9106)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FinishSectionEventCsReq {
#[prost(enumeration = "ActionType", tag = "4")]
pub action_type: i32,
#[prost(enumeration = "EventGraphOwnerType", tag = "8")]
pub owner_type: i32,
#[xor(15425)]
#[prost(uint32, tag = "9")]
pub event_graph_uid: u32,
#[prost(bytes = "vec", tag = "10")]
pub action_data: ::prost::alloc::vec::Vec<u8>,
#[xor(3183)]
#[prost(uint32, tag = "6")]
pub event_id: u32,
#[xor(3059)]
#[prost(uint32, tag = "5")]
pub section_id: u32,
#[xor(10274)]
#[prost(uint32, tag = "1")]
pub owner_id: u32,
#[xor(13404)]
#[prost(uint32, tag = "2")]
pub tag: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct VhsGuestInfo {
#[xor(2834)]
#[prost(int32, tag = "2")]
pub guest_id: i32,
#[xor(7940)]
#[prost(uint32, tag = "3")]
pub guest_type: u32,
#[prost(bool, tag = "7")]
pub has_guest: bool,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(7852)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -622,6 +829,18 @@ pub struct GetExplorationDataCsReq {}
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetResourceDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(3734)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AdvanceBeginnerProcedureCsReq {
#[xor(4241)]
#[prost(int32, tag = "5")]
pub params: i32,
#[xor(7267)]
#[prost(int32, tag = "7")]
pub procedure_id: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(4813)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -639,6 +858,9 @@ pub struct RunEventGraphCsReq {
#[xor(8708)]
#[prost(uint32, tag = "14")]
pub tag: u32,
#[xor(3174)]
#[prost(uint32, tag = "6")]
pub event_id: u32,
#[xor(14860)]
#[prost(uint32, tag = "8")]
pub owner_id: u32,
@ -664,6 +886,23 @@ pub struct StartHollowQuestScRsp {
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct FreshSceneInfo {
#[xor(13677)]
#[prost(uint32, tag = "7")]
pub last_procedure_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TipsInfo {
#[prost(int32, repeated, tag = "12")]
pub tips_group_list: ::prost::alloc::vec::Vec<i32>,
#[prost(int32, repeated, tag = "15")]
pub tips_list: ::prost::alloc::vec::Vec<i32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(2708)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -675,6 +914,15 @@ pub struct GetRoleCardDataScRsp {
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(1067)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct FinishSectionEventScRsp {
#[xor(9232)]
#[prost(int32, tag = "9")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(9476)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -682,6 +930,9 @@ pub struct SavePlayerSystemSettingCsReq {
#[xor(6028)]
#[prost(uint32, tag = "10")]
pub r#type: u32,
#[xor(8376)]
#[prost(uint32, tag = "14")]
pub params: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(2418)]
@ -692,7 +943,7 @@ pub struct GetRewardBuffDataCsReq {}
#[cmdid(8186)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BeginTrainingCourseBattleCsReq {
pub struct EnterTrainingRoomCsReq {
#[xor(8200)]
#[prost(uint32, tag = "5")]
pub quest_id: u32,
@ -717,6 +968,24 @@ pub struct QuestCollection {
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PopupWindowInfo {
#[prost(uint32, repeated, tag = "4")]
pub popup_window_list: ::prost::alloc::vec::Vec<u32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8963)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetVhsStoreDataScRsp {
#[xor(4520)]
#[prost(int32, tag = "12")]
pub retcode: i32,
#[prost(message, optional, tag = "11")]
pub data: ::core::option::Option<VhsStoreData>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ItemSync {
#[prost(message, repeated, tag = "6")]
pub material_list: ::prost::alloc::vec::Vec<Material>,
@ -745,6 +1014,8 @@ pub struct BeginArchiveBattleQuestScRsp {
pub struct BuddyUnitInfo {
#[prost(enumeration = "BuddyTeamType", tag = "6")]
pub r#type: i32,
#[prost(map = "uint32, int32", tag = "15")]
pub properties: ::std::collections::HashMap<u32, i32>,
#[xor(4322)]
#[prost(uint32, tag = "5")]
pub buddy_id: u32,
@ -913,6 +1184,18 @@ pub struct WeaponDressCsReq {
pub weapon_uid: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8333)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct EndNewbieScRsp {
#[xor(7830)]
#[prost(uint32, tag = "9")]
pub group_id: u32,
#[xor(16016)]
#[prost(int32, tag = "2")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8553)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -941,6 +1224,14 @@ pub struct HollowInfo {
pub hollow_quest_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(5937)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UnlockClueItemCsReq {
#[prost(enumeration = "Lclkcaiolep", tag = "4")]
pub r#type: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(9350)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -1015,7 +1306,7 @@ pub struct GetQuestDataCsReq {
#[cmdid(2325)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetTipsInfoCsReq {
pub struct GetSystemSettingsCsReq {
#[xor(12773)]
#[prost(uint32, tag = "12")]
pub r#type: u32,
@ -1048,6 +1339,18 @@ pub struct ActiveHollowCheckPointCsReq {
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetServerTimestampCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(9745)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct AdvanceBeginnerProcedureScRsp {
#[xor(9328)]
#[prost(int32, tag = "6")]
pub next_procedure_id: i32,
#[xor(5852)]
#[prost(int32, tag = "7")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(7723)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -1128,24 +1431,28 @@ pub struct GetQuestionsAnswerGameDataCsReq {}
#[cmdid(4174)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetClientSystemsDataScRsp {
pub struct GetUnlockDataScRsp {
#[xor(2530)]
#[prost(int32, tag = "3")]
pub retcode: i32,
#[prost(message, optional, tag = "6")]
pub data: ::core::option::Option<ClientSystemsData>,
pub data: ::core::option::Option<UnlockData>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(6645)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetTipsInfoScRsp {
pub struct GetSystemSettingsScRsp {
#[xor(11676)]
#[prost(uint32, tag = "10")]
pub r#type: u32,
#[xor(10864)]
#[prost(int32, tag = "5")]
pub retcode: i32,
#[prost(map = "uint32, uint32", tag = "15")]
pub player_settings_map: ::std::collections::HashMap<u32, u32>,
#[prost(message, optional, tag = "12")]
pub settings: ::core::option::Option<SystemSettings>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(1087)]
@ -1173,6 +1480,8 @@ pub struct GetWishlistDataCsReq {}
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct AvatarUnitInfo {
#[prost(map = "uint32, int32", tag = "9")]
pub properties: ::std::collections::HashMap<u32, i32>,
#[xor(3561)]
#[prost(uint32, tag = "3")]
pub avatar_id: u32,
@ -1219,6 +1528,14 @@ pub struct PlayerGetTokenScRsp {
pub sign: ::prost::alloc::string::String,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct PromoterInfo {
#[xor(10809)]
#[prost(uint32, tag = "11")]
pub id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(3631)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -1279,6 +1596,9 @@ pub struct UndressEquipmentCsReq {
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SyncEventInfoScNotify {
#[xor(3581)]
#[prost(uint32, tag = "11")]
pub event_id: u32,
#[prost(message, repeated, tag = "13")]
pub action_list: ::prost::alloc::vec::Vec<ActionInfo>,
#[xor(2229)]
@ -1299,6 +1619,13 @@ pub struct SyncEventInfoScNotify {
pub owner_type: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct VhsFlowInfo {
#[prost(message, repeated, tag = "9")]
pub buff_list: ::prost::alloc::vec::Vec<VhsFlowBuffInfo>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(9161)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -1354,18 +1681,34 @@ pub struct GetFashionStoreDataCsReq {}
#[cmdid(7302)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetPlayerBasicInfoScRsp {
pub struct GetPlayerInfoScRsp {
#[xor(4333)]
#[prost(int32, tag = "10")]
pub retcode: i32,
#[prost(message, optional, tag = "8")]
pub basic_info: ::core::option::Option<PlayerBasicInfo>,
pub player_info: ::core::option::Option<PlayerInfo>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct VhsFlowBuffInfo {
#[prost(enumeration = "VhsFlowBuffSource", tag = "3")]
pub buff_source: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(4652)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct SelectRoleScRsp {
#[xor(417)]
#[prost(int32, tag = "7")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(6289)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetClientSystemsDataCsReq {}
pub struct GetUnlockDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(2111)]
#[derive(trigger_protobuf_derive::XorFields)]
@ -1378,15 +1721,19 @@ pub struct GetChatEmojiListScRsp {
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ClientSystemsData {
pub struct UnlockData {
#[prost(message, optional, tag = "1")]
pub post_girl_data: ::core::option::Option<PostGirlData>,
pub post_girl: ::core::option::Option<PostGirlInfo>,
#[prost(message, optional, tag = "14")]
pub unlock_data: ::core::option::Option<UnlockData>,
pub unlock: ::core::option::Option<UnlockInfo>,
#[prost(message, optional, tag = "10")]
pub teleport_data: ::core::option::Option<TeleportData>,
pub teleport: ::core::option::Option<TeleportUnlockInfo>,
#[prost(message, optional, tag = "2")]
pub hollow_event: ::core::option::Option<HollowEventUnlockInfo>,
#[prost(message, optional, tag = "8")]
pub music_player_data: ::core::option::Option<MusicPlayerData>,
pub music_player: ::core::option::Option<MusicPlayerInfo>,
#[prost(message, optional, tag = "4")]
pub perform: ::core::option::Option<PerformInfo>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(2014)]
@ -1419,7 +1766,7 @@ pub struct GetActivityDataCsReq {
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UnlockData {
pub struct UnlockInfo {
#[prost(int32, repeated, tag = "13")]
pub unlocked_list: ::prost::alloc::vec::Vec<i32>,
}
@ -1496,6 +1843,18 @@ pub struct GetCafeDataScRsp {
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct PlayerLogoutCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct VhsStoreOpenInfo {
#[prost(message, optional, tag = "4")]
pub cur_promoter: ::core::option::Option<PromoterInfo>,
#[prost(int32, repeated, tag = "13")]
pub vhs_collection_id_list: ::prost::alloc::vec::Vec<i32>,
#[xor(3569)]
#[prost(int64, tag = "3")]
pub setup_time: i64,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(6280)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -1556,7 +1915,7 @@ pub struct GetMonthCardRewardListCsReq {}
#[cmdid(4783)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct GetFairyDataCsReq {}
pub struct GetTipsDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(3591)]
#[derive(trigger_protobuf_derive::XorFields)]
@ -1580,6 +1939,18 @@ pub struct GetBattlePassDataCsReq {}
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct PostEnterWorldCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8883)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct DressAvatarSkinCsReq {
#[xor(6961)]
#[prost(uint32, tag = "7")]
pub avatar_id: u32,
#[xor(59)]
#[prost(uint32, tag = "12")]
pub avatar_skin_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PublicVariable {
@ -1623,6 +1994,13 @@ pub struct PlayerGetTokenCsReq {
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct HollowEventUnlockInfo {
#[prost(int32, repeated, tag = "3")]
pub unlocked_list: ::prost::alloc::vec::Vec<i32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DungeonEquipInfo {
#[prost(message, repeated, tag = "15")]
pub equip_list: ::prost::alloc::vec::Vec<Equip>,
@ -1657,7 +2035,9 @@ pub struct PlayerSyncScNotify {
#[prost(message, optional, tag = "2")]
pub avatar_sync: ::core::option::Option<AvatarSync>,
#[prost(message, optional, tag = "5")]
pub basic_info: ::core::option::Option<PlayerBasicInfo>,
pub player_info: ::core::option::Option<PlayerInfo>,
#[prost(message, optional, tag = "13")]
pub tips: ::core::option::Option<TipsSync>,
#[prost(message, optional, tag = "1")]
pub item_sync: ::core::option::Option<ItemSync>,
}
@ -1748,6 +2128,18 @@ pub struct UpdateEventGraphScNotify {
pub event_graph_uid: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(2753)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct StartTrainingScRsp {
#[xor(9872)]
#[prost(int64, tag = "15")]
pub training_uid: i64,
#[xor(1222)]
#[prost(int32, tag = "13")]
pub retcode: i32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(7975)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
@ -1777,11 +2169,20 @@ pub struct GetDisplayCaseDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TeleportData {
pub struct TeleportUnlockInfo {
#[prost(int32, repeated, tag = "8")]
pub unlocked_list: ::prost::alloc::vec::Vec<i32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FairyInfo {
#[prost(map = "int32, enumeration(FairyState)", tag = "10")]
pub fairy_groups: ::std::collections::HashMap<i32, i32>,
#[prost(int32, repeated, tag = "14")]
pub fairy_record_list: ::prost::alloc::vec::Vec<i32>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(5659)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
@ -1805,6 +2206,46 @@ pub struct ClickHollowSystemCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct VhsStoreData {
#[xor(2629)]
#[prost(uint32, tag = "4")]
pub store_level: u32,
#[prost(int32, repeated, tag = "3")]
pub unlock_collection_id_list: ::prost::alloc::vec::Vec<i32>,
#[prost(message, optional, tag = "13")]
pub vhs_store_open_info: ::core::option::Option<VhsStoreOpenInfo>,
#[prost(map = "uint32, message", tag = "10")]
pub promoter_info_map: ::std::collections::HashMap<u32, PromoterInfo>,
#[prost(message, optional, tag = "2")]
pub vhs_guest_info: ::core::option::Option<VhsGuestInfo>,
#[prost(message, optional, tag = "1")]
pub vhs_flow_info: ::core::option::Option<VhsFlowInfo>,
#[prost(bool, tag = "8")]
pub is_need_refresh: bool,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(5983)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct EndNewbieCsReq {
#[xor(413)]
#[prost(uint32, tag = "11")]
pub group_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SystemSettings {
#[prost(uint32, repeated, tag = "1")]
pub systems: ::prost::alloc::vec::Vec<u32>,
#[prost(bool, tag = "7")]
pub switch_of_story_mode: bool,
#[prost(bool, tag = "6")]
pub switch_of_qte: bool,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct QuestInfo {
#[xor(5460)]
#[prost(uint32, tag = "14")]
@ -1861,9 +2302,11 @@ pub struct MusicPlayerItem {
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SceneInfo {
pub struct SceneData {
#[prost(message, optional, tag = "11")]
pub hall_scene_info: ::core::option::Option<HallSceneInfo>,
#[prost(message, optional, tag = "12")]
pub fresh_scene_info: ::core::option::Option<FreshSceneInfo>,
#[xor(10113)]
#[prost(uint32, tag = "6")]
pub local_play_type: u32,
@ -1876,7 +2319,7 @@ pub struct SceneInfo {
pub rally_scene_info: ::core::option::Option<RallySceneInfo>,
#[xor(13343)]
#[prost(uint32, tag = "7")]
pub event_id: u32,
pub scene_id: u32,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(5352)]
@ -1896,11 +2339,20 @@ pub struct GetWeaponDataCsReq {}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct FairyData {}
pub struct TipsData {
#[prost(message, optional, tag = "5")]
pub tips: ::core::option::Option<TipsInfo>,
#[prost(message, optional, tag = "7")]
pub fairy: ::core::option::Option<FairyInfo>,
#[prost(message, optional, tag = "10")]
pub loading_page_tips: ::core::option::Option<LoadingPageTipsInfo>,
#[prost(message, optional, tag = "9")]
pub popup_window: ::core::option::Option<PopupWindowInfo>,
}
#[derive(trigger_protobuf_derive::CmdID)]
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct MusicPlayerData {
pub struct MusicPlayerInfo {
#[prost(message, repeated, tag = "3")]
pub music_list: ::prost::alloc::vec::Vec<MusicPlayerItem>,
}
@ -5925,26 +6377,26 @@ impl Ilojlciaack {
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum Eifoghmicik {
Cldigdhookf = 0,
Fjookhinkdm = 1,
pub enum FairyState {
EifoghmicikCldigdhookf = 0,
EifoghmicikFjookhinkdm = 1,
}
impl Eifoghmicik {
impl FairyState {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
Self::Cldigdhookf => "EIFOGHMICIK_CLDIGDHOOKF",
Self::Fjookhinkdm => "EIFOGHMICIK_FJOOKHINKDM",
Self::EifoghmicikCldigdhookf => "EIFOGHMICIK_CLDIGDHOOKF",
Self::EifoghmicikFjookhinkdm => "EIFOGHMICIK_FJOOKHINKDM",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"EIFOGHMICIK_CLDIGDHOOKF" => Some(Self::Cldigdhookf),
"EIFOGHMICIK_FJOOKHINKDM" => Some(Self::Fjookhinkdm),
"EIFOGHMICIK_CLDIGDHOOKF" => Some(Self::EifoghmicikCldigdhookf),
"EIFOGHMICIK_FJOOKHINKDM" => Some(Self::EifoghmicikFjookhinkdm),
_ => None,
}
}
@ -17299,27 +17751,33 @@ impl Fgchgkjflpl {
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum Amnemeaehhp {
VhsFlowBuffSourceNone = 0,
VhsFlowBuffSourceQuest = 1,
pub enum VhsFlowBuffSource {
AmnemeaehhpVhsFlowBuffSourceNone = 0,
AmnemeaehhpVhsFlowBuffSourceQuest = 1,
}
impl Amnemeaehhp {
impl VhsFlowBuffSource {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
Self::VhsFlowBuffSourceNone => "AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_NONE",
Self::VhsFlowBuffSourceQuest => "AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_QUEST",
Self::AmnemeaehhpVhsFlowBuffSourceNone => {
"AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_NONE"
}
Self::AmnemeaehhpVhsFlowBuffSourceQuest => {
"AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_QUEST"
}
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_NONE" => Some(Self::VhsFlowBuffSourceNone),
"AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_NONE" => {
Some(Self::AmnemeaehhpVhsFlowBuffSourceNone)
}
"AMNEMEAEHHP_VHS_FLOW_BUFF_SOURCE_QUEST" => {
Some(Self::VhsFlowBuffSourceQuest)
Some(Self::AmnemeaehhpVhsFlowBuffSourceQuest)
}
_ => None,
}
@ -29900,29 +30358,29 @@ impl Eepfppcppge {
#[derive(trigger_protobuf_derive::XorFields)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum Ggdbnpkalbm {
pub enum PerformType {
PlotPlay = 0,
Dialog = 1,
Bubble = 2,
}
impl Ggdbnpkalbm {
impl PerformType {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
Self::PlotPlay => "GGDBNPKALBM_PLOT_PLAY",
Self::Dialog => "GGDBNPKALBM_DIALOG",
Self::Bubble => "GGDBNPKALBM_BUBBLE",
Self::PlotPlay => "PERFORM_TYPE_PLOT_PLAY",
Self::Dialog => "PERFORM_TYPE_DIALOG",
Self::Bubble => "PERFORM_TYPE_BUBBLE",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"GGDBNPKALBM_PLOT_PLAY" => Some(Self::PlotPlay),
"GGDBNPKALBM_DIALOG" => Some(Self::Dialog),
"GGDBNPKALBM_BUBBLE" => Some(Self::Bubble),
"PERFORM_TYPE_PLOT_PLAY" => Some(Self::PlotPlay),
"PERFORM_TYPE_DIALOG" => Some(Self::Dialog),
"PERFORM_TYPE_BUBBLE" => Some(Self::Bubble),
_ => None,
}
}

File diff suppressed because it is too large Load diff

View file

@ -30,24 +30,26 @@ where
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1)]
pub struct GetPlayerBasicInfoCsReq {}
pub struct GetPlayerInfoCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PlayerBasicInfo {
pub struct PlayerInfo {
pub nick_name: String,
pub level: u32,
pub exp: u32,
pub avatar_id: u32,
pub player_avatar_id: u32,
pub role_create_time: i64,
pub name_change_times: u32,
pub portrait_id: u32,
pub control_avatar_id: u32,
pub last_enter_world_timestamp: i64,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2)]
pub struct GetPlayerBasicInfoScRsp {
pub struct GetPlayerInfoScRsp {
pub retcode: i32,
pub basic_info: Option<PlayerBasicInfo>,
pub player_info: Option<PlayerInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -83,6 +85,18 @@ pub struct PlayerLogoutScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(9)]
pub struct SelectRoleCsReq {
pub avatar_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(10)]
pub struct SelectRoleScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(80)]
pub struct SwitchRoleCsReq {
@ -145,7 +159,7 @@ pub struct CafeSync {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(100)]
pub struct PlayerSyncScNotify {
pub basic_info: Option<PlayerBasicInfo>,
pub player_info: Option<PlayerInfo>,
pub avatar_sync: Option<AvatarSync>,
pub item_sync: Option<ItemSync>,
pub ramen_sync: Option<RamenSync>,
@ -261,12 +275,13 @@ pub struct Transform {
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct SceneInfo {
pub struct SceneData {
pub scene_type: u32,
pub event_id: u32,
pub scene_id: u32,
pub local_play_type: u32,
pub hall_scene_info: Option<HallSceneInfo>,
pub fight_scene_info: Option<FightSceneInfo>,
pub fresh_scene_info: Option<FreshSceneInfo>,
pub rally_scene_info: Option<RallySceneInfo>,
}
@ -320,6 +335,11 @@ pub struct FightSceneInfo {
pub level_reward_info: Option<LevelRewardInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct FreshSceneInfo {
pub last_procedure_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PublicVariable {
pub r#type: u32,
@ -355,6 +375,7 @@ pub struct DungeonEquipInfo {
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct AvatarUnitInfo {
pub avatar_id: u32,
pub properties: HashMap<u32, i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
@ -392,8 +413,8 @@ pub struct EnterWorldScRsp {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(452)]
pub struct EnterSceneScNotify {
pub scene_info: Option<SceneInfo>,
pub dungeon_info: Option<DungeonInfo>,
pub scene: Option<SceneData>,
pub dungeon: Option<DungeonInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -558,6 +579,59 @@ pub struct ActiveHollowCheckPointScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(477)]
pub struct AdvanceBeginnerProcedureCsReq {
pub procedure_id: i32,
pub params: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(478)]
pub struct AdvanceBeginnerProcedureScRsp {
pub retcode: i32,
pub next_procedure_id: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(479)]
pub struct BeginnerbattleBeginCsReq {
pub battle_id: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(480)]
pub struct BeginnerbattleBeginScRsp {
pub retcode: i32,
pub battle_uid: i64,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(481)]
pub struct BeginnerbattleRebeginCsReq {
pub battle_id: i32,
pub battle_uid: i64,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(482)]
pub struct BeginnerbattleRebeginScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(483)]
pub struct BeginnerbattleEndCsReq {
pub battle_id: i32,
pub battle_uid: i64,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(484)]
pub struct BeginnerbattleEndScRsp {
pub retcode: i32,
}
// Quest
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
@ -695,7 +769,7 @@ pub struct GetPrivateMessageDataScRsp {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(640)]
pub struct BeginTrainingCourseBattleCsReq {
pub struct EnterTrainingRoomCsReq {
pub quest_id: u32,
pub buddy_id: u32,
pub avatar_id_list: Vec<u32>,
@ -703,7 +777,7 @@ pub struct BeginTrainingCourseBattleCsReq {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(641)]
pub struct BeginTrainingCourseBattleScRsp {
pub struct EnterTrainingRoomScRsp {
pub retcode: i32,
}
@ -978,6 +1052,31 @@ pub struct GetAvatarRecommendEquipScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(842)]
pub struct DressAvatarSkinCsReq {
pub avatar_id: u32,
pub avatar_skin_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(843)]
pub struct DressAvatarSkinScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(844)]
pub struct UndressAvatarSkinCsReq {
pub avatar_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(845)]
pub struct UndressAvatarSkinScRsp {
pub retcode: i32,
}
// Bangboo
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1052,7 +1151,7 @@ pub struct EatRamenScRsp {
// Client systems
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct UnlockData {
pub struct UnlockInfo {
pub unlocked_list: Vec<i32>,
}
@ -1063,7 +1162,7 @@ pub struct PostGirlItem {
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PostGirlData {
pub struct PostGirlInfo {
pub post_girl_item_list: Vec<PostGirlItem>,
pub selected_post_girl_id_list: Vec<u32>,
pub show_random_selected: bool,
@ -1077,21 +1176,61 @@ pub struct MusicPlayerItem {
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct MusicPlayerData {
pub struct MusicPlayerInfo {
pub music_list: Vec<MusicPlayerItem>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct TeleportData {
pub struct TeleportUnlockInfo {
pub unlocked_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct ClientSystemsData {
pub unlock_data: Option<UnlockData>,
pub post_girl_data: Option<PostGirlData>,
pub teleport_data: Option<TeleportData>,
pub music_player_data: Option<MusicPlayerData>,
pub struct NewbieInfo {
pub unlocked_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PerformInfo {
pub perform_id_list: Vec<u32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct HollowEventUnlockInfo {
pub unlock_map: Vec<i32>,
pub new_unlock_map: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct HollowCardUnlockInfo {
pub unlock_map: Vec<i32>,
pub new_unlock_map: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct HollowItemUnlockInfo {
pub unlock_map: Vec<i32>,
pub new_unlock_map: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct CurseUnlockInfo {
pub unlock_map: Vec<i32>,
pub new_unlock_map: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct UnlockData {
pub unlock: Option<UnlockInfo>,
pub newbie: Option<NewbieInfo>,
pub perform: Option<PerformInfo>,
pub hollow_event: Option<HollowEventUnlockInfo>,
pub hollow_card: Option<HollowCardUnlockInfo>,
pub hollow_item: Option<HollowItemUnlockInfo>,
pub curse: Option<CurseUnlockInfo>,
pub teleport: Option<TeleportUnlockInfo>,
pub post_girl: Option<PostGirlInfo>,
pub music_player: Option<MusicPlayerInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1120,27 +1259,35 @@ pub struct SavePlayerSystemSettingScRsp {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1305)]
pub struct GetTipsInfoCsReq {}
pub struct GetSystemSettingsCsReq {
pub r#type: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct TipsInfo {}
pub struct SystemSettings {
pub systems: Vec<u32>,
pub switch_of_story_mode: bool,
pub switch_of_qte: bool,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1306)]
pub struct GetTipsInfoScRsp {
pub struct GetSystemSettingsScRsp {
pub retcode: i32,
pub tips_info: Option<TipsInfo>,
pub r#type: u32,
pub settings: Option<SystemSettings>,
pub player_settings_map: HashMap<u32, u32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1307)]
pub struct GetClientSystemsDataCsReq {}
pub struct GetUnlockDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1308)]
pub struct GetClientSystemsDataScRsp {
pub struct GetUnlockDataScRsp {
pub retcode: i32,
pub data: Option<ClientSystemsData>,
pub data: Option<UnlockData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1222,6 +1369,19 @@ pub struct GetNewsStandDataScRsp {
pub news_stand_data: Option<NewsStandData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1323)]
pub struct EndNewbieCsReq {
pub group_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1324)]
pub struct EndNewbieScRsp {
pub retcode: i32,
pub group_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1340)]
pub struct GetTrashbinHermitDataCsReq {}
@ -1300,20 +1460,47 @@ pub struct GetDailyChallengeDataScRsp {
pub data: Option<DailyChallengeData>,
}
// Fairy
// Tips
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1601)]
pub struct GetFairyDataCsReq {}
pub struct GetTipsDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct FairyData {}
pub struct TipsInfo {
pub tips_group_list: Vec<i32>,
pub tips_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct FairyInfo {
pub fairy_record_list: Vec<i32>,
pub fairy_groups: HashMap<i32, i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PopupWindowInfo {
pub popup_window_list: Vec<u32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct LoadingPageTipsInfo {
pub unlocked_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct TipsData {
pub tips: Option<TipsInfo>,
pub fairy: Option<FairyInfo>,
pub popup_window: Option<PopupWindowInfo>,
pub loading_page_tips: Option<LoadingPageTipsInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1602)]
pub struct GetFairyDataScRsp {
pub struct GetTipsDataScRsp {
pub retcode: i32,
pub data: Option<FairyData>,
pub data: Option<TipsData>,
}
// Activity
@ -1386,36 +1573,64 @@ pub struct GetMainCityRevivalDataScRsp {
pub main_city_revival_data: Option<MainCityRevivalData>,
}
// Collections
// Workbench
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2001)]
pub struct GetCollectMapCsReq {}
#[id(2000)]
pub struct GetWorkbenchDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct CollectMap {}
pub struct ClueData {
pub unlocked_clue_area_list: Vec<i32>,
pub unlocked_clue_id_list: Vec<i32>,
pub awarded_clue_id_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2002)]
pub struct GetCollectMapScRsp {
pub retcode: i32,
pub collect_map: Option<CollectMap>,
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct WorkbenchData {
pub workbench_app_list: Vec<u32>,
pub clue_data: Option<ClueData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2021)]
pub struct WorkbenchGetDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct WorkbenchData {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2022)]
pub struct WorkbenchGetDataScRsp {
#[id(2001)]
pub struct GetWorkbenchDataScRsp {
pub retcode: i32,
pub workbench_data: Option<WorkbenchData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2002)]
pub struct UnlockClueItemCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2003)]
pub struct UnlockClueItemScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2010)]
pub struct GetPartnerDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PartnerTrustInfo {
pub level: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PartnerData {
pub partner_memory_id_list: Vec<u32>,
pub partner_trust_list: Vec<PartnerTrustInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2011)]
pub struct GetPartnerDataScRsp {
pub retcode: i32,
pub partner_data: Option<PartnerData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2041)]
pub struct GetAbyssRewardDataCsReq {}
@ -1504,6 +1719,20 @@ pub struct PerformEndScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2406)]
pub struct StartTrainingCsReq {
pub avatar_list: Vec<i32>,
pub special_training_index: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2407)]
pub struct StartTrainingScRsp {
pub retcode: i32,
pub training_uid: i64,
}
// BattleEvent
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1520,18 +1749,6 @@ pub struct GetBattleEventInfoScRsp {
pub event_info: Option<BattleEventInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2452)]
pub struct ReportBattleTeamCsReq {
pub avatar_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2453)]
pub struct ReportBattleTeamScRsp {
pub retcode: i32,
}
// VhsStore
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]

View file

@ -1,4 +1,4 @@
use serde::{de::DeserializeOwned, Deserialize, Deserializer};
use serde::{Deserialize, Deserializer, de::DeserializeOwned};
use std::net::SocketAddr;
use tracing::error;
use trigger_database::DatabaseSetting;

View file

@ -43,6 +43,7 @@ pub enum GMCommand {
UnlockAllHollow = 302,
UnlockAllHollowBuff = 400,
UnlockAllCafeItem = 401,
UnlockAllAvatarSkin = 402,
}
#[derive(thiserror::Error, Debug)]

View file

@ -1,6 +1,6 @@
use crate::message::opcode;
use trigger_codegen::{Decodeable, Encodeable};
use trigger_protocol::{util::ProtocolUnit, DungeonEquipInfo};
use trigger_protocol::{DungeonEquipInfo, util::ProtocolUnit};
#[derive(Debug, Encodeable, Decodeable)]
pub struct BindClientSessionMessage {

View file

@ -4,7 +4,7 @@ use futures::future::BoxFuture;
use tokio::task::JoinHandle;
use tracing::warn;
use trigger_encoding::Decodeable;
use zeromq::{prelude::*, PullSocket, ZmqError};
use zeromq::{PullSocket, ZmqError, prelude::*};
use crate::message::NetworkPacket;

View file

@ -3,7 +3,7 @@ mod socket;
use std::{collections::HashMap, io::Cursor, net::SocketAddr};
pub use listener::{listen, RecvCallback};
pub use listener::{RecvCallback, listen};
use num_enum::{IntoPrimitive, TryFromPrimitive};
pub use socket::ServerSocket;

View file

@ -5,8 +5,8 @@ use std::time::Duration;
use tokio::sync::mpsc;
use tracing::warn;
use trigger_encoding::Encodeable;
use zeromq::prelude::*;
use zeromq::PushSocket;
use zeromq::prelude::*;
use crate::message::NetworkPacket;

13
res_versions.toml Normal file
View file

@ -0,0 +1,13 @@
["OSPRODWin1.6.0"]
design_data_url = "https://autopatchos.zenlesszonezero.com/design_data/1.6_live/output_7108077_40d564da66/client/"
design_data_revision = "7108077"
design_data_files = '[{"fileName":"data_version","fileSize":4304,"fileMD5":"941245265336071363"}]'
game_res_url = "https://autopatchos.zenlesszonezero.com/game_res/1.6_live/output_7108077_40d564da66/client/"
game_res_branch = "1.6_live"
game_audio_revision = "7036823"
game_res_revision = "7108077"
game_res_files = '[{"fileName":"res_version","fileSize":2487933,"fileMD5":"16738022146290696861"},{"fileName":"audio_version","fileSize":32246,"fileMD5":"718221674779072830"},{"fileName":"base_revision","fileSize":18,"fileMD5":"3467029748880207404"}]'
silence_url = "https://autopatchos.zenlesszonezero.com/design_data/1.6_live/output_7108077_40d564da66/client_silence/"
silence_revision = "7036823"
silence_files = '[{"fileName":"silence_version","fileSize":467,"fileMD5":"2392489994088458280"}]'