Compare commits

..

4 commits

Author SHA1 Message Date
af2cef394b Updated Filecfgs 2025-03-19 11:02:00 +01:00
23fcde33f5 Properties calc port for 1.7beta (#7)
Reviewed-on: #7
Co-authored-by: traffic95 <traffic95@xeondev.com>
Co-committed-by: traffic95 <traffic95@xeondev.com>
2025-03-19 08:52:04 +00:00
543727ce4e Added TeleportData support 2025-03-13 19:10:38 +01:00
7412dcec2d CNBeta 1.7.0 support 2025-03-11 18:20:56 +01:00
64 changed files with 33644 additions and 36713 deletions

2
Cargo.lock generated
View file

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

View file

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -41,7 +41,7 @@ Start each service in order from option `a)`.
Most of the configuration (database, encryption keys) is stored in a shared environment configuration file (`environment.toml`). Some of server-specific options are stored in their respective configuration files (which are created upon first startup of each server).
### Logging in
To login to this server, you have to obtain a compatible game client. Currently supported one is `OSPRODWin1.6.0`, you can get it from game launcher. Next, you have to apply the necessary [client patch](https://git.xeondev.com/ObolSquad/trigger-patch). It allows you to connect to the local server and replaces encryption keys with custom ones.
To login to this server, you have to obtain a compatible game client. Currently supported one is `CNBetaWin1.7.0`, you can get it from uploads found on [Our Discord Server](https://discord.gg/reversedrooms). Next, you have to apply the necessary [client patch](https://git.xeondev.com/ObolSquad/trigger-patch). It allows you to connect to the local server and replaces encryption keys with custom ones.
### Management
You can use the [trigger-muip-tool](https://git.xeondev.com/ObolSquad/trigger-muip-tool) to communicate with MUIP server and execute GM commands.

View file

@ -29,7 +29,7 @@ impl GameState {
} => Self {
filecfg,
scene: Scene::Fight(FightScene {
scene_id: Self::get_scene_id(filecfg, *quest_id, (*play_type).into()),
event_id: Self::get_scene_event_id(filecfg, *quest_id, (*play_type).into()),
play_type: (*play_type).into(),
perform: ScenePerform {
time: String::from("Morning"),
@ -53,7 +53,11 @@ impl GameState {
buddy_type: 0,
buddy_id: 50001,
}],
inner_quests: vec![Self::get_scene_id(filecfg, *quest_id, (*play_type).into())],
inner_quests: vec![Self::get_scene_event_id(
filecfg,
*quest_id,
(*play_type).into(),
)],
equip: dungeon_equip.clone(),
},
},
@ -65,7 +69,7 @@ impl GameState {
dungeon_equip,
} => Self {
scene: Scene::Rally(RallyScene {
scene_id: Self::get_scene_id(filecfg, *quest_id, (*play_type).into()),
event_id: Self::get_scene_event_id(filecfg, *quest_id, (*play_type).into()),
perform: ScenePerform {
time: String::from("Morning"),
weather: String::from("SunShine"),
@ -88,7 +92,11 @@ impl GameState {
buddy_type: 0,
buddy_id: 50001,
}],
inner_quests: vec![Self::get_scene_id(filecfg, *quest_id, (*play_type).into())],
inner_quests: vec![Self::get_scene_event_id(
filecfg,
*quest_id,
(*play_type).into(),
)],
equip: dungeon_equip.clone(),
},
filecfg,
@ -97,7 +105,7 @@ impl GameState {
})
}
fn get_scene_id(filecfg: &NapFileCfg, quest_id: u32, play_type: ELocalPlayType) -> u32 {
fn get_scene_event_id(filecfg: &NapFileCfg, quest_id: u32, play_type: ELocalPlayType) -> u32 {
match play_type {
ELocalPlayType::TrainingRoom => 19800014,
ELocalPlayType::ArchiveBattle => filecfg
@ -127,7 +135,7 @@ impl GameState {
debug!(
"the battle is over, quest_id: {}, event_id: {}",
self.dungeon.quest_id,
self.scene.get_scene_id()
self.scene.get_event_id()
);
vec![

View file

@ -3,19 +3,19 @@ use trigger_logic::scene::ELocalPlayType;
use super::ScenePerform;
pub struct FightScene {
pub scene_id: u32,
pub event_id: u32,
pub play_type: ELocalPlayType,
pub perform: ScenePerform,
}
impl FightScene {
pub fn get_protocol_scene_data(&self) -> trigger_protocol::SceneData {
pub fn get_protocol_scene_info(&self) -> trigger_protocol::SceneInfo {
use trigger_protocol::*;
SceneData {
SceneInfo {
scene_type: 3,
local_play_type: self.play_type.into(),
scene_id: self.scene_id,
event_id: self.event_id, // or maybe it's actually 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_data(&self) -> trigger_protocol::SceneData {
pub fn get_protocol_scene_info(&self) -> trigger_protocol::SceneInfo {
match self {
Self::Fight(scene) => scene.get_protocol_scene_data(),
Self::Rally(scene) => scene.get_protocol_scene_data(),
Self::Fight(scene) => scene.get_protocol_scene_info(),
Self::Rally(scene) => scene.get_protocol_scene_info(),
}
}
pub fn get_scene_id(&self) -> u32 {
pub fn get_event_id(&self) -> u32 {
match self {
Self::Fight(scene) => scene.scene_id,
Self::Rally(scene) => scene.scene_id,
Self::Fight(scene) => scene.event_id,
Self::Rally(scene) => scene.event_id,
}
}

View file

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

View file

@ -67,8 +67,8 @@ async fn on_change_game_state(
);
let enter_scene_notify = EnterSceneScNotify {
scene: Some(game_state.scene.get_protocol_scene_data()),
dungeon: Some(game_state.dungeon.get_protocol_dungeon_info()),
scene_info: Some(game_state.scene.get_protocol_scene_info()),
dungeon_info: Some(game_state.dungeon.get_protocol_dungeon_info()),
};
session.game_state = Some(game_state);

View file

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

View file

@ -13,7 +13,7 @@ area = 2
[bound_server]
name = "trigger_rs"
title = "Trigger-RS"
seed = "70fed6d1bdf76412"
seed = "789bd844f8c04bc3"
addr = "127.0.0.1"
port = 20501
is_kcp = false

View file

@ -1,7 +1,7 @@
use std::{collections::HashMap, net::SocketAddr};
use std::net::SocketAddr;
use serde::Deserialize;
use trigger_sv::config::{ConfigurationLoadError, TomlConfig};
use trigger_sv::config::TomlConfig;
#[derive(Deserialize)]
pub struct NetworkSetting {
@ -37,29 +37,6 @@ 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,11 +1,10 @@
use std::{
collections::HashMap,
process::ExitCode,
sync::{LazyLock, OnceLock},
};
use axum::{Router, routing::get};
use config::{DispatchConfig, ResVersionConfig};
use config::DispatchConfig;
use tokio::net::TcpListener;
use tracing::error;
use trigger_sv::{
@ -20,12 +19,11 @@ 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]
@ -43,16 +41,9 @@ 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()
@ -61,10 +52,11 @@ async fn main() -> ExitCode {
.route(query_gateway::ROUTE_ENDPOINT, get(query_gateway::process))
.with_state(state);
let listener = TcpListener::bind(CONFIG.network.http_addr).await.unwrap_or_else(|err| {
let Ok(listener) = TcpListener::bind(CONFIG.network.http_addr).await.inspect_err(|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

@ -30,15 +30,13 @@ 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(_, _) | Self::MissingResVersionConfig(_) => 75,
Self::InvalidDispatchSeed(_, _) => 75,
}
}
@ -73,7 +71,6 @@ impl IntoResponse for Response {
#[derive(Deserialize)]
pub struct QueryGatewayParam {
pub version: String,
pub rsa_ver: u32,
pub seed: String,
}
@ -121,13 +118,6 @@ 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 {
@ -150,22 +140,35 @@ 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(&res_version.design_data_url),
data_revision: Borrowed(&res_version.design_data_revision),
md5_files: Borrowed(&res_version.design_data_files),
base_url: Borrowed(
"https://autopatchcn.juequling.com/design_data/beta_live/output_7054632_323d17319c/client/",
),
data_revision: Borrowed("7054632"),
md5_files: Borrowed(
r#"[{"fileName": "data_version", "fileSize": 4503, "fileMD5": "419987357302147246"}]"#,
),
},
game_res: CdnGameRes {
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),
audio_revision: Borrowed("7025371"),
base_url: Borrowed(
"https://autopatchcn.juequling.com/game_res/beta_live/output_7054632_323d17319c/client/",
),
branch: Borrowed("beta_live"),
md5_files: Borrowed(
r#"[{"fileName": "res_version", "fileSize": 2379030, "fileMD5": "15840336186912297231"}, {"fileName": "audio_version", "fileSize": 30435, "fileMD5": "15675397132378459243"}, {"fileName": "base_revision", "fileSize": 18, "fileMD5": "18079377284431001248"}]"#,
),
res_revision: Borrowed("7054632"),
},
silence_data: CdnSilenceData {
base_url: Borrowed(&res_version.silence_url),
md5_files: Borrowed(&res_version.silence_files),
silence_revision: Borrowed(&res_version.silence_revision),
base_url: Borrowed(
"https://autopatchcn.juequling.com/design_data/beta_live/output_7054632_323d17319c/client_silence/",
),
md5_files: Borrowed(
r#"[{"fileName": "silence_version", "fileSize": 647, "fileMD5": "15019531890587528788"}]"#,
),
silence_revision: Borrowed("7042559"),
},
pre_download: None,
}),

View file

@ -1,3 +1,10 @@
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

@ -72,36 +72,9 @@ 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,7 +4,6 @@ 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,18 +101,7 @@ impl ItemModel {
.transaction::<_, (), DbErr>(|txn| {
Box::pin(async move {
for model in updated_models {
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?;
model.update(txn).await?;
}
Ok(())
@ -196,9 +185,3 @@ impl ItemModel {
.collect()
}
}
impl From<(u32, i32)> for MaterialDelta {
fn from((id, num): (u32, i32)) -> Self {
Self { id, num }
}
}

View file

@ -8,8 +8,8 @@ use role::RoleModel;
use scene::SceneModel;
use trigger_database::{DatabaseConnection, entity::*, prelude::*};
use trigger_fileconfig::NapFileCfg;
use trigger_logic::{scene::ESceneType, template_ext::TemplateExt};
use trigger_protocol::PlayerInfo;
use trigger_logic::scene::ESceneType;
use trigger_protocol::PlayerBasicInfo;
use trigger_sv::message::GameStateData;
use yorozuya::YorozuyaModel;
@ -62,8 +62,11 @@ impl NapPlayer {
player_uid,
};
let (player_basic_info, is_new_player) =
player_util::load_player_basic_info(database, player_uid, create_if_not_exists).await?;
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 role_model = RoleModel::init(context.clone()).await;
let item_model = ItemModel::init(context.clone()).await;
@ -92,28 +95,6 @@ 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 {
@ -125,31 +106,6 @@ 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();
@ -170,17 +126,15 @@ impl NapPlayer {
.expect("player_basic_info::update failed");
}
pub fn get_protocol_player_info(&self) -> PlayerInfo {
PlayerInfo {
pub fn get_protocol_player_basic_info(&self) -> PlayerBasicInfo {
PlayerBasicInfo {
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,
role_create_time: 0,
name_change_times: 1,
portrait_id: 0,
last_enter_world_timestamp: self.scene_model.last_enter_world_timestamp(),
}
}

View file

@ -32,10 +32,9 @@ fn create_default_player_basic_info(player_uid: i32) -> player_basic_info::Activ
nick_name: String::from("ReversedRooms"),
level: 60,
exp: 0,
avatar_id: 0,
player_avatar_id: 0,
control_avatar_id: 0,
beginner_procedure_id: 0,
avatar_id: 2021,
player_avatar_id: 2021,
control_avatar_id: 1361,
}
.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, template_ext::TemplateExt};
use trigger_logic::skill::EAvatarSkillType;
use trigger_protocol::{Avatar, AvatarSkillLevel, DressedEquip};
use trigger_sv::time_util;
@ -23,8 +23,6 @@ pub struct AvatarPropertyChanges {
}
impl RoleModel {
const PIDORS: &[i32] = &[1331, 1291];
pub async fn init(context: NapContext) -> Self {
let avatar_map = Self::load_or_create_avatar_map(&context).await;
@ -325,36 +323,6 @@ 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)
}
@ -362,7 +330,6 @@ impl RoleModel {
pub async fn unlock_avatars(&mut self, avatar_id_list: &[i32]) -> Vec<u32> {
let models = avatar_id_list
.iter()
.filter(|id| !Self::PIDORS.contains(*id))
.filter(|id| !self.is_avatar_unlocked(**id as u32))
.map(|id| {
self.context

View file

@ -138,6 +138,10 @@ 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

@ -1,22 +0,0 @@
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

@ -32,8 +32,7 @@ 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
{
@ -195,53 +194,4 @@ 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,4 +12,11 @@ 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

@ -93,30 +93,24 @@ mod client_systems_module {
PlayerOperationScRsp { retcode: 0 }
}
pub async fn on_get_system_settings(
pub async fn on_get_tips_info(
_context: &mut MessageContext<'_, '_>,
request: GetSystemSettingsCsReq,
) -> GetSystemSettingsScRsp {
GetSystemSettingsScRsp {
_request: GetTipsInfoCsReq,
) -> GetTipsInfoScRsp {
GetTipsInfoScRsp {
retcode: 0,
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(),
tips_info: Some(TipsInfo::default()),
}
}
pub async fn on_get_unlock_data(
pub async fn on_get_client_systems_data(
context: &mut MessageContext<'_, '_>,
_request: GetUnlockDataCsReq,
) -> GetUnlockDataScRsp {
GetUnlockDataScRsp {
_request: GetClientSystemsDataCsReq,
) -> GetClientSystemsDataScRsp {
GetClientSystemsDataScRsp {
retcode: 0,
data: Some(UnlockData {
unlock: Some(UnlockInfo {
data: Some(ClientSystemsData {
unlock_data: Some(UnlockData {
unlocked_list: context
.state
.filecfg
@ -128,7 +122,7 @@ mod client_systems_module {
.collect(),
..Default::default()
}),
post_girl: Some(PostGirlInfo {
post_girl_data: Some(PostGirlData {
post_girl_item_list: context
.state
.filecfg
@ -144,7 +138,7 @@ mod client_systems_module {
selected_post_girl_id_list: vec![3510028],
show_random_selected: false,
}),
music_player: Some(MusicPlayerInfo {
music_player_data: Some(MusicPlayerData {
music_list: context
.state
.filecfg
@ -159,7 +153,7 @@ mod client_systems_module {
})
.collect(),
}),
teleport: Some(TeleportUnlockInfo {
teleport_data: Some(TeleportData {
unlocked_list: context
.state
.filecfg
@ -187,14 +181,16 @@ mod client_systems_module {
pub async fn on_end_newbie(
_context: &mut MessageContext<'_, '_>,
request: EndNewbieCsReq,
_request: EndNewbieCsReq,
) -> EndNewbieScRsp {
debug!("EndNewbie({})", request.group_id);
EndNewbieScRsp { retcode: 0 }
}
EndNewbieScRsp {
retcode: 0,
group_id: 0,
}
pub async fn on_sync_global_variables(
_context: &mut MessageContext<'_, '_>,
_request: SyncGlobalVariablesCsReq,
) -> SyncGlobalVariablesScRsp {
SyncGlobalVariablesScRsp { retcode: 0 }
}
pub async fn on_get_trashbin_hermit_data(

View file

@ -0,0 +1,35 @@
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

@ -0,0 +1,15 @@
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

@ -0,0 +1,12 @@
use super::MessageContext;
use trigger_codegen::handlers;
#[handlers]
mod flower_shop_module {
pub async fn on_get_flower_shop_data(
_context: &mut MessageContext<'_, '_>,
_request: GetFlowerShopDataCsReq,
) -> GetFlowerShopDataScRsp {
GetFlowerShopDataScRsp { retcode: 0 }
}
}

View file

@ -13,7 +13,7 @@ modules! {
quest,
abyss,
bangboo,
system,
client_systems,
gacha,
mail,
ramen,
@ -22,10 +22,10 @@ modules! {
reward_buff,
arcade,
daily_challenge,
tips,
fairy,
activity,
land_revive,
workbench,
collections,
perform,
battle_event,
vhs_store,
@ -39,9 +39,9 @@ modules! {
camp_idle,
miniscape_entrust,
fishing_contest,
qa_game,
ridus_got_boo,
training
qa_game,
flower_shop
}
client_message_forwarding! {

View file

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

View file

@ -75,6 +75,35 @@ 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,29 +4,11 @@ use trigger_codegen::handlers;
#[handlers]
mod scene_module {
use tracing::debug;
use trigger_logic::scene::{ELocalPlayType, ESceneType};
use trigger_sv::{
message::{AvailableServerProtocolMessage, GameStateData},
net::ServerType,
};
use trigger_logic::scene::ESceneType;
use crate::logic::{dungeon_util, scene::ServerlessStateData, scene_util};
use crate::logic::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 {
@ -41,6 +23,7 @@ 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
@ -105,35 +88,6 @@ 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,
@ -165,104 +119,6 @@ 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

@ -1,32 +0,0 @@
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

@ -1,19 +0,0 @@
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

@ -1,45 +0,0 @@
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::{NapPlayer, scene::ServerlessStateData, scene_util};
use crate::logic::{NapPlayer, scene_util};
pub mod message;
@ -50,31 +50,6 @@ 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

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

View file

@ -11,7 +11,6 @@ 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

@ -14,7 +14,6 @@ pub mod prelude {
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

@ -395,15 +395,6 @@ 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];
@ -558,33 +549,6 @@ table EquipmentLevelTemplate {
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];
}
@ -657,10 +621,6 @@ table ConditionConfigTemplateTb {
data: [ConditionConfigTemplate];
}
table ProcedureConfigTemplateTb {
data: [ProcedureConfigTemplate];
}
table AvatarBattleTemplateTb {
data: [AvatarBattleTemplate];
}
@ -683,8 +643,4 @@ table AvatarPassiveSkillTemplateTb {
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, non_snake_case)]
#[allow(dead_code, unused_imports, unsafe_op_in_unsafe_fn)]
#[path = "../gen_flatbuffers/tables_generated.rs"]
mod data;
pub mod main_city_script;
@ -45,7 +45,6 @@ file_cfg! {
WeaponTemplateTb;
EquipmentTemplateTb;
EquipmentSuitTemplateTb;
ProcedureConfigTemplateTb;
UnlockConfigTemplateTb;
PostGirlConfigTemplateTb;
ArchiveFileQuestTemplateTb;
@ -65,5 +64,4 @@ file_cfg! {
WeaponStarTemplateTb;
AvatarPassiveSkillTemplateTb;
EquipmentLevelTemplateTb;
AvatarSkinBaseTemplateTb;
}

View file

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

View file

@ -4,4 +4,3 @@ pub mod item;
pub mod quest;
pub mod scene;
pub mod skill;
pub mod template_ext;

View file

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

View file

@ -1,53 +0,0 @@
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
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@ include!("../out/_.rs");
include!("../out/protocol_map.rs");
#[derive(trigger_protobuf_derive::CmdID)]
#[cmdid(8128)]
#[cmdid(5636)]
#[derive(trigger_protobuf_derive::XorFields, Clone, Copy, PartialEq, ::prost::Message)]
pub struct FallbackRsp {}

View file

@ -30,26 +30,24 @@ where
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1)]
pub struct GetPlayerInfoCsReq {}
pub struct GetPlayerBasicInfoCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PlayerInfo {
pub struct PlayerBasicInfo {
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 GetPlayerInfoScRsp {
pub struct GetPlayerBasicInfoScRsp {
pub retcode: i32,
pub player_info: Option<PlayerInfo>,
pub basic_info: Option<PlayerBasicInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -85,18 +83,6 @@ 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 {
@ -159,7 +145,7 @@ pub struct CafeSync {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(100)]
pub struct PlayerSyncScNotify {
pub player_info: Option<PlayerInfo>,
pub basic_info: Option<PlayerBasicInfo>,
pub avatar_sync: Option<AvatarSync>,
pub item_sync: Option<ItemSync>,
pub ramen_sync: Option<RamenSync>,
@ -275,13 +261,12 @@ pub struct Transform {
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct SceneData {
pub struct SceneInfo {
pub scene_type: u32,
pub scene_id: u32,
pub event_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>,
}
@ -335,11 +320,6 @@ 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,
@ -413,8 +393,8 @@ pub struct EnterWorldScRsp {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(452)]
pub struct EnterSceneScNotify {
pub scene: Option<SceneData>,
pub dungeon: Option<DungeonInfo>,
pub scene_info: Option<SceneInfo>,
pub dungeon_info: Option<DungeonInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -579,59 +559,6 @@ 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)]
@ -769,7 +696,7 @@ pub struct GetPrivateMessageDataScRsp {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(640)]
pub struct EnterTrainingRoomCsReq {
pub struct BeginTrainingCourseBattleCsReq {
pub quest_id: u32,
pub buddy_id: u32,
pub avatar_id_list: Vec<u32>,
@ -777,7 +704,7 @@ pub struct EnterTrainingRoomCsReq {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(641)]
pub struct EnterTrainingRoomScRsp {
pub struct BeginTrainingCourseBattleScRsp {
pub retcode: i32,
}
@ -1052,31 +979,6 @@ 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)]
@ -1151,7 +1053,7 @@ pub struct EatRamenScRsp {
// Client systems
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct UnlockInfo {
pub struct UnlockData {
pub unlocked_list: Vec<i32>,
}
@ -1162,7 +1064,7 @@ pub struct PostGirlItem {
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct PostGirlInfo {
pub struct PostGirlData {
pub post_girl_item_list: Vec<PostGirlItem>,
pub selected_post_girl_id_list: Vec<u32>,
pub show_random_selected: bool,
@ -1176,61 +1078,21 @@ pub struct MusicPlayerItem {
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct MusicPlayerInfo {
pub struct MusicPlayerData {
pub music_list: Vec<MusicPlayerItem>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct TeleportUnlockInfo {
pub struct TeleportData {
pub unlocked_list: Vec<i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
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>,
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>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1259,35 +1121,27 @@ pub struct SavePlayerSystemSettingScRsp {
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1305)]
pub struct GetSystemSettingsCsReq {
pub r#type: u32,
}
pub struct GetTipsInfoCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct SystemSettings {
pub systems: Vec<u32>,
pub switch_of_story_mode: bool,
pub switch_of_qte: bool,
}
pub struct TipsInfo {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1306)]
pub struct GetSystemSettingsScRsp {
pub struct GetTipsInfoScRsp {
pub retcode: i32,
pub r#type: u32,
pub settings: Option<SystemSettings>,
pub player_settings_map: HashMap<u32, u32>,
pub tips_info: Option<TipsInfo>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1307)]
pub struct GetUnlockDataCsReq {}
pub struct GetClientSystemsDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1308)]
pub struct GetUnlockDataScRsp {
pub struct GetClientSystemsDataScRsp {
pub retcode: i32,
pub data: Option<UnlockData>,
pub data: Option<ClientSystemsData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1379,7 +1233,18 @@ pub struct EndNewbieCsReq {
#[id(1324)]
pub struct EndNewbieScRsp {
pub retcode: i32,
pub group_id: u32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1325)]
pub struct SyncGlobalVariablesCsReq {
pub global_variables: HashMap<u32, i32>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1326)]
pub struct SyncGlobalVariablesScRsp {
pub retcode: i32,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1460,47 +1325,20 @@ pub struct GetDailyChallengeDataScRsp {
pub data: Option<DailyChallengeData>,
}
// Tips
// Fairy
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1601)]
pub struct GetTipsDataCsReq {}
pub struct GetFairyDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
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>,
}
pub struct FairyData {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(1602)]
pub struct GetTipsDataScRsp {
pub struct GetFairyDataScRsp {
pub retcode: i32,
pub data: Option<TipsData>,
pub data: Option<FairyData>,
}
// Activity
@ -1573,62 +1411,34 @@ pub struct GetMainCityRevivalDataScRsp {
pub main_city_revival_data: Option<MainCityRevivalData>,
}
// Workbench
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2000)]
pub struct GetWorkbenchDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
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)]
pub struct WorkbenchData {
pub workbench_app_list: Vec<u32>,
pub clue_data: Option<ClueData>,
}
// Collections
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2001)]
pub struct GetWorkbenchDataScRsp {
pub retcode: i32,
pub workbench_data: Option<WorkbenchData>,
}
pub struct GetCollectMapCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable)]
pub struct CollectMap {}
#[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 struct GetCollectMapScRsp {
pub retcode: i32,
pub collect_map: Option<CollectMap>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2010)]
pub struct GetPartnerDataCsReq {}
#[id(2021)]
pub struct WorkbenchGetDataCsReq {}
#[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>,
}
pub struct WorkbenchData {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(2011)]
pub struct GetPartnerDataScRsp {
#[id(2022)]
pub struct WorkbenchGetDataScRsp {
pub retcode: i32,
pub partner_data: Option<PartnerData>,
pub workbench_data: Option<WorkbenchData>,
}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
@ -1719,20 +1529,6 @@ 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)]
@ -1749,6 +1545,18 @@ 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)]
@ -1974,3 +1782,15 @@ pub struct GetQuestionsAnswerGameDataCsReq {}
pub struct GetQuestionsAnswerGameDataScRsp {
pub retcode: i32,
}
// FlowerShop
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(7150)]
pub struct GetFlowerShopDataCsReq {}
#[derive(Default, Debug, Clone, Encodeable, Decodeable, ClientCmdID)]
#[id(7151)]
pub struct GetFlowerShopDataScRsp {
pub retcode: i32,
}

View file

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

View file

@ -30,7 +30,7 @@ user = "root"
password = "root"
[security]
static_key = "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"
static_key = "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"
[[security.rsa_versions]]
version = 3

View file

@ -1,13 +0,0 @@
["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"}]'