Compare commits

..

No commits in common. "master" and "0.1.0" have entirely different histories.

22 changed files with 399 additions and 14881 deletions

View file

@ -46,8 +46,7 @@ start sdkserver.exe
Get GI 4.5.0 client from somewhere, Get GI 4.5.0 client from somewhere,
put patch [version.dll](https://git.xeondev.com/reversedrooms/hk4e-patch/releases/download/0.1.0/version.dll) put patch [version.dll](https://git.xeondev.com/reversedrooms/hk4e-patch/releases/download/0.1.0/version.dll)
file in your game folder, it will redirect game traffic and patch cryptography. file in your game folder, it will redirect game traffic and patch cryptography
Replace [mihoyonet.dll](https://autopatchhk.yuanshen.com/client_app/download/pc_zip/20231030132335_iOEfPMcbrXpiA8Ca/ScatteredFiles/GenshinImpact_Data/Plugins/mihoyonet.dll) in `GenshinImpact_Data\Plugins`
## Contributing ## Contributing

View file

@ -1,123 +0,0 @@
[
{
"flycloakId": 140001,
"nameTextMapHash": 1227437700,
"descTextMapHash": 2963284368,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Glider_01/Flycloak_Normal_Glider_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Glider",
"materialId": 140001
},
{
"flycloakId": 140002,
"nameTextMapHash": 3679998556,
"descTextMapHash": 2439760640,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Starlit_01/Flycloak_Normal_Starlit_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Starlit",
"materialId": 140002
},
{
"flycloakId": 140003,
"nameTextMapHash": 1307041812,
"descTextMapHash": 251460624,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Psalmus_01/Flycloak_Normal_Psalmus_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Psalmus",
"materialId": 140003
},
{
"flycloakId": 140004,
"nameTextMapHash": 3265724196,
"descTextMapHash": 95448472,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Gale_01/Flycloak_Normal_Gale_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Gale",
"materialId": 140004
},
{
"flycloakId": 140005,
"nameTextMapHash": 1800191236,
"descTextMapHash": 397410296,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Megalith_01/Flycloak_Normal_Megalith_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Megalith",
"materialId": 140005
},
{
"flycloakId": 140006,
"nameTextMapHash": 790364508,
"descTextMapHash": 2419069352,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Nixavis_01/Flycloak_Normal_Nixavis_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Nixavis",
"materialId": 140006
},
{
"flycloakId": 140007,
"nameTextMapHash": 972574812,
"descTextMapHash": 3582594568,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Redcomet_01/Flycloak_Normal_Redcomet_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Redcomet",
"materialId": 140007,
"hide": true
},
{
"flycloakId": 140008,
"nameTextMapHash": 1047777100,
"descTextMapHash": 533901256,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Thunderclap_01/Flycloak_Normal_Thunderclap_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Thunderclap",
"materialId": 140008
},
{
"flycloakId": 140009,
"nameTextMapHash": 14389020,
"descTextMapHash": 3075333936,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Skald_01/Flycloak_Normal_Skald_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Skald",
"materialId": 140009,
"hide": true
},
{
"flycloakId": 140010,
"nameTextMapHash": 2488969468,
"descTextMapHash": 1899653016,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Ayus_01/Flycloak_Normal_Ayus_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Ayus",
"materialId": 140010
},
{
"flycloakId": 140011,
"nameTextMapHash": 2292890772,
"descTextMapHash": 681143304,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Asterceno_01/Flycloak_Normal_Asterceno_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Asterceno",
"materialId": 140011,
"hide": true
},
{
"flycloakId": 140012,
"nameTextMapHash": 180645420,
"descTextMapHash": 1161581424,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Iustitia_01/Flycloak_Normal_Iustitia_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Iustitia",
"materialId": 140012
},
{
"flycloakId": 140013,
"nameTextMapHash": 2462291164,
"descTextMapHash": 1830391744,
"prefabPath": "ART/System/Flycloak/Flycloak_Normal_Sternlied_01/Flycloak_Normal_Sternlied_01",
"jsonName": "Flycloak_Default_01",
"icon": "UI_Gacha_FlycloakIcon_Sternlied",
"materialId": 140013,
"hide": true
}
]

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -37,89 +37,6 @@ pub struct AvatarExcelConfig {
pub lodpattern_name: String, pub lodpattern_name: String,
} }
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct AvatarCostumeExcelConfig {
pub skin_id: u32,
#[serde(rename = "indexID")]
pub index_id: u32,
pub name_text_map_hash: u64,
pub desc_text_map_hash: u64,
pub item_id: u32,
pub character_id: u32,
pub json_name: String,
pub prefab_path_hash: u64,
pub prefab_remote_path_hash: u64,
pub prefab_npc_path_hash: u64,
pub prefab_manekin_path_hash: u64,
pub quality: u32,
pub front_icon_name: String,
pub side_icon_name: String,
pub image_name_hash: u64,
}
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct AvatarFlycloakExcelConfig {
pub flycloak_id: u32,
pub name_text_map_hash: u64,
pub desc_text_map_hash: u64,
pub prefab_path: String,
pub json_name: String,
pub icon: String,
pub material_id: u32,
}
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct WeaponExcelConfig {
pub weapon_type: String,
pub rank_level: u32,
pub weapon_base_exp: u32,
pub skill_affix: Vec<u32>,
pub weapon_prop: Vec<WeaponProp>,
pub awaken_texture: String,
pub awaken_light_map_texture: String,
pub awaken_icon: String,
pub weapon_promote_id: u32,
pub story_id: u32,
pub awaken_costs: Vec<u32>,
pub gacha_card_name_hash: u64,
pub destroy_rule: String,
pub destroy_return_material: Vec<u32>,
pub destroy_return_material_count: Vec<u32>,
pub id: u32,
pub name_text_map_hash: u64,
pub desc_text_map_hash: u64,
pub icon: String,
pub item_type: String,
pub weight: u32,
pub rank: u32,
pub gadget_id: u32,
}
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct WeaponProp {
pub prop_type: String,
pub init_value: f32,
#[serde(rename = "type")]
pub type_field: String,
}
#[derive(Deserialize, Default)]
#[serde(default)]
#[serde(rename_all = "camelCase")]
pub struct OpenStateConfig {
pub id: u32,
pub default_state: bool,
pub allow_client_open: bool,
}
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PropGrowCurve { pub struct PropGrowCurve {

View file

@ -20,10 +20,6 @@ lazy_static! {
pub struct ExcelCollection { pub struct ExcelCollection {
pub avatar_configs: Vec<AvatarExcelConfig>, pub avatar_configs: Vec<AvatarExcelConfig>,
pub avatar_flycloak_configs: Vec<AvatarFlycloakExcelConfig>,
pub avatar_costume_configs: Vec<AvatarCostumeExcelConfig>,
pub weapon_configs: Vec<WeaponExcelConfig>,
pub open_state_configs: Vec<OpenStateConfig>,
} }
pub struct GameConfigCollection { pub struct GameConfigCollection {
@ -37,27 +33,11 @@ impl ExcelCollection {
"assets/ExcelBinOutput/AvatarExcelConfigData.json", "assets/ExcelBinOutput/AvatarExcelConfigData.json",
)) ))
.unwrap(), .unwrap(),
avatar_flycloak_configs: from_str(&load_asset(
"assets/ExcelBinOutput/AvatarFlycloakExcelConfigData.json",
))
.unwrap(),
avatar_costume_configs: from_str(&load_asset(
"assets/ExcelBinOutput/AvatarCostumeExcelConfigData.json",
))
.unwrap(),
weapon_configs: from_str(&load_asset(
"assets/ExcelBinOutput/WeaponExcelConfigData.json",
))
.unwrap(),
open_state_configs: from_str(&load_asset(
"assets/ExcelBinOutput/OpenStateConfigData.json",
))
.unwrap(),
} }
} }
pub fn table_count(&self) -> usize { pub fn table_count(&self) -> usize {
5 1
} }
} }

View file

@ -1,5 +1,11 @@
use proto::Vector; use proto::Vector;
pub static OPEN_STATES: [u32; 58] = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 27, 28, 29, 30, 31, 32, 33, 37, 38, 45, 47,
53, 54, 55, 59, 62, 65, 900, 901, 902, 903, 1001, 1002, 1003, 1004, 1005, 1007, 1008, 1009,
1010, 1100, 1103, 1300, 1401, 1403, 1700, 2100, 2101, 2103, 2400, 3701, 3702, 4100,
];
pub static INITIAL_POS: Vector = Vector { pub static INITIAL_POS: Vector = Vector {
x: 2336.789, x: 2336.789,
y: 249.98996, y: 249.98996,

View file

@ -3,7 +3,7 @@ use proto::*;
use super::*; use super::*;
use crate::{ use crate::{
data, data,
game::{AvatarData, WeaponData}, game::{constants, AvatarData},
util, util,
}; };
@ -11,16 +11,14 @@ pub struct SceneAvatar {
data: AvatarData, data: AvatarData,
weapon: SceneWeapon, weapon: SceneWeapon,
entity_id: u32, entity_id: u32,
pos: Vector,
} }
impl SceneAvatar { impl SceneAvatar {
pub fn new(id: u32, data: AvatarData, weapon: SceneWeapon, pos: Vector) -> Self { pub fn new(id: u32, data: AvatarData, weapon: SceneWeapon) -> Self {
Self { Self {
data, data,
weapon, weapon,
entity_id: calc_entity_id(id, ProtEntityType::ProtEntityAvatar), entity_id: calc_entity_id(id, ProtEntityType::ProtEntityAvatar),
pos,
} }
} }
@ -29,14 +27,6 @@ impl SceneAvatar {
self.data.clone() self.data.clone()
} }
pub fn update_data(&mut self, data: &AvatarData) {
self.data = AvatarData {
properties: self.data.properties.clone(),
fight_properties: self.data.fight_properties.clone(),
..data.clone()
};
}
pub fn avatar_guid(&self) -> u64 { pub fn avatar_guid(&self) -> u64 {
self.data.guid self.data.guid
} }
@ -61,10 +51,6 @@ impl SceneAvatar {
} }
} }
pub fn change_weapon(&mut self, weapon: WeaponData) {
self.weapon = SceneWeapon::new(self.weapon.get_entity_id(), weapon);
}
pub fn ability_control_block(&self) -> AbilityControlBlock { pub fn ability_control_block(&self) -> AbilityControlBlock {
let mut control_block = AbilityControlBlock::default(); let mut control_block = AbilityControlBlock::default();
@ -99,11 +85,7 @@ impl SceneAvatar {
impl Entity for SceneAvatar { impl Entity for SceneAvatar {
fn get_position(&self) -> Vector { fn get_position(&self) -> Vector {
self.pos.clone() constants::INITIAL_POS.clone()
}
fn set_position(&mut self, pos: Vector) {
self.pos = pos
} }
fn get_entity_id(&self) -> u32 { fn get_entity_id(&self) -> u32 {
@ -148,7 +130,6 @@ impl Entity for SceneAvatar {
skill_depot_id: self.data.skill_depot_id, skill_depot_id: self.data.skill_depot_id,
weapon: Some(self.weapon.scene_weapon_info()), weapon: Some(self.weapon.scene_weapon_info()),
team_resonance_list: vec![10301], team_resonance_list: vec![10301],
costume_id: self.data.costume_id,
wearing_flycloak_id: self.data.wearing_flycloak_id, wearing_flycloak_id: self.data.wearing_flycloak_id,
born_time: self.data.born_time, born_time: self.data.born_time,
excel_info: Some(AvatarExcelInfo::default()), excel_info: Some(AvatarExcelInfo::default()),

View file

@ -8,7 +8,6 @@ pub use weapon::SceneWeapon;
pub trait Entity { pub trait Entity {
fn get_position(&self) -> Vector; fn get_position(&self) -> Vector;
fn set_position(&mut self, pos: Vector);
fn get_entity_id(&self) -> u32; fn get_entity_id(&self) -> u32;
fn get_entity_type(&self) -> ProtEntityType; fn get_entity_type(&self) -> ProtEntityType;
fn info(&self) -> SceneEntityInfo; fn info(&self) -> SceneEntityInfo;

View file

@ -44,8 +44,6 @@ impl Entity for SceneWeapon {
Vector::default() Vector::default()
} }
fn set_position(&mut self, _pos: Vector) {}
fn get_entity_id(&self) -> u32 { fn get_entity_id(&self) -> u32 {
self.entity_id self.entity_id
} }

View file

@ -7,7 +7,6 @@ pub struct PlayerInfo {
pub uid: u32, pub uid: u32,
pub guid_manager: GUIDManager, pub guid_manager: GUIDManager,
pub avatars: Vec<AvatarData>, pub avatars: Vec<AvatarData>,
pub weapons: Vec<WeaponData>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -16,7 +15,6 @@ pub struct AvatarData {
pub avatar_id: u32, pub avatar_id: u32,
pub skill_depot_id: u32, pub skill_depot_id: u32,
pub wearing_flycloak_id: u32, pub wearing_flycloak_id: u32,
pub costume_id: u32,
pub born_time: u32, pub born_time: u32,
pub weapon: WeaponData, pub weapon: WeaponData,
pub properties: Vec<PropValue>, pub properties: Vec<PropValue>,
@ -36,7 +34,6 @@ impl PlayerInfo {
uid: 1337, uid: 1337,
guid_manager: GUIDManager::new(), guid_manager: GUIDManager::new(),
avatars: Vec::new(), avatars: Vec::new(),
weapons: Vec::new(),
} }
} }
@ -44,34 +41,22 @@ impl PlayerInfo {
self.guid_manager.next() self.guid_manager.next()
} }
pub fn unlock_all_weapons(&mut self) {
self.weapons
.extend(EXCEL_COLLECTION.weapon_configs.iter().map(|w| WeaponData {
weapon_id: w.id,
guid: self.guid_manager.next(),
}));
}
pub fn unlock_all_avatars(&mut self) { pub fn unlock_all_avatars(&mut self) {
for config in EXCEL_COLLECTION for config in EXCEL_COLLECTION
.avatar_configs .avatar_configs
.iter() .iter()
.filter(|c| !DISABLED_AVATAR_LIST.contains(&c.id)) .filter(|c| !DISABLED_AVATAR_LIST.contains(&c.id))
{ {
let weapon = WeaponData {
weapon_id: config.initial_weapon,
guid: self.next_guid(),
};
self.weapons.push(weapon.clone());
let mut data = AvatarData { let mut data = AvatarData {
guid: self.next_guid(), guid: self.next_guid(),
avatar_id: config.id, avatar_id: config.id,
skill_depot_id: config.skill_depot_id, skill_depot_id: config.skill_depot_id,
wearing_flycloak_id: 140001, wearing_flycloak_id: 140001,
costume_id: 0,
born_time: util::cur_timestamp() as u32, born_time: util::cur_timestamp() as u32,
weapon, weapon: WeaponData {
guid: self.next_guid(),
weapon_id: config.initial_weapon,
},
properties: Vec::new(), properties: Vec::new(),
fight_properties: Vec::new(), fight_properties: Vec::new(),
}; };
@ -169,22 +154,6 @@ impl AvatarData {
} }
} }
impl From<WeaponData> for Item {
fn from(value: WeaponData) -> Self {
Self {
item_id: value.weapon_id,
guid: value.guid,
detail: Some(item::Detail::Equip(Equip {
is_locked: false,
detail: Some(equip::Detail::Weapon(Weapon {
level: 1,
..Default::default()
})),
})),
}
}
}
impl From<AvatarData> for AvatarInfo { impl From<AvatarData> for AvatarInfo {
fn from(value: AvatarData) -> Self { fn from(value: AvatarData) -> Self {
Self { Self {
@ -192,7 +161,6 @@ impl From<AvatarData> for AvatarInfo {
avatar_id: value.avatar_id, avatar_id: value.avatar_id,
skill_depot_id: value.skill_depot_id, skill_depot_id: value.skill_depot_id,
wearing_flycloak_id: value.wearing_flycloak_id, wearing_flycloak_id: value.wearing_flycloak_id,
costume_id: value.costume_id,
born_time: value.born_time, born_time: value.born_time,
life_state: 1, life_state: 1,
avatar_type: 1, avatar_type: 1,

View file

@ -2,19 +2,16 @@ use std::sync::atomic::{AtomicU32, Ordering};
use anyhow::Result; use anyhow::Result;
use proto::*; use proto::*;
use rand::RngCore;
use super::{ use super::{
constants,
entity::{Entity, SceneAvatar, SceneWeapon}, entity::{Entity, SceneAvatar, SceneWeapon},
AvatarData, AvatarData,
}; };
use crate::{net::PlayerSession, util}; use crate::net::PlayerSession;
pub struct Scene { pub struct Scene {
id: u32, id: u32,
entity_id_counter: AtomicU32, entity_id_counter: AtomicU32,
last_player_pos: Vector,
pub avatars: Vec<SceneAvatar>, pub avatars: Vec<SceneAvatar>,
pub cur_entity_id: u32, pub cur_entity_id: u32,
} }
@ -23,7 +20,6 @@ impl Scene {
pub fn new(id: u32) -> Self { pub fn new(id: u32) -> Self {
Self { Self {
id, id,
last_player_pos: constants::INITIAL_POS.clone(),
entity_id_counter: AtomicU32::new(0), entity_id_counter: AtomicU32::new(0),
avatars: Vec::new(), avatars: Vec::new(),
cur_entity_id: 0, cur_entity_id: 0,
@ -41,53 +37,8 @@ impl Scene {
pub fn add_avatar(&mut self, data: AvatarData) { pub fn add_avatar(&mut self, data: AvatarData) {
let weapon = SceneWeapon::new(self.next_entity_id(), data.weapon.clone()); let weapon = SceneWeapon::new(self.next_entity_id(), data.weapon.clone());
self.avatars.push(SceneAvatar::new( self.avatars
self.next_entity_id(), .push(SceneAvatar::new(self.next_entity_id(), data, weapon));
data,
weapon,
self.cur_player_pos(),
));
}
pub fn cur_player_pos(&self) -> Vector {
if let Some(avatar) = self
.avatars
.iter()
.find(|a| a.get_entity_id() == self.cur_entity_id)
{
avatar.get_position()
} else {
self.last_player_pos.clone()
}
}
pub fn teleport(&mut self, to_pos: &Vector) {
self.last_player_pos = to_pos.clone();
for avatar in self.avatars.iter_mut() {
avatar.set_position(self.last_player_pos.clone())
}
}
pub async fn enter(&mut self, session: &PlayerSession, enter_type: EnterType) -> Result<()> {
let begin_time_ms = util::cur_timestamp_ms();
let begin_time = begin_time_ms / 1000;
let scene_id = self.id;
let player_uid = session.player_uid();
let enter_scene = PlayerEnterSceneNotify {
scene_begin_time: begin_time_ms,
scene_id,
enter_scene_token: rand::thread_rng().next_u32() % 65535,
scene_transaction: format!("{scene_id}-{player_uid}-{begin_time}-179398"),
pos: Some(self.last_player_pos.clone()),
prev_pos: Some(Vector::default()),
target_uid: player_uid,
r#type: enter_type.into(),
..Default::default()
};
session.send(PLAYER_ENTER_SCENE_NOTIFY, enter_scene).await
} }
pub async fn sync_scene_team(&self, session: &PlayerSession) -> Result<()> { pub async fn sync_scene_team(&self, session: &PlayerSession) -> Result<()> {

View file

@ -5,8 +5,7 @@ use rand::RngCore;
use super::*; use super::*;
use crate::{ use crate::{
data::EXCEL_COLLECTION, game::{constants, entity::Entity, prop_types::*},
game::{entity::Entity, prop_types::*},
util, util,
}; };
@ -38,7 +37,9 @@ pub async fn on_get_player_token_req(
pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq) -> Result<()> { pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq) -> Result<()> {
session.player_info_mut().unlock_all_avatars(); session.player_info_mut().unlock_all_avatars();
session.player_info_mut().unlock_all_weapons();
let login_time_ms = util::cur_timestamp_ms();
let login_time = login_time_ms / 1000;
let props = [ let props = [
(PROP_PLAYER_LEVEL, 5), (PROP_PLAYER_LEVEL, 5),
@ -74,38 +75,20 @@ pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq
.send( .send(
OPEN_STATE_UPDATE_NOTIFY, OPEN_STATE_UPDATE_NOTIFY,
OpenStateUpdateNotify { OpenStateUpdateNotify {
open_state_map: EXCEL_COLLECTION open_state_map: constants::OPEN_STATES
.open_state_configs .into_iter()
.iter() .map(|id| (id, 1))
.map(|op| (op.id, 1))
.collect(), .collect(),
}, },
) )
.await?; .await?;
let player_info = session.player_info(); let player_info = session.player_info();
let player_store_notify = PlayerStoreNotify {
weight_limit: 30000,
store_type: StoreType::StorePack.into(),
item_list: player_info
.weapons
.clone()
.into_iter()
.map(Item::from)
.collect(),
};
session
.send(PLAYER_STORE_NOTIFY, player_store_notify)
.await?;
let avatar_data_notify = AvatarDataNotify { let avatar_data_notify = AvatarDataNotify {
avatar_list: player_info avatar_list: player_info
.avatars .avatars
.clone() .iter()
.into_iter() .map(|a| Into::<AvatarInfo>::into(a.clone()))
.map(AvatarInfo::from)
.collect(), .collect(),
cur_avatar_team_id: 1, cur_avatar_team_id: 1,
choose_avatar_guid: 228, choose_avatar_guid: 228,
@ -123,21 +106,12 @@ pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq
team_name: String::from("LogicTeam"), team_name: String::from("LogicTeam"),
}, },
)]), )]),
owned_costume_list: EXCEL_COLLECTION
.avatar_costume_configs
.iter()
.map(|a| a.skin_id)
.collect(),
owned_flycloak_list: EXCEL_COLLECTION
.avatar_flycloak_configs
.iter()
.map(|a| a.flycloak_id)
.collect(),
..Default::default() ..Default::default()
}; };
session.send(AVATAR_DATA_NOTIFY, avatar_data_notify).await?; session.send(AVATAR_DATA_NOTIFY, avatar_data_notify).await?;
{
let mut scene = session.context.scene.borrow_mut(); let mut scene = session.context.scene.borrow_mut();
let player = session.player_info(); let player = session.player_info();
@ -150,8 +124,26 @@ pub async fn on_player_login_req(session: &PlayerSession, _body: &PlayerLoginReq
.clone(), .clone(),
); );
scene.cur_entity_id = scene.avatars.first().unwrap().get_entity_id(); scene.cur_entity_id = scene.avatars.first().unwrap().get_entity_id()
scene.enter(session, EnterType::EnterSelf).await?; }
let scene = session.context.scene.borrow();
let scene_id = scene.id();
let player_uid = session.player_uid();
let enter_scene = PlayerEnterSceneNotify {
scene_begin_time: 7313,
scene_id,
enter_scene_token: 15771,
scene_transaction: format!("{scene_id}-{player_uid}-{login_time}-179398"),
scene_tag_id_list: Vec::new(),
pos: Some(constants::INITIAL_POS.clone()),
prev_pos: Some(Vector::default()),
target_uid: player_uid,
r#type: EnterType::EnterSelf.into(),
..Default::default()
};
session.send(PLAYER_ENTER_SCENE_NOTIFY, enter_scene).await?;
session session
.send( .send(

View file

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use super::*; use super::*;
use crate::game::entity::{Entity, SceneWeapon}; use crate::game::entity::Entity;
pub async fn on_change_avatar_req(session: &PlayerSession, body: &ChangeAvatarReq) -> Result<()> { pub async fn on_change_avatar_req(session: &PlayerSession, body: &ChangeAvatarReq) -> Result<()> {
let mut scene = session.context.scene.borrow_mut(); let mut scene = session.context.scene.borrow_mut();
@ -33,176 +33,6 @@ pub async fn on_change_avatar_req(session: &PlayerSession, body: &ChangeAvatarRe
.await .await
} }
pub async fn on_avatar_change_costume_req(
session: &PlayerSession,
body: &AvatarChangeCostumeReq,
) -> Result<()> {
let mut player = session.player_info_mut();
let Some(avatar) = player
.avatars
.iter_mut()
.find(|a| a.guid == body.avatar_guid)
else {
return session
.send(
AVATAR_CHANGE_COSTUME_RSP,
AvatarChangeCostumeRsp {
retcode: -1,
..Default::default()
},
)
.await;
};
avatar.costume_id = body.costume_id;
let mut scene = session.context.scene.borrow_mut();
if let Some(avatar_entity) = scene
.avatars
.iter_mut()
.find(|a| a.avatar_guid() == body.avatar_guid)
{
avatar_entity.update_data(avatar);
session
.send(
AVATAR_CHANGE_COSTUME_NOTIFY,
AvatarChangeCostumeNotify {
entity_info: Some(avatar_entity.info()),
},
)
.await?;
}
session
.send(
AVATAR_CHANGE_COSTUME_RSP,
AvatarChangeCostumeRsp {
avatar_guid: body.avatar_guid,
costume_id: body.costume_id,
retcode: 0,
},
)
.await
}
pub async fn on_avatar_wear_flycloak_req(
session: &PlayerSession,
body: &AvatarWearFlycloakReq,
) -> Result<()> {
let mut player = session.player_info_mut();
let Some(avatar) = player
.avatars
.iter_mut()
.find(|a| a.guid == body.avatar_guid)
else {
return session
.send(
AVATAR_WEAR_FLYCLOAK_RSP,
AvatarWearFlycloakRsp {
retcode: -1,
..Default::default()
},
)
.await;
};
avatar.wearing_flycloak_id = body.flycloak_id;
let mut scene = session.context.scene.borrow_mut();
if let Some(avatar_entity) = scene
.avatars
.iter_mut()
.find(|a| a.avatar_guid() == body.avatar_guid)
{
avatar_entity.update_data(avatar);
}
session
.send(
AVATAR_FLYCLOAK_CHANGE_NOTIFY,
AvatarFlycloakChangeNotify {
avatar_guid: body.avatar_guid,
flycloak_id: body.flycloak_id,
},
)
.await?;
session
.send(
AVATAR_WEAR_FLYCLOAK_RSP,
AvatarWearFlycloakRsp {
retcode: 0,
avatar_guid: body.avatar_guid,
flycloak_id: body.flycloak_id,
},
)
.await
}
pub async fn on_wear_equip_req(session: &PlayerSession, body: &WearEquipReq) -> Result<()> {
let mut player = session.player_info_mut();
let weapon = player
.weapons
.iter()
.find(|w| w.guid == body.equip_guid)
.map(|w| w.clone());
let avatar = player
.avatars
.iter_mut()
.find(|a| a.guid == body.avatar_guid);
let (Some(weapon), Some(avatar)) = (weapon, avatar) else {
return session
.send(
WEAR_EQUIP_RSP,
WearEquipRsp {
retcode: -1,
..Default::default()
},
)
.await;
};
avatar.weapon = weapon;
session
.send(
AVATAR_EQUIP_CHANGE_NOTIFY,
AvatarEquipChangeNotify {
avatar_guid: body.avatar_guid,
equip_guid: body.equip_guid,
item_id: avatar.weapon.weapon_id,
equip_type: 6,
weapon: Some(SceneWeapon::new(0, avatar.weapon.clone()).scene_weapon_info()),
reliquary: None,
},
)
.await?;
let mut scene = session.context.scene.borrow_mut();
if let Some(avatar_entity) = scene
.avatars
.iter_mut()
.find(|a| a.avatar_guid() == body.avatar_guid)
{
avatar_entity.update_data(&avatar);
avatar_entity.change_weapon(avatar.weapon.clone());
}
session
.send(
WEAR_EQUIP_RSP,
WearEquipRsp {
retcode: 0,
equip_guid: body.equip_guid,
avatar_guid: body.avatar_guid,
},
)
.await
}
pub async fn on_set_up_avatar_team_req( pub async fn on_set_up_avatar_team_req(
session: &PlayerSession, session: &PlayerSession,
body: &SetUpAvatarTeamReq, body: &SetUpAvatarTeamReq,

View file

@ -1,24 +0,0 @@
use super::*;
pub async fn on_mark_map_req(session: &PlayerSession, body: &MarkMapReq) -> Result<()> {
if let Some(mark) = body.mark.as_ref() {
let mut scene = session.context.scene.borrow_mut();
let mut pos = mark.pos.clone().unwrap();
pos.y = 500.0;
scene.teleport(&pos);
scene.enter(session, EnterType::EnterJump).await?;
}
session.send(MARK_MAP_RSP, MarkMapRsp::default()).await
}
pub async fn on_get_scene_area_req(session: &PlayerSession, body: &GetSceneAreaReq) -> Result<()> {
let rsp = GetSceneAreaRsp {
area_id_list: (0..50).collect(),
scene_id: body.scene_id,
..Default::default()
};
session.send(GET_SCENE_AREA_RSP, rsp).await
}

View file

@ -1,13 +1,11 @@
mod authentication; mod authentication;
mod avatar; mod avatar;
mod map;
mod time; mod time;
mod world; mod world;
use anyhow::Result; use anyhow::Result;
pub use authentication::*; pub use authentication::*;
pub use avatar::*; pub use avatar::*;
pub use map::*;
use proto::*; use proto::*;
pub use time::*; pub use time::*;
pub use world::*; pub use world::*;

View file

@ -136,9 +136,4 @@ trait_handler! {
ChangeAvatarReq 3330; ChangeAvatarReq 3330;
EvtAvatarSitDownReq 764; EvtAvatarSitDownReq 764;
EvtAvatarStandUpNotify 8549; EvtAvatarStandUpNotify 8549;
MarkMapReq 7802;
GetSceneAreaReq 5114;
AvatarChangeCostumeReq 24368;
AvatarWearFlycloakReq 27466;
WearEquipReq 21829;
} }

View file

@ -37,7 +37,10 @@ pub fn xor(bytes: &mut [u8], key: &[u8]) {
} }
pub fn hash_str(value: &str) -> u32 { pub fn hash_str(value: &str) -> u32 {
value.chars().fold(0, |hash, c| { let mut hash = 0;
(((c as u64) + 131 * hash as u64) & 0xFFFFFFFF) as u32 value
}) .chars()
.for_each(|c| hash = (((c as u64) + 131 * hash as u64) & 0xFFFFFFFF) as u32);
hash
} }

File diff suppressed because it is too large Load diff

View file

@ -21,12 +21,3 @@ pub const SET_UP_AVATAR_TEAM_RSP: u16 = 29283;
pub const CHANGE_AVATAR_RSP: u16 = 5958; pub const CHANGE_AVATAR_RSP: u16 = 5958;
pub const EVT_AVATAR_SIT_DOWN_RSP: u16 = 29232; pub const EVT_AVATAR_SIT_DOWN_RSP: u16 = 29232;
pub const EVT_AVATAR_STAND_UP_NOTIFY: u16 = 8549; pub const EVT_AVATAR_STAND_UP_NOTIFY: u16 = 8549;
pub const MARK_MAP_RSP: u16 = 25569;
pub const GET_SCENE_AREA_RSP: u16 = 22648;
pub const AVATAR_CHANGE_COSTUME_RSP: u16 = 21748;
pub const AVATAR_CHANGE_COSTUME_NOTIFY: u16 = 8370;
pub const AVATAR_WEAR_FLYCLOAK_RSP: u16 = 25960;
pub const AVATAR_FLYCLOAK_CHANGE_NOTIFY: u16 = 23818;
pub const PLAYER_STORE_NOTIFY: u16 = 20155;
pub const WEAR_EQUIP_RSP: u16 = 9831;
pub const AVATAR_EQUIP_CHANGE_NOTIFY: u16 = 9280;

View file

@ -4,4 +4,3 @@ format_macro_matchers = true
imports_granularity = "Crate" imports_granularity = "Crate"
group_imports = "StdExternalCrate" group_imports = "StdExternalCrate"
wrap_comments = true wrap_comments = true
edition = "2021"