From fcd356e7bfe9bc5a676d67fe35afb3c34e55e6b0 Mon Sep 17 00:00:00 2001 From: Nobody Date: Sun, 22 May 2022 17:46:50 +0500 Subject: [PATCH] A bunch of stuff for 2.7.50. With some workarounds it's now possible to play. --- src/dbmanager/database_manager.rs | 1 - src/server/auth_manager.rs | 4 ++-- src/server/dispatch_server.rs | 30 ++++++++++++++++-------------- src/server/game_world.rs | 18 ++++++++++++------ src/server/login_manager.rs | 2 ++ src/utils/avatar_builder.rs | 7 +++++++ src/utils/id_manager.rs | 4 ++++ 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/dbmanager/database_manager.rs b/src/dbmanager/database_manager.rs index 35b931f..411274f 100644 --- a/src/dbmanager/database_manager.rs +++ b/src/dbmanager/database_manager.rs @@ -1082,7 +1082,6 @@ impl DatabaseManager { pub const SPOOFED_AVATAR_ID: u32 = 1; pub const SPOOFED_WEAPON_ID: u32 = 2; const SPOOFED_SCENE_ID: u32 = 3; // TODO: that's a different kind of ID! - pub const SPOOFED_TEAM_ID: u32 = 4; pub const SPOOFED_MP_LEVEL_ID: u32 = 5; const SPOOFED_SCENE_TOKEN: u32 = 0x1234; } diff --git a/src/server/auth_manager.rs b/src/server/auth_manager.rs index e14138a..20d0918 100644 --- a/src/server/auth_manager.rs +++ b/src/server/auth_manager.rs @@ -38,8 +38,8 @@ impl AuthManager { rsp.account_type = req.account_type; rsp.account_uid = req.account_uid.clone(); - rsp.token = format!("token-game-{}", req.account_uid); - rsp.secret_key_seed = seed; + rsp.token = req.account_token.clone(); + rsp.secret_key_seed = 0;//seed; // TODO: temporary workaround! rsp.uid = uid; self.conv_to_user.insert(conv, uid); diff --git a/src/server/dispatch_server.rs b/src/server/dispatch_server.rs index 53da2cd..8a0d6b3 100644 --- a/src/server/dispatch_server.rs +++ b/src/server/dispatch_server.rs @@ -38,12 +38,12 @@ pub struct DispatchServer {} // Keys stuff #[derive(Deserialize,Debug)] -struct KeyInfo { - key_id: u8, - #[serde(deserialize_with = "deserialize_pub_key")] - public_key: Rsa, +pub struct KeyInfo { + pub key_id: u8, #[serde(deserialize_with = "deserialize_priv_key")] - private_key: Rsa, + pub encrypt_key: Rsa, + #[serde(deserialize_with = "deserialize_priv_key")] + pub signing_key: Rsa, } fn deserialize_pub_key<'de, D>(deserializer: D) -> Result, D::Error> @@ -317,16 +317,18 @@ impl DispatchServer { None => panic!("Unknown key ID {}!", key_id), }; - let mut out_buf: Vec = Vec::new(); - let mut enc_buf: Vec = vec![0; keys.public_key.size() as usize]; + const key_size: usize = 256; // TODO: hardcoded constant! - for chunk in region_conf_buf.chunks((keys.public_key.size() - 11) as usize) { // TODO: value hardcoded for the PKCS1 v1.5! - let len = keys.private_key.public_encrypt(chunk, &mut enc_buf, Padding::PKCS1).unwrap(); - out_buf.append(&mut enc_buf); - enc_buf.resize(keys.public_key.size() as usize, 0); + let mut out_buf: Vec = Vec::new(); + let mut enc_buf: Vec = vec![0; key_size]; + + for chunk in region_conf_buf.chunks((key_size - 11) as usize) { // TODO: value hardcoded for the PKCS1 v1.5! + let len = keys.encrypt_key.public_encrypt(chunk, &mut enc_buf, Padding::PKCS1).unwrap(); + out_buf.append(&mut enc_buf[0..len].to_vec()); + enc_buf.resize(key_size, 0); } - let keypair = PKey::from_rsa(keys.private_key.clone()).unwrap(); // TODO: this is not a correct private key! + let keypair = PKey::from_rsa(keys.signing_key.clone()).unwrap(); let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap(); let signature = signer.sign_oneshot_to_vec(®ion_conf_buf).unwrap(); @@ -658,7 +660,7 @@ impl DispatchServer { } async fn log_skip(body: web::Bytes) -> String { - //println!("Logging: {}", std::str::from_utf8(&body).unwrap()); + println!("Logging: {}", std::str::from_utf8(&body).unwrap()); return "{}".to_string(); } @@ -704,7 +706,7 @@ impl DispatchServer { return "127.0.0.1".to_string(); } - fn load_rsa_keys(name: &str) -> HashMap { + pub fn load_rsa_keys(name: &str) -> HashMap { // Key depo let path = format!("./{}/{}.json", "keys", name); let json_file_path = Path::new(&path); diff --git a/src/server/game_world.rs b/src/server/game_world.rs index d5732a9..66cd2b0 100644 --- a/src/server/game_world.rs +++ b/src/server/game_world.rs @@ -80,8 +80,8 @@ impl GameWorld { } fn process_scene_init_finish(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::SceneInitFinishReq, rsp: &mut proto::SceneInitFinishRsp) { - let current_avatar_guid = match self.db.get_player_team_selection(user_id) { - Some(team_selection) => team_selection.avatar, + let (current_avatar_guid, current_team_id) = match self.db.get_player_team_selection(user_id) { + Some(team_selection) => (team_selection.avatar, team_selection.team), None => panic!("Team selection info not found for user {}!", user_id), }; @@ -110,13 +110,15 @@ impl GameWorld { uid: user_id, nickname: user.nick_name.clone(), player_level: user_level, - avatar_id: user.avatar_id, + avatar_id: user.avatar_id, // TODO: this is deprecated in current game versions, profile_picture is used instead mp_setting_type: proto::MpSettingType::MpSettingEnterAfterApply as i32, // TODO! cur_player_num_in_world: 1, // TODO! world_level: world_level, name_card_id: user.namecard_id, signature: user.signature.clone(), - // TODO: Field 12! + profile_picture: Some(build!(ProfilePicture { + avatar_id: user.avatar_id, + })), }); build_and_send!(self, user_id, metadata, WorldPlayerInfoNotify { @@ -150,7 +152,7 @@ impl GameWorld { ability_info: Some(build!(AbilitySyncStateInfo {})), }); let team_enter_info = build!(TeamEnterSceneInfo { - team_entity_id: IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityTeam, DatabaseManager::SPOOFED_TEAM_ID), // TODO + team_entity_id: IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityTeam, current_team_id as u32), team_ability_info: Some(build!(AbilitySyncStateInfo {})), ability_control_block: Some(build!(AbilityControlBlock {})), }); @@ -190,8 +192,10 @@ impl GameWorld { player_uid: user_id, avatar_guid: current_avatar_guid as u64, // FIXME entity_id: IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityAvatar, DatabaseManager::SPOOFED_AVATAR_ID), + avatar_ability_info: Some(build!(AbilitySyncStateInfo {})), weapon_guid: IdManager::get_guid_by_uid_and_id(user_id, DatabaseManager::SPOOFED_WEAPON_ID), weapon_entity_id: IdManager::get_entity_id_by_type_and_sub_id(&proto::ProtEntityType::ProtEntityWeapon, DatabaseManager::SPOOFED_WEAPON_ID), + weapon_ability_info: Some(build!(AbilitySyncStateInfo {})), is_player_cur_avatar: true, // TODO scene_entity_info: Some(self.spoof_scene_default_avatar(user_id)), ability_control_block: Some(self.spoof_default_abilities()), @@ -271,6 +275,7 @@ impl GameWorld { equip_id_list: vec![11406], // TODO weapon: Some(weapon), wearing_flycloak_id: 140001, // TODO + excel_info: avatar_info.excel_info.clone(), }); let scene_ai_info = build!(SceneEntityAiInfo { @@ -288,6 +293,7 @@ impl GameWorld { fight_prop_list: Remapper::remap3(¤t_avatar_fight_props), motion_info: Some(motion_info), entity_authority_info: Some(authority_info), + entity_client_data: Some(build!(EntityClientData {})), animator_para_list: vec![build!(AnimatorParameterValueInfoPair { name_id: 0, // TODO: unknown! animator_para: Some(build!(AnimatorParameterValueInfo {})), @@ -342,7 +348,7 @@ impl GameWorld { for (key, value) in map { let mut emb = proto::AbilityEmbryo::default(); - //emb.ability_id = key; // TODO: ability IDs should be PRECISE or LEFT OUT completely! + emb.ability_id = key; emb.ability_name_hash = value; emb.ability_override_name_hash = 0x463810D9; ability_list.push(emb); diff --git a/src/server/login_manager.rs b/src/server/login_manager.rs index b82c227..ce30de3 100644 --- a/src/server/login_manager.rs +++ b/src/server/login_manager.rs @@ -115,6 +115,8 @@ impl LoginManager { owned_flycloak_list: vec![140001], // TODO! }); + build_and_send!(self, user_id, metadata, CoopDataNotify { }); + let pos = luamanager::Vector {x: scene_info.pos_x, y: scene_info.pos_y, z: scene_info.pos_z}; self.em.player_teleported(user_id, pos, scene_info.scene_id, scene_info.scene_token, &proto::EnterType::EnterSelf); diff --git a/src/utils/avatar_builder.rs b/src/utils/avatar_builder.rs index 92b45d3..dfa8d87 100644 --- a/src/utils/avatar_builder.rs +++ b/src/utils/avatar_builder.rs @@ -84,6 +84,13 @@ impl AvatarBuilder { proud_skill_extra_level_map: fuck, //collection!{739 => 3, 732 => 3}, wearing_flycloak_id: 140001, // TODO: hack! life_state: 1, + excel_info: Some(build!(AvatarExcelInfo { // TODO: load values from config! + prefab_path_hash: IdManager::get_hash_by_prefix_suffix(50, 2568507538), + prefab_path_remote_hash: IdManager::get_hash_by_prefix_suffix(158, 3204428759), + controller_path_hash: IdManager::get_hash_by_prefix_suffix(154, 3376713903), + controller_path_remote_hash: IdManager::get_hash_by_prefix_suffix(228, 1479775384), + combat_config_hash: IdManager::get_hash_by_prefix_suffix(244, 4049143033), + })), }); return ai; } diff --git a/src/utils/id_manager.rs b/src/utils/id_manager.rs index a3d0cb8..e4804d0 100644 --- a/src/utils/id_manager.rs +++ b/src/utils/id_manager.rs @@ -50,4 +50,8 @@ impl IdManager { pub fn get_guid_by_uid_and_id(uid: u32, id: u32) -> u64 { return (((uid as u64) << 32) | (id as u64)); } + + pub fn get_hash_by_prefix_suffix(prefix: u8, suffix: u32) -> u64 { + ((prefix as u64) << 32) | (suffix as u64) + } }