mirror of
https://github.com/RustySamovar/RustySamovar.git
synced 2024-11-24 19:27:35 +00:00
Move mapper and avatar building into separate module
This commit is contained in:
parent
2d9aa1dc4c
commit
9b088aaf80
@ -17,19 +17,23 @@ pub struct GameServer {
|
|||||||
packets_to_send_tx: mpsc::Sender<IpcMessage>,
|
packets_to_send_tx: mpsc::Sender<IpcMessage>,
|
||||||
worlds: HashMap<u32, GameWorld>,
|
worlds: HashMap<u32, GameWorld>,
|
||||||
login_manager: LoginManager,
|
login_manager: LoginManager,
|
||||||
|
database_manager: Arc<DatabaseManager>,
|
||||||
|
json_manager: Arc<JsonManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameServer {
|
impl GameServer {
|
||||||
pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer {
|
pub fn new(packets_to_process_rx: mpsc::Receiver<IpcMessage>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameServer {
|
||||||
let db = DatabaseManager::new("sqlite://./database.db3");
|
let db = Arc::new(DatabaseManager::new("sqlite://./database.db3"));
|
||||||
let jm = JsonManager::new("./json");
|
let jm = Arc::new(JsonManager::new("./json"));
|
||||||
let lm = LoginManager::new(Arc::new(db), Arc::new(jm), packets_to_send_tx.clone());
|
let lm = LoginManager::new(db.clone(), jm.clone(), packets_to_send_tx.clone());
|
||||||
|
|
||||||
let gs = GameServer {
|
let gs = GameServer {
|
||||||
packets_to_process_rx: packets_to_process_rx,
|
packets_to_process_rx: packets_to_process_rx,
|
||||||
packets_to_send_tx: packets_to_send_tx,
|
packets_to_send_tx: packets_to_send_tx,
|
||||||
worlds: HashMap::new(),
|
worlds: HashMap::new(),
|
||||||
login_manager: lm,
|
login_manager: lm,
|
||||||
|
database_manager: db.clone(),
|
||||||
|
json_manager: jm.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return gs;
|
return gs;
|
||||||
@ -53,7 +57,7 @@ impl GameServer {
|
|||||||
let world = match self.worlds.entry(user_id) {
|
let world = match self.worlds.entry(user_id) {
|
||||||
Occupied(world) => world.into_mut(),
|
Occupied(world) => world.into_mut(),
|
||||||
Vacant(entry) => {
|
Vacant(entry) => {
|
||||||
let mut world = GameWorld::new(self.packets_to_send_tx.clone());
|
let mut world = GameWorld::new(self.database_manager.clone(),self.json_manager.clone(), self.packets_to_send_tx.clone());
|
||||||
entry.insert(world)
|
entry.insert(world)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
use std::sync::mpsc;
|
use std::sync::{mpsc, Arc};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
|
|
||||||
|
use chrono::Datelike;
|
||||||
|
|
||||||
use crate::server::IpcMessage;
|
use crate::server::IpcMessage;
|
||||||
|
|
||||||
|
use crate::utils::{AvatarBuilder, Remapper};
|
||||||
|
|
||||||
use packet_processor_macro::*;
|
use packet_processor_macro::*;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
use packet_processor::*;
|
use packet_processor::*;
|
||||||
|
use crate::DatabaseManager;
|
||||||
|
use crate::JsonManager;
|
||||||
|
|
||||||
macro_rules! collection {
|
macro_rules! collection {
|
||||||
// map-like
|
// map-like
|
||||||
@ -35,20 +41,21 @@ macro_rules! collection {
|
|||||||
)]
|
)]
|
||||||
pub struct GameWorld {
|
pub struct GameWorld {
|
||||||
packets_to_send_tx: mpsc::Sender<IpcMessage>,
|
packets_to_send_tx: mpsc::Sender<IpcMessage>,
|
||||||
|
db: Arc<DatabaseManager>,
|
||||||
|
jm: Arc<JsonManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameWorld {
|
impl GameWorld {
|
||||||
const BASE_GUID: u64 = 0x2400000000000000;
|
const BASE_GUID: u64 = 0x2400000000000000;
|
||||||
const SPOOFED_AVATAR_EID: u32 = (1<<24) + 146;
|
const SPOOFED_AVATAR_EID: u32 = (1<<24) + 146;
|
||||||
const SPOOFED_AVATAR_GUID: u64 = GameWorld::BASE_GUID + 1;
|
|
||||||
const SPOOFED_WEAPON_EID: u32 = 0x6000000 + 146;
|
const SPOOFED_WEAPON_EID: u32 = 0x6000000 + 146;
|
||||||
const SPOOFED_WEAPON_GUID: u64 = GameWorld::BASE_GUID + 2;
|
const SPOOFED_WEAPON_GUID: u64 = GameWorld::BASE_GUID + 2;
|
||||||
const SPOOFED_SCENE_TOKEN: u32 = 0x1234;
|
|
||||||
const SPOOFED_SCENE_ID: u32 = 3;
|
|
||||||
|
|
||||||
pub fn new(packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameWorld {
|
pub fn new(db: Arc<DatabaseManager>, jm: Arc<JsonManager>, packets_to_send_tx: mpsc::Sender<IpcMessage>) -> GameWorld {
|
||||||
let mut gw = GameWorld {
|
let mut gw = GameWorld {
|
||||||
packets_to_send_tx: packets_to_send_tx,
|
packets_to_send_tx: packets_to_send_tx,
|
||||||
|
db: db.clone(),
|
||||||
|
jm: jm.clone(),
|
||||||
packet_callbacks: HashMap::new(),
|
packet_callbacks: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,28 +69,38 @@ impl GameWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_get_player_social_detail(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::GetPlayerSocialDetailReq, rsp: &mut proto::GetPlayerSocialDetailRsp) {
|
fn process_get_player_social_detail(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::GetPlayerSocialDetailReq, rsp: &mut proto::GetPlayerSocialDetailRsp) {
|
||||||
|
let user = match self.db.get_player_info(user_id) {
|
||||||
|
Some(user) => user,
|
||||||
|
None => panic!("User {} not found!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
let props = self.db.get_player_props(user_id).unwrap_or_else(|| panic!("Failed to get properties for user {}!", user_id));
|
||||||
|
|
||||||
|
let user_level = props[&(proto::PropType::PropPlayerLevel as u32)] as u32;
|
||||||
|
let world_level = props[&(proto::PropType::PropPlayerWorldLevel as u32)] as u32;
|
||||||
|
|
||||||
let avatar_info = build!(SocialShowAvatarInfo {
|
let avatar_info = build!(SocialShowAvatarInfo {
|
||||||
avatar_id: 10000007,
|
avatar_id: user.avatar_id,
|
||||||
level: 80,
|
level: 80,
|
||||||
});
|
});
|
||||||
|
|
||||||
let details = build!(SocialDetail {
|
let details = build!(SocialDetail {
|
||||||
uid: user_id,
|
uid: user_id,
|
||||||
nickname: "Fukker".to_string(),
|
nickname: user.nick_name.clone(),
|
||||||
level: 56,
|
level: user_level,
|
||||||
avatar_id: 10000007,
|
avatar_id: user.avatar_id,
|
||||||
signature: "Fuck you".to_string(),
|
signature: user.signature.clone(),
|
||||||
birthday: Some(proto::Birthday {month: 2, day: 11}),
|
birthday: Some(proto::Birthday {month: user.birthday.month(), day: user.birthday.day()}),
|
||||||
world_level: 8,
|
world_level: world_level,
|
||||||
online_state: proto::FriendOnlineState::FriendOnline as i32,
|
online_state: proto::FriendOnlineState::FriendOnline as i32, // TODO
|
||||||
is_friend: true,
|
is_friend: true, // TODO
|
||||||
is_mp_mode_available: true,
|
is_mp_mode_available: true, // TODO
|
||||||
name_card_id: 210051,
|
name_card_id: user.namecard_id,
|
||||||
finish_achievement_num: 42,
|
finish_achievement_num: user.finish_achievement_num, // TODO
|
||||||
tower_floor_index: 1,
|
tower_floor_index: user.tower_floor_index as u32,
|
||||||
tower_level_index: 1,
|
tower_level_index: user.tower_level_index as u32,
|
||||||
show_avatar_info_list: vec![avatar_info], // TODO
|
show_avatar_info_list: vec![avatar_info], // TODO
|
||||||
show_name_card_id_list: vec![210051],
|
show_name_card_id_list: vec![user.namecard_id], // TODO: add all namecards!
|
||||||
// Field 25!
|
// Field 25!
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -93,31 +110,56 @@ impl GameWorld {
|
|||||||
fn process_enter_scene_ready(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::EnterSceneReadyReq, rsp: &mut proto::EnterSceneReadyRsp) {
|
fn process_enter_scene_ready(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::EnterSceneReadyReq, rsp: &mut proto::EnterSceneReadyRsp) {
|
||||||
rsp.enter_scene_token = req.enter_scene_token;
|
rsp.enter_scene_token = req.enter_scene_token;
|
||||||
|
|
||||||
|
let current_scene_info = match self.db.get_player_scene_info(user_id) {
|
||||||
|
Some(scene_info) => scene_info,
|
||||||
|
None => panic!("Scene info not found for user {}!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
build_and_send!(self, user_id, metadata, EnterScenePeerNotify {
|
build_and_send!(self, user_id, metadata, EnterScenePeerNotify {
|
||||||
dest_scene_id: GameWorld::SPOOFED_SCENE_ID,
|
dest_scene_id: current_scene_info.scene_id,
|
||||||
peer_id: 1,
|
peer_id: 1, // TODO
|
||||||
host_peer_id: 1,
|
host_peer_id: 1, // TODO
|
||||||
enter_scene_token: GameWorld::SPOOFED_SCENE_TOKEN,
|
enter_scene_token: req.enter_scene_token, // TODO??
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_scene_init_finish(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::SceneInitFinishReq, rsp: &mut proto::SceneInitFinishRsp) {
|
fn process_scene_init_finish(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::SceneInitFinishReq, rsp: &mut proto::SceneInitFinishRsp) {
|
||||||
rsp.enter_scene_token = GameWorld::SPOOFED_SCENE_TOKEN;
|
let current_avatar_guid = match self.db.get_player_team_selection(user_id) {
|
||||||
|
Some(team_selection) => team_selection.avatar,
|
||||||
|
None => panic!("Team selection info not found for user {}!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
let current_scene_info = match self.db.get_player_scene_info(user_id) {
|
||||||
|
Some(scene_info) => scene_info,
|
||||||
|
None => panic!("Scene info not found for user {}!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = match self.db.get_player_info(user_id) {
|
||||||
|
Some(user) => user,
|
||||||
|
None => panic!("User {} not found!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
let props = self.db.get_player_props(user_id).unwrap_or_else(|| panic!("Failed to get properties for user {}!", user_id));
|
||||||
|
|
||||||
|
let user_level = props[&(proto::PropType::PropPlayerLevel as u32)] as u32;
|
||||||
|
let world_level = props[&(proto::PropType::PropPlayerWorldLevel as u32)] as u32;
|
||||||
|
|
||||||
|
rsp.enter_scene_token = current_scene_info.scene_token;
|
||||||
|
|
||||||
build_and_send!(self, user_id, metadata, WorldDataNotify {
|
build_and_send!(self, user_id, metadata, WorldDataNotify {
|
||||||
world_prop_map: self.remap(&collection!{1 => 8, 2 => 0}),
|
world_prop_map: Remapper::remap(&collection!{1 => 8, 2 => 0}),
|
||||||
});
|
});
|
||||||
|
|
||||||
let online_player_info = build!(OnlinePlayerInfo {
|
let online_player_info = build!(OnlinePlayerInfo {
|
||||||
uid: user_id,
|
uid: user_id,
|
||||||
nickname: "Fukker".to_string(),
|
nickname: user.nick_name.clone(),
|
||||||
player_level: 56,
|
player_level: user_level,
|
||||||
avatar_id: 10000007,
|
avatar_id: user.avatar_id,
|
||||||
mp_setting_type: proto::MpSettingType::MpSettingEnterAfterApply as i32,
|
mp_setting_type: proto::MpSettingType::MpSettingEnterAfterApply as i32, // TODO!
|
||||||
cur_player_num_in_world: 1,
|
cur_player_num_in_world: 1, // TODO!
|
||||||
world_level: 8,
|
world_level: world_level,
|
||||||
name_card_id: 210051,
|
name_card_id: user.namecard_id,
|
||||||
signature: "Fuck you!".to_string(),
|
signature: user.signature.clone(),
|
||||||
// TODO: Field 12!
|
// TODO: Field 12!
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,9 +170,9 @@ impl GameWorld {
|
|||||||
|
|
||||||
let scene_player_info_e = build!(ScenePlayerInfo {
|
let scene_player_info_e = build!(ScenePlayerInfo {
|
||||||
uid: user_id,
|
uid: user_id,
|
||||||
peer_id: 1,
|
peer_id: 1, // TODO
|
||||||
name: "Fukker".to_string(),
|
name: user.nick_name.clone(),
|
||||||
scene_id: GameWorld::SPOOFED_SCENE_ID,
|
scene_id: current_scene_info.scene_id,
|
||||||
online_player_info: Some(online_player_info),
|
online_player_info: Some(online_player_info),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -139,7 +181,7 @@ impl GameWorld {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let avatar_enter_info = build!(AvatarEnterSceneInfo {
|
let avatar_enter_info = build!(AvatarEnterSceneInfo {
|
||||||
avatar_guid: GameWorld::SPOOFED_AVATAR_GUID,
|
avatar_guid: current_avatar_guid as u64, // FIXME
|
||||||
avatar_entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
avatar_entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
||||||
weapon_guid: GameWorld::SPOOFED_WEAPON_GUID,
|
weapon_guid: GameWorld::SPOOFED_WEAPON_GUID,
|
||||||
weapon_entity_id: GameWorld::SPOOFED_WEAPON_EID,
|
weapon_entity_id: GameWorld::SPOOFED_WEAPON_EID,
|
||||||
@ -151,7 +193,7 @@ impl GameWorld {
|
|||||||
let team_enter_info = build!(TeamEnterSceneInfo { team_entity_id: 0x9000000 + 1, });
|
let team_enter_info = build!(TeamEnterSceneInfo { team_entity_id: 0x9000000 + 1, });
|
||||||
|
|
||||||
build_and_send!(self, user_id, metadata, PlayerEnterSceneInfoNotify {
|
build_and_send!(self, user_id, metadata, PlayerEnterSceneInfoNotify {
|
||||||
enter_scene_token: GameWorld::SPOOFED_SCENE_TOKEN,
|
enter_scene_token: current_scene_info.scene_token,
|
||||||
avatar_enter_info: vec![avatar_enter_info],
|
avatar_enter_info: vec![avatar_enter_info],
|
||||||
cur_avatar_entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
cur_avatar_entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
||||||
mp_level_entity_info: Some(mp_level_info),
|
mp_level_entity_info: Some(mp_level_info),
|
||||||
@ -164,27 +206,28 @@ impl GameWorld {
|
|||||||
});
|
});
|
||||||
|
|
||||||
build_and_send!(self, user_id, metadata, SceneTimeNotify {
|
build_and_send!(self, user_id, metadata, SceneTimeNotify {
|
||||||
scene_id: GameWorld::SPOOFED_SCENE_ID,
|
scene_id: current_scene_info.scene_id,
|
||||||
scene_time: 9000,
|
scene_time: 9000,
|
||||||
});
|
});
|
||||||
|
|
||||||
build_and_send!(self, user_id, metadata, SceneDataNotify {
|
build_and_send!(self, user_id, metadata, SceneDataNotify {
|
||||||
level_config_name_list: vec!["Level_BigWorld".to_string()],
|
level_config_name_list: vec!["Level_BigWorld".to_string()], // TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
build_and_send!(self, user_id, metadata, HostPlayerNotify {
|
build_and_send!(self, user_id, metadata, HostPlayerNotify {
|
||||||
host_uid: user_id,
|
host_uid: user_id,
|
||||||
host_peer_id: 1,
|
host_peer_id: 1, // TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: perform for each avatar in the team!
|
||||||
let scene_team_avatar = build!(SceneTeamAvatar {
|
let scene_team_avatar = build!(SceneTeamAvatar {
|
||||||
scene_id: GameWorld::SPOOFED_SCENE_ID,
|
scene_id: current_scene_info.scene_id,
|
||||||
player_uid: user_id,
|
player_uid: user_id,
|
||||||
avatar_guid: GameWorld::SPOOFED_AVATAR_GUID,
|
avatar_guid: current_avatar_guid as u64, // FIXME
|
||||||
entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
||||||
weapon_guid: GameWorld::SPOOFED_WEAPON_GUID,
|
weapon_guid: GameWorld::SPOOFED_WEAPON_GUID,
|
||||||
weapon_entity_id: GameWorld::SPOOFED_WEAPON_EID,
|
weapon_entity_id: GameWorld::SPOOFED_WEAPON_EID,
|
||||||
is_player_cur_avatar: true,
|
is_player_cur_avatar: true, // TODO
|
||||||
scene_entity_info: Some(self.spoof_scene_default_avatar(user_id)),
|
scene_entity_info: Some(self.spoof_scene_default_avatar(user_id)),
|
||||||
ability_control_block: Some(self.spoof_default_abilities()),
|
ability_control_block: Some(self.spoof_default_abilities()),
|
||||||
});
|
});
|
||||||
@ -198,12 +241,17 @@ impl GameWorld {
|
|||||||
|
|
||||||
build_and_send!(self, user_id, metadata, SceneEntityAppearNotify {
|
build_and_send!(self, user_id, metadata, SceneEntityAppearNotify {
|
||||||
entity_list: vec![self.spoof_scene_default_avatar(user_id)],
|
entity_list: vec![self.spoof_scene_default_avatar(user_id)],
|
||||||
appear_type: proto::VisionType::VisionBorn as i32,
|
appear_type: proto::VisionType::VisionBorn as i32, // TODO
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_post_enter_scene(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::PostEnterSceneReq, rsp: &mut proto::PostEnterSceneRsp) {
|
fn process_post_enter_scene(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::PostEnterSceneReq, rsp: &mut proto::PostEnterSceneRsp) {
|
||||||
rsp.enter_scene_token = GameWorld::SPOOFED_SCENE_TOKEN;
|
let current_scene_info = match self.db.get_player_scene_info(user_id) {
|
||||||
|
Some(scene_info) => scene_info,
|
||||||
|
None => panic!("Scene info not found for user {}!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
rsp.enter_scene_token = current_scene_info.scene_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_enter_world_area(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::EnterWorldAreaReq, rsp: &mut proto::EnterWorldAreaRsp) {
|
fn process_enter_world_area(&self, user_id: u32, metadata: &proto::PacketHead, req: &proto::EnterWorldAreaReq, rsp: &mut proto::EnterWorldAreaRsp) {
|
||||||
@ -212,8 +260,23 @@ impl GameWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn spoof_scene_default_avatar(&self, user_id: u32) -> proto::SceneEntityInfo {
|
fn spoof_scene_default_avatar(&self, user_id: u32) -> proto::SceneEntityInfo {
|
||||||
|
let user = self.db.get_player_scene_info(user_id).unwrap_or_else(|| panic!("User info not found for user {}!", user_id));
|
||||||
|
|
||||||
|
let current_avatar_guid = match self.db.get_player_team_selection(user_id) {
|
||||||
|
Some(team_selection) => team_selection.avatar,
|
||||||
|
None => panic!("Team selection info not found for user {}!", user_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
let avatar_info = self.db.get_avatar(current_avatar_guid).unwrap_or_else(|| panic!("Avatar info for avatar {} not found!", current_avatar_guid));
|
||||||
|
|
||||||
|
let avatar_info = AvatarBuilder::build_avatar_info(self.jm.clone(), self.db.clone(), &avatar_info);
|
||||||
|
|
||||||
|
let current_avatar_props = self.db.get_avatar_props(current_avatar_guid).unwrap_or_else(|| panic!("Properties not found for avatar {}!", current_avatar_guid));
|
||||||
|
|
||||||
|
let current_avatar_fight_props = self.db.get_avatar_fight_props(current_avatar_guid).unwrap_or_else(|| panic!("Fight props not found for avatar {}!", current_avatar_guid));
|
||||||
|
|
||||||
let motion_info = build!(MotionInfo {
|
let motion_info = build!(MotionInfo {
|
||||||
pos: Some(proto::Vector {x: -3400.0, y: 233.0, z: -3427.0}),
|
pos: Some(proto::Vector {x: user.pos_x, y: user.pos_y, z: user.pos_z}),
|
||||||
rot: Some(proto::Vector::default()),
|
rot: Some(proto::Vector::default()),
|
||||||
speed: Some(proto::Vector::default()),
|
speed: Some(proto::Vector::default()),
|
||||||
});
|
});
|
||||||
@ -230,16 +293,16 @@ impl GameWorld {
|
|||||||
|
|
||||||
let scene_avatar_info = build!(SceneAvatarInfo {
|
let scene_avatar_info = build!(SceneAvatarInfo {
|
||||||
uid: user_id,
|
uid: user_id,
|
||||||
avatar_id: 10000007,
|
avatar_id: avatar_info.avatar_id,
|
||||||
guid: GameWorld::SPOOFED_AVATAR_GUID,
|
guid: current_avatar_guid as u64, // FIXME
|
||||||
peer_id: 1,
|
peer_id: 1, // TODO
|
||||||
skill_depot_id: 704,
|
skill_depot_id: avatar_info.skill_depot_id,
|
||||||
born_time: 1633790000,
|
born_time: avatar_info.born_time,
|
||||||
talent_id_list: vec![71, 72, 73, 74, 75, 76],
|
talent_id_list: avatar_info.talent_id_list,
|
||||||
inherent_proud_skill_list: vec![72101, 72201],
|
inherent_proud_skill_list: avatar_info.inherent_proud_skill_list,
|
||||||
skill_level_map: collection!{100553 => 3, 10067 => 3, 10068 => 3},
|
skill_level_map: avatar_info.skill_level_map,
|
||||||
proud_skill_extra_level_map: collection!{739 => 3, 732 => 3},
|
proud_skill_extra_level_map: avatar_info.proud_skill_extra_level_map,
|
||||||
equip_id_list: vec![11406],
|
equip_id_list: vec![11406], // TODO
|
||||||
weapon: Some(weapon),
|
weapon: Some(weapon),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -254,8 +317,8 @@ impl GameWorld {
|
|||||||
entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
entity_id: GameWorld::SPOOFED_AVATAR_EID,
|
||||||
life_state: 1,
|
life_state: 1,
|
||||||
entity: Some(proto::scene_entity_info::Entity::Avatar(scene_avatar_info)),
|
entity: Some(proto::scene_entity_info::Entity::Avatar(scene_avatar_info)),
|
||||||
prop_list: self.spoof_scene_avatar_props(),
|
prop_list: Remapper::remap2(¤t_avatar_props),
|
||||||
fight_prop_list: self.spoof_scene_avatar_fight_props(),
|
fight_prop_list: Remapper::remap3(¤t_avatar_fight_props),
|
||||||
motion_info: Some(motion_info),
|
motion_info: Some(motion_info),
|
||||||
entity_authority_info: Some(authority_info),
|
entity_authority_info: Some(authority_info),
|
||||||
});
|
});
|
||||||
@ -263,89 +326,6 @@ impl GameWorld {
|
|||||||
return scene_entity_info;
|
return scene_entity_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spoof_avatar_props_raw(&self) -> HashMap<u32,i64> {
|
|
||||||
// TODO: fill!
|
|
||||||
let map = collection! {
|
|
||||||
proto::PropType::PropExp as u32 => 0,
|
|
||||||
proto::PropType::PropLevel as u32 => 80,
|
|
||||||
proto::PropType::PropBreakLevel as u32 => 5,
|
|
||||||
proto::PropType::PropSatiationVal as u32 => 0,
|
|
||||||
proto::PropType::PropSatiationPenaltyTime as u32 => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spoof_avatar_fight_props(&self) -> HashMap<u32,f32> {
|
|
||||||
// TODO: fill!
|
|
||||||
let map = collection! {
|
|
||||||
proto::FightPropType::FightPropBaseHp as u32 => 9000.0,
|
|
||||||
proto::FightPropType::FightPropHp as u32 => 3000.0,
|
|
||||||
proto::FightPropType::FightPropHpPercent as u32 => 0.0746000,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropBaseAttack as u32 => 600.0,
|
|
||||||
proto::FightPropType::FightPropAttack as u32 => 50.0,
|
|
||||||
proto::FightPropType::FightPropAttackPercent as u32 => 0.40,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropBaseDefense as u32 => 600.0,
|
|
||||||
proto::FightPropType::FightPropDefense as u32 => 40.0,
|
|
||||||
proto::FightPropType::FightPropDefensePercent as u32 => 0.04,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropCritical as u32 => 0.99,
|
|
||||||
proto::FightPropType::FightPropAntiCritical as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropCriticalHurt as u32 => 0.99,
|
|
||||||
proto::FightPropType::FightPropChargeEfficiency as u32 => 1.337,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropHealAdd as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropHealedAdd as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropElementMastery as u32 => 42.0,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropPhysicalSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropPhysicalAddHurt as u32 => 0.271828,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropFireAddHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropElecAddHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropWaterAddHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropGrassAddHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropWindAddHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropRockAddHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropIceAddHurt as u32 => 0.00000,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropFireSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropElecSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropWaterSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropGrassSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropWindSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropRockSubHurt as u32 => 0.00000,
|
|
||||||
proto::FightPropType::FightPropIceSubHurt as u32 => 0.00000,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropMaxWindEnergy as u32 => 60.0000,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropCurWindEnergy as u32 => 60.0000,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropCurHp as u32 => 10000.0,
|
|
||||||
|
|
||||||
proto::FightPropType::FightPropMaxHp as u32 => 12000.0,
|
|
||||||
proto::FightPropType::FightPropCurAttack as u32 => 900.0,
|
|
||||||
proto::FightPropType::FightPropCurDefense as u32 => 700.0,
|
|
||||||
proto::FightPropType::FightPropCurSpeed as u32 => 10.00000,
|
|
||||||
};
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spoof_scene_avatar_props(&self) -> Vec<proto::PropPair> {
|
|
||||||
let map = self.spoof_avatar_props_raw();
|
|
||||||
|
|
||||||
return self.remap2(&map);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spoof_scene_avatar_fight_props(&self) -> Vec<proto::FightPropPair> {
|
|
||||||
let map = self.spoof_avatar_fight_props();
|
|
||||||
|
|
||||||
return self.remap3(&map);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spoof_default_abilities(&self) -> proto::AbilityControlBlock {
|
fn spoof_default_abilities(&self) -> proto::AbilityControlBlock {
|
||||||
let map: HashMap<u32,u32> = collection! {
|
let map: HashMap<u32,u32> = collection! {
|
||||||
1 => 0x05FF9657,
|
1 => 0x05FF9657,
|
||||||
@ -402,70 +382,4 @@ impl GameWorld {
|
|||||||
|
|
||||||
return acb;
|
return acb;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spoof_fetter_info(&self) -> proto::AvatarFetterInfo {
|
|
||||||
// Fetter info is used for character info and voicelines in "about" section of chara menu
|
|
||||||
let mut afi = proto::AvatarFetterInfo::default();
|
|
||||||
afi.exp_level = 1;
|
|
||||||
|
|
||||||
let map: HashMap<u32,u32> = collection! {
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut fl = vec![];
|
|
||||||
|
|
||||||
for (key, value) in map {
|
|
||||||
let mut fd = proto::FetterData::default();
|
|
||||||
fd.fetter_id = key;
|
|
||||||
fd.fetter_state = value;
|
|
||||||
fl.push(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
//afi.fetter_list = fl;
|
|
||||||
|
|
||||||
return afi;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remap(&self, map: &HashMap<u32, i64>) -> HashMap<u32, proto::PropValue> {
|
|
||||||
let mut hashmap = HashMap::<u32, proto::PropValue>::new();
|
|
||||||
|
|
||||||
for (key, value) in map {
|
|
||||||
let mut prop = proto::PropValue::default();
|
|
||||||
prop.r#type = *key;
|
|
||||||
prop.val = *value;
|
|
||||||
prop.value = Some(proto::prop_value::Value::Ival(*value));
|
|
||||||
hashmap.insert(*key, prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remap2(&self, map: &HashMap<u32, i64>) -> Vec<proto::PropPair> {
|
|
||||||
let mut ret = vec![];
|
|
||||||
|
|
||||||
for (key, value) in map {
|
|
||||||
let mut prop = proto::PropValue::default();
|
|
||||||
prop.r#type = *key;
|
|
||||||
prop.val = *value;
|
|
||||||
prop.value = Some(proto::prop_value::Value::Ival(*value));
|
|
||||||
let mut pair = proto::PropPair::default();
|
|
||||||
pair.r#type = *key;
|
|
||||||
pair.prop_value = Some(prop);
|
|
||||||
ret.push(pair);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remap3(&self, map: &HashMap<u32, f32>) -> Vec<proto::FightPropPair> {
|
|
||||||
let mut ret = vec![];
|
|
||||||
|
|
||||||
for (key, value) in map {
|
|
||||||
let mut pair = proto::FightPropPair::default();
|
|
||||||
pair.prop_type = *key;
|
|
||||||
pair.prop_value = *value;
|
|
||||||
ret.push(pair);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use packet_processor::*;
|
|||||||
use crate::DatabaseManager;
|
use crate::DatabaseManager;
|
||||||
use crate::JsonManager;
|
use crate::JsonManager;
|
||||||
|
|
||||||
use crate::utils::IdManager;
|
use crate::utils::{AvatarBuilder, IdManager, Remapper};
|
||||||
use crate::utils::TimeManager;
|
use crate::utils::TimeManager;
|
||||||
|
|
||||||
use crate::dbmanager::database_manager::AvatarInfo as DbAvatarInfo;
|
use crate::dbmanager::database_manager::AvatarInfo as DbAvatarInfo;
|
||||||
@ -45,7 +45,7 @@ impl LoginManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let player_props = match self.db.get_player_props(user_id) {
|
let player_props = match self.db.get_player_props(user_id) {
|
||||||
Some(props) => Self::remap(&props),
|
Some(props) => Remapper::remap(&props),
|
||||||
None => panic!("Props for user {} not found!", user_id),
|
None => panic!("Props for user {} not found!", user_id),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ impl LoginManager {
|
|||||||
let avatar_list = match self.db.get_avatars(user_id) {
|
let avatar_list = match self.db.get_avatars(user_id) {
|
||||||
Some(avatars) => avatars
|
Some(avatars) => avatars
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| self.build_avatar_info(&a))
|
.map(|a| AvatarBuilder::build_avatar_info(self.jm.clone(), self.db.clone(), &a))
|
||||||
.collect(),
|
.collect(),
|
||||||
None => panic!("Avatars for user {} not found!", user_id),
|
None => panic!("Avatars for user {} not found!", user_id),
|
||||||
};
|
};
|
||||||
@ -79,6 +79,8 @@ impl LoginManager {
|
|||||||
None => panic!("Scene info for user {} not found!", user_id),
|
None => panic!("Scene info for user {} not found!", user_id),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let world_level = player_props[&(proto::PropType::PropPlayerWorldLevel as u32)].val as u32;
|
||||||
|
|
||||||
build_and_send! ( self, user_id, metadata, PlayerDataNotify {
|
build_and_send! ( self, user_id, metadata, PlayerDataNotify {
|
||||||
nick_name: user.nick_name, server_time: TimeManager::timestamp(), prop_map: player_props,
|
nick_name: user.nick_name, server_time: TimeManager::timestamp(), prop_map: player_props,
|
||||||
});
|
});
|
||||||
@ -106,7 +108,7 @@ impl LoginManager {
|
|||||||
avatar_list: avatar_list,
|
avatar_list: avatar_list,
|
||||||
avatar_team_map: team_map,
|
avatar_team_map: team_map,
|
||||||
cur_avatar_team_id: current_team.into(),
|
cur_avatar_team_id: current_team.into(),
|
||||||
choose_avatar_guid: current_avatar,
|
choose_avatar_guid: current_avatar as u64, // FIXME
|
||||||
});
|
});
|
||||||
|
|
||||||
build_and_send! (self, user_id, metadata, PlayerEnterSceneNotify {
|
build_and_send! (self, user_id, metadata, PlayerEnterSceneNotify {
|
||||||
@ -115,7 +117,7 @@ impl LoginManager {
|
|||||||
scene_begin_time: TimeManager::timestamp(),
|
scene_begin_time: TimeManager::timestamp(),
|
||||||
pos: Some(proto::Vector {x: scene_info.pos_x, y: scene_info.pos_y, z: scene_info.pos_z}),
|
pos: Some(proto::Vector {x: scene_info.pos_x, y: scene_info.pos_y, z: scene_info.pos_z}),
|
||||||
target_uid: user_id,
|
target_uid: user_id,
|
||||||
world_level: user.world_level as u32,
|
world_level: world_level,
|
||||||
enter_scene_token: scene_info.scene_token,
|
enter_scene_token: scene_info.scene_token,
|
||||||
//enter_reason: 1,
|
//enter_reason: 1,
|
||||||
});
|
});
|
||||||
@ -137,7 +139,7 @@ impl LoginManager {
|
|||||||
for team in player_teams {
|
for team in player_teams {
|
||||||
let at = build! ( AvatarTeam {
|
let at = build! ( AvatarTeam {
|
||||||
team_name: team.name.clone(),
|
team_name: team.name.clone(),
|
||||||
avatar_guid_list: player_teams_avatars.clone().into_iter().filter(|a| a.team_id == team.id).map(|a| a.guid).collect(),
|
avatar_guid_list: player_teams_avatars.clone().into_iter().filter(|a| a.team_id == team.id).map(|a| a.guid as u64).collect(), // FIXME
|
||||||
});
|
});
|
||||||
|
|
||||||
team_map.insert(team.id.into(), at);
|
team_map.insert(team.id.into(), at);
|
||||||
@ -145,87 +147,4 @@ impl LoginManager {
|
|||||||
|
|
||||||
return team_map;
|
return team_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_avatar_info(&self, a: &DbAvatarInfo) -> proto::AvatarInfo {
|
|
||||||
let di = IdManager::get_depot_id_by_char_id(a.character_id);
|
|
||||||
|
|
||||||
let asd = &self.jm.avatar_skill_depot[&di];
|
|
||||||
|
|
||||||
let asl = self.db.get_skill_levels(a.guid).unwrap_or_else(|| panic!("No skill levels for avatar {}!", a.guid));
|
|
||||||
|
|
||||||
let mut slm = HashMap::new();
|
|
||||||
|
|
||||||
match asd.energy_skill {
|
|
||||||
Some(es) => {
|
|
||||||
if (asl.contains_key(&es)) {
|
|
||||||
slm.insert(es, asl[&es]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
for s in &asd.skills {
|
|
||||||
if (*s != 0) {
|
|
||||||
if (asl.contains_key(s)) {
|
|
||||||
slm.insert(*s, asl[s]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ap = self.db.get_avatar_props(a.guid).unwrap_or_else(|| panic!("Props not found for avatar {}!", a.guid));
|
|
||||||
let afp = self.db.get_avatar_fight_props(a.guid).unwrap_or_else(|| panic!("Fight props not found for avatar {}!", a.guid));
|
|
||||||
|
|
||||||
let pli = proto::PropType::PropBreakLevel as u32;
|
|
||||||
|
|
||||||
let promote_level = if ap.contains_key(&pli) { ap[&pli] as u32 } else { 0 };
|
|
||||||
|
|
||||||
let ips = asd.inherent_proud_skill_opens
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.filter(|s| s.proud_skill_group_id != None)
|
|
||||||
.filter(|s| s.need_avatar_promote_level == None || s.need_avatar_promote_level.unwrap() <= promote_level)
|
|
||||||
.map(|s| s.proud_skill_group_id.unwrap())
|
|
||||||
.map(|s| s * 100 + 1) // TODO: ugly hack! Fix it by reading ProudSkillExcelConfigData!
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// TODO: properly fill!
|
|
||||||
let afi = build!(AvatarFetterInfo {
|
|
||||||
exp_level: 1,
|
|
||||||
// TODO: fill fetter list!
|
|
||||||
});
|
|
||||||
|
|
||||||
let egi = self.db.get_avatar_equip(a.guid).unwrap_or_else(|| panic!("Equip not found for avatar {}!", a.guid));
|
|
||||||
|
|
||||||
// TODO: ugly ugly hack!
|
|
||||||
let mut fuck = HashMap::new();
|
|
||||||
fuck.insert(732, 3);
|
|
||||||
fuck.insert(739, 3);
|
|
||||||
|
|
||||||
let ai = build!(AvatarInfo {
|
|
||||||
avatar_id: IdManager::get_avatar_id_by_char_id(a.character_id),
|
|
||||||
avatar_type: a.avatar_type.into(),
|
|
||||||
guid: a.guid,
|
|
||||||
born_time: a.born_time,
|
|
||||||
skill_depot_id: asd.id,
|
|
||||||
talent_id_list: asd.talents.clone(),
|
|
||||||
prop_map: Self::remap(&ap),
|
|
||||||
fight_prop_map: afp,
|
|
||||||
fetter_info: Some(afi),
|
|
||||||
equip_guid_list: egi,
|
|
||||||
inherent_proud_skill_list: ips, //vec![72101, 72201],
|
|
||||||
skill_level_map: slm,
|
|
||||||
proud_skill_extra_level_map: fuck, //collection!{739 => 3, 732 => 3},
|
|
||||||
});
|
|
||||||
return ai;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remap(map: &HashMap<u32, i64>) -> HashMap<u32, proto::PropValue> {
|
|
||||||
let mut hashmap = HashMap::<u32, proto::PropValue>::new();
|
|
||||||
|
|
||||||
for (key, value) in map {
|
|
||||||
hashmap.insert(*key, build!(PropValue { r#type: *key, val: *value, value: Some(proto::prop_value::Value::Ival(*value)), }));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashmap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
110
src/utils/avatar_builder.rs
Normal file
110
src/utils/avatar_builder.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use packet_processor_macro::*;
|
||||||
|
#[macro_use]
|
||||||
|
use packet_processor::*;
|
||||||
|
|
||||||
|
use crate::dbmanager::database_manager::AvatarInfo as DbAvatarInfo;
|
||||||
|
use crate::{DatabaseManager, JsonManager};
|
||||||
|
use crate::utils::{IdManager, Remapper};
|
||||||
|
|
||||||
|
pub struct AvatarBuilder {}
|
||||||
|
|
||||||
|
impl AvatarBuilder {
|
||||||
|
pub fn build_avatar_info(jm: Arc<JsonManager>, db: Arc<DatabaseManager>, a: &DbAvatarInfo) -> proto::AvatarInfo {
|
||||||
|
let di = IdManager::get_depot_id_by_char_id(a.character_id);
|
||||||
|
|
||||||
|
let asd = &jm.avatar_skill_depot[&di];
|
||||||
|
|
||||||
|
let asl = db.get_skill_levels(a.guid).unwrap_or_else(|| panic!("No skill levels for avatar {}!", a.guid));
|
||||||
|
|
||||||
|
let mut slm = HashMap::new();
|
||||||
|
|
||||||
|
match asd.energy_skill {
|
||||||
|
Some(es) => {
|
||||||
|
if (asl.contains_key(&es)) {
|
||||||
|
slm.insert(es, asl[&es]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
for s in &asd.skills {
|
||||||
|
if (*s != 0) {
|
||||||
|
if (asl.contains_key(s)) {
|
||||||
|
slm.insert(*s, asl[s]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ap = db.get_avatar_props(a.guid).unwrap_or_else(|| panic!("Props not found for avatar {}!", a.guid));
|
||||||
|
let afp = db.get_avatar_fight_props(a.guid).unwrap_or_else(|| panic!("Fight props not found for avatar {}!", a.guid));
|
||||||
|
|
||||||
|
let pli = proto::PropType::PropBreakLevel as u32;
|
||||||
|
|
||||||
|
let promote_level = if ap.contains_key(&pli) { ap[&pli] as u32 } else { 0 };
|
||||||
|
|
||||||
|
let ips = asd.inherent_proud_skill_opens
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|s| s.proud_skill_group_id != None)
|
||||||
|
.filter(|s| s.need_avatar_promote_level == None || s.need_avatar_promote_level.unwrap() <= promote_level)
|
||||||
|
.map(|s| s.proud_skill_group_id.unwrap())
|
||||||
|
.map(|s| s * 100 + 1) // TODO: ugly hack! Fix it by reading ProudSkillExcelConfigData!
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// TODO: properly fill!
|
||||||
|
let afi = build!(AvatarFetterInfo {
|
||||||
|
exp_level: 1,
|
||||||
|
// TODO: fill fetter list!
|
||||||
|
});
|
||||||
|
|
||||||
|
let egi = db.get_avatar_equip(a.guid).unwrap_or_else(|| panic!("Equip not found for avatar {}!", a.guid));
|
||||||
|
let egi = egi.into_iter().map(|g| g as u64).collect(); // FIXME
|
||||||
|
|
||||||
|
// TODO: ugly ugly hack!
|
||||||
|
let mut fuck = HashMap::new();
|
||||||
|
fuck.insert(732, 3);
|
||||||
|
fuck.insert(739, 3);
|
||||||
|
|
||||||
|
let ai = build!(AvatarInfo {
|
||||||
|
avatar_id: IdManager::get_avatar_id_by_char_id(a.character_id),
|
||||||
|
avatar_type: a.avatar_type.into(),
|
||||||
|
guid: a.guid as u64, // FIXME
|
||||||
|
born_time: a.born_time,
|
||||||
|
skill_depot_id: asd.id,
|
||||||
|
talent_id_list: asd.talents.clone(),
|
||||||
|
prop_map: Remapper::remap(&ap),
|
||||||
|
fight_prop_map: afp,
|
||||||
|
fetter_info: Some(afi),
|
||||||
|
equip_guid_list: egi,
|
||||||
|
inherent_proud_skill_list: ips, //vec![72101, 72201],
|
||||||
|
skill_level_map: slm,
|
||||||
|
proud_skill_extra_level_map: fuck, //collection!{739 => 3, 732 => 3},
|
||||||
|
});
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spoof_fetter_info() -> proto::AvatarFetterInfo {
|
||||||
|
// Fetter info is used for character info and voicelines in "about" section of chara menu
|
||||||
|
let mut afi = proto::AvatarFetterInfo::default();
|
||||||
|
afi.exp_level = 1;
|
||||||
|
|
||||||
|
/*let map: HashMap<u32,u32> = collection! {
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut fl = vec![];
|
||||||
|
|
||||||
|
for (key, value) in map {
|
||||||
|
let mut fd = proto::FetterData::default();
|
||||||
|
fd.fetter_id = key;
|
||||||
|
fd.fetter_state = value;
|
||||||
|
fl.push(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//afi.fetter_list = fl;*/
|
||||||
|
|
||||||
|
return afi;
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,12 @@ mod handshake_packet;
|
|||||||
mod data_packet;
|
mod data_packet;
|
||||||
mod id_manager;
|
mod id_manager;
|
||||||
mod time_manager;
|
mod time_manager;
|
||||||
|
mod avatar_builder;
|
||||||
|
mod remapper;
|
||||||
|
|
||||||
pub use self::handshake_packet::HandshakePacket;
|
pub use self::handshake_packet::HandshakePacket;
|
||||||
pub use self::data_packet::DataPacket;
|
pub use self::data_packet::DataPacket;
|
||||||
pub use self::id_manager::IdManager;
|
pub use self::id_manager::IdManager;
|
||||||
pub use self::time_manager::TimeManager;
|
pub use self::time_manager::TimeManager;
|
||||||
|
pub use self::remapper::Remapper;
|
||||||
|
pub use self::avatar_builder::AvatarBuilder;
|
49
src/utils/remapper.rs
Normal file
49
src/utils/remapper.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub struct Remapper {}
|
||||||
|
|
||||||
|
impl Remapper {
|
||||||
|
pub fn remap(map: &HashMap<u32, i64>) -> HashMap<u32, proto::PropValue> {
|
||||||
|
let mut hashmap = HashMap::<u32, proto::PropValue>::new();
|
||||||
|
|
||||||
|
for (key, value) in map {
|
||||||
|
let mut prop = proto::PropValue::default();
|
||||||
|
prop.r#type = *key;
|
||||||
|
prop.val = *value;
|
||||||
|
prop.value = Some(proto::prop_value::Value::Ival(*value));
|
||||||
|
hashmap.insert(*key, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remap2(map: &HashMap<u32, i64>) -> Vec<proto::PropPair> {
|
||||||
|
let mut ret = vec![];
|
||||||
|
|
||||||
|
for (key, value) in map {
|
||||||
|
let mut prop = proto::PropValue::default();
|
||||||
|
prop.r#type = *key;
|
||||||
|
prop.val = *value;
|
||||||
|
prop.value = Some(proto::prop_value::Value::Ival(*value));
|
||||||
|
let mut pair = proto::PropPair::default();
|
||||||
|
pair.r#type = *key;
|
||||||
|
pair.prop_value = Some(prop);
|
||||||
|
ret.push(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remap3(map: &HashMap<u32, f32>) -> Vec<proto::FightPropPair> {
|
||||||
|
let mut ret = vec![];
|
||||||
|
|
||||||
|
for (key, value) in map {
|
||||||
|
let mut pair = proto::FightPropPair::default();
|
||||||
|
pair.prop_type = *key;
|
||||||
|
pair.prop_value = *value;
|
||||||
|
ret.push(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user