344 lines
9.5 KiB
Rust
344 lines
9.5 KiB
Rust
use common::{resources::GAME_RES, sr_tools::FreesrData};
|
|
use proto::{get_big_data_all_recommend_sc_rsp::RecommendType, *};
|
|
|
|
use crate::net::PlayerSession;
|
|
|
|
use super::UNLOCKED_AVATARS;
|
|
|
|
pub async fn on_get_bag_cs_req(
|
|
session: &mut PlayerSession,
|
|
_req: &GetBagCsReq,
|
|
res: &mut GetBagScRsp,
|
|
) {
|
|
let Some(player) = session.json_data.get() else {
|
|
tracing::error!("data is not set!");
|
|
return;
|
|
};
|
|
|
|
res.equipment_list = player.lightcones.iter().map(|v| v.into()).collect();
|
|
res.relic_list = player.relics.iter().map(|v| v.into()).collect();
|
|
res.material_list = vec![
|
|
Material {
|
|
tid: 101, // Normal Pass
|
|
num: 999999,
|
|
..Default::default()
|
|
},
|
|
Material {
|
|
tid: 102, // Special Pass
|
|
num: 999999,
|
|
..Default::default()
|
|
},
|
|
];
|
|
}
|
|
|
|
pub async fn on_get_archive_data_cs_req(
|
|
_session: &mut PlayerSession,
|
|
_: &GetArchiveDataCsReq,
|
|
res: &mut GetArchiveDataScRsp,
|
|
) {
|
|
res.archive_data = Some(ArchiveData::default());
|
|
}
|
|
|
|
pub async fn on_dress_relic_avatar_cs_req(
|
|
session: &mut PlayerSession,
|
|
req: &DressRelicAvatarCsReq,
|
|
_: &mut DressRelicAvatarScRsp,
|
|
) {
|
|
let Some(player) = session.json_data.get_mut() else {
|
|
tracing::error!("data is not set!");
|
|
return;
|
|
};
|
|
|
|
if let Some(pkt) = equip_relic(player, req) {
|
|
let _ = session.send(pkt).await;
|
|
};
|
|
}
|
|
|
|
pub async fn on_take_off_relic_cs_req(
|
|
session: &mut PlayerSession,
|
|
req: &TakeOffRelicCsReq,
|
|
_: &mut TakeOffRelicScRsp,
|
|
) {
|
|
let Some(player) = session.json_data.get_mut() else {
|
|
tracing::error!("data is not set!");
|
|
return;
|
|
};
|
|
|
|
if let Some(pkt) = unequip_relic(player, req) {
|
|
let _ = session.send(pkt).await;
|
|
};
|
|
}
|
|
|
|
pub async fn on_dress_avatar_cs_req(
|
|
session: &mut PlayerSession,
|
|
req: &DressAvatarCsReq,
|
|
_: &mut DressAvatarScRsp,
|
|
) {
|
|
let Some(player) = session.json_data.get_mut() else {
|
|
tracing::error!("data is not set!");
|
|
return;
|
|
};
|
|
|
|
if let Some(pkt) = set_lightcone_equipper(player, req.avatar_id, req.equipment_unique_id) {
|
|
let _ = session.send(pkt).await;
|
|
};
|
|
}
|
|
|
|
pub async fn on_take_off_equipment_cs_req(
|
|
session: &mut PlayerSession,
|
|
req: &TakeOffEquipmentCsReq,
|
|
_: &mut TakeOffEquipmentScRsp,
|
|
) {
|
|
let Some(player) = session.json_data.get_mut() else {
|
|
tracing::error!("data is not set!");
|
|
return;
|
|
};
|
|
|
|
if let Some(pkt) = set_lightcone_equipper(player, req.avatar_id, 0) {
|
|
let _ = session.send(pkt).await;
|
|
};
|
|
}
|
|
|
|
pub async fn on_get_big_data_all_recommend_cs_req(
|
|
_: &mut PlayerSession,
|
|
req: &GetBigDataAllRecommendCsReq,
|
|
res: &mut GetBigDataAllRecommendScRsp,
|
|
) {
|
|
res.big_data_recommend_type = req.big_data_recommend_type;
|
|
|
|
match req.big_data_recommend_type() {
|
|
BigDataRecommendType::RelicAvatar => {
|
|
res.recommend_type = Some(RecommendType::RelicAvatar(BigDataRecommendRelicAvatar {
|
|
recommended_avatar_info_list: GAME_RES
|
|
.relic_avatar_recommend
|
|
.iter()
|
|
.map(|(set_id, avatar_list)| RecomendedAvatarInfo {
|
|
avatar_id_list: avatar_list.clone(),
|
|
recommend_avatar_id: avatar_list.first().copied().unwrap_or_default(),
|
|
relic_set_id: *set_id,
|
|
})
|
|
.collect(),
|
|
}))
|
|
}
|
|
BigDataRecommendType::AvatarRelic => {
|
|
res.recommend_type = Some(RecommendType::AvatarRelic(BigDataRecommendAvatarRelic {
|
|
recomended_relic_info_list: UNLOCKED_AVATARS
|
|
.into_iter()
|
|
.map(|avatar_id| RecommendedRelicInfo {
|
|
avatar_id,
|
|
..Default::default()
|
|
})
|
|
.collect(),
|
|
}))
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
pub async fn on_rank_up_avatar_cs_req(
|
|
session: &mut PlayerSession,
|
|
req: &RankUpAvatarCsReq,
|
|
_: &mut RankUpAvatarScRsp,
|
|
) -> Option<()> {
|
|
let player = session.json_data.get_mut()?;
|
|
let avatar = player.avatars.get_mut(&req.avatar_id)?;
|
|
|
|
avatar.data.rank = req.rank;
|
|
|
|
let avatar_id = avatar.avatar_id;
|
|
|
|
let mut ret = PlayerSyncScNotify::default();
|
|
|
|
build_sync(
|
|
player,
|
|
&mut ret,
|
|
vec![avatar_id],
|
|
Vec::with_capacity(0),
|
|
Vec::with_capacity(0),
|
|
);
|
|
|
|
let _ = session.send(ret).await;
|
|
|
|
Some(())
|
|
}
|
|
|
|
// TODO: move these somewhere else?
|
|
|
|
fn set_lightcone_equipper(
|
|
player: &mut FreesrData,
|
|
target_avatar: u32,
|
|
target_lightcone_uid: u32,
|
|
) -> Option<PlayerSyncScNotify> {
|
|
let mut ret = PlayerSyncScNotify::default();
|
|
|
|
let target_avatar = player.avatars.get(&target_avatar)?;
|
|
|
|
let cur_avatar_lc_idx = player
|
|
.lightcones
|
|
.iter()
|
|
.position(|l| l.equip_avatar == target_avatar.avatar_id);
|
|
|
|
// undress
|
|
if target_lightcone_uid == 0
|
|
&& let Some(cur_avatar_lc_idx) = cur_avatar_lc_idx
|
|
{
|
|
player.lightcones[cur_avatar_lc_idx].equip_avatar = 0;
|
|
|
|
build_sync(
|
|
player,
|
|
&mut ret,
|
|
vec![target_avatar.avatar_id],
|
|
vec![cur_avatar_lc_idx],
|
|
Vec::with_capacity(0),
|
|
);
|
|
|
|
return Some(ret);
|
|
}
|
|
|
|
let target_lightcone_idx = player
|
|
.lightcones
|
|
.iter()
|
|
.position(|l| l.get_unique_id() == target_lightcone_uid)?;
|
|
|
|
// jika avatar sekarang sedang pakai LC, kita tukar pemiliknya dengan pemilik dari LC target
|
|
if let Some(cur_avatar_lc_idx) = cur_avatar_lc_idx {
|
|
player.lightcones[cur_avatar_lc_idx].equip_avatar =
|
|
player.lightcones[target_lightcone_idx].equip_avatar;
|
|
}
|
|
|
|
let avatars_sync = vec![
|
|
player.lightcones[target_lightcone_idx].equip_avatar, // old
|
|
target_avatar.avatar_id, // cur
|
|
];
|
|
|
|
// set kepemilikan lightcone barunya ke avatar sekarang
|
|
player.lightcones[target_lightcone_idx].equip_avatar = target_avatar.avatar_id;
|
|
|
|
build_sync(
|
|
player,
|
|
&mut ret,
|
|
avatars_sync,
|
|
[Some(target_lightcone_idx), cur_avatar_lc_idx]
|
|
.into_iter()
|
|
.flatten()
|
|
.collect(),
|
|
Vec::with_capacity(0),
|
|
);
|
|
|
|
Some(ret)
|
|
}
|
|
|
|
fn equip_relic(player: &mut FreesrData, req: &DressRelicAvatarCsReq) -> Option<PlayerSyncScNotify> {
|
|
let mut ret = PlayerSyncScNotify::default();
|
|
|
|
let target_avatar = player.avatars.get(&req.avatar_id)?;
|
|
|
|
let mut avatar_ids_to_sy = vec![];
|
|
let mut relic_index_to_sync = vec![];
|
|
|
|
for param in &req.param_list {
|
|
let Some(target_relic_idx) = player
|
|
.relics
|
|
.iter()
|
|
.position(|v| v.get_unique_id() == param.relic_unique_id)
|
|
else {
|
|
continue;
|
|
};
|
|
|
|
let cur_avatar_relic_idx = player
|
|
.relics
|
|
.iter()
|
|
.position(|r| r.equip_avatar == target_avatar.avatar_id && r.get_slot() == param.slot);
|
|
|
|
// jika avatar sekarang sedang pakai LC, kita tukar pemiliknya dengan pemilik dari LC target
|
|
if let Some(cur_avatar_relic_idx) = cur_avatar_relic_idx {
|
|
avatar_ids_to_sy.push(player.relics[cur_avatar_relic_idx].equip_avatar);
|
|
player.relics[cur_avatar_relic_idx].equip_avatar =
|
|
player.relics[target_relic_idx].equip_avatar;
|
|
|
|
relic_index_to_sync.push(cur_avatar_relic_idx);
|
|
}
|
|
|
|
// old owner
|
|
avatar_ids_to_sy.push(player.relics[target_relic_idx].equip_avatar);
|
|
|
|
// set kepemilikan relic barunya ke avatar sekarang
|
|
player.relics[target_relic_idx].equip_avatar = target_avatar.avatar_id;
|
|
|
|
// new owner
|
|
avatar_ids_to_sy.push(player.relics[target_relic_idx].equip_avatar);
|
|
|
|
relic_index_to_sync.push(target_relic_idx);
|
|
}
|
|
|
|
build_sync(
|
|
player,
|
|
&mut ret,
|
|
avatar_ids_to_sy,
|
|
Vec::with_capacity(0),
|
|
relic_index_to_sync,
|
|
);
|
|
|
|
Some(ret)
|
|
}
|
|
|
|
fn unequip_relic(player: &mut FreesrData, req: &TakeOffRelicCsReq) -> Option<PlayerSyncScNotify> {
|
|
let mut ret = PlayerSyncScNotify::default();
|
|
|
|
let target_avatar = player.avatars.get(&req.avatar_id)?;
|
|
|
|
let mut relic_index_to_sync = vec![];
|
|
|
|
for slot in &req.slot_list {
|
|
let relics = player
|
|
.relics
|
|
.iter()
|
|
.enumerate()
|
|
.filter(|(_, r)| r.equip_avatar == target_avatar.avatar_id && r.get_slot() == *slot)
|
|
.map(|(i, _)| i)
|
|
.collect::<Vec<_>>();
|
|
|
|
for relic_idx in &relics {
|
|
player.relics[*relic_idx].equip_avatar = 0;
|
|
}
|
|
|
|
relic_index_to_sync.extend(relics);
|
|
}
|
|
|
|
build_sync(
|
|
player,
|
|
&mut ret,
|
|
vec![req.avatar_id],
|
|
Vec::with_capacity(0),
|
|
relic_index_to_sync,
|
|
);
|
|
|
|
Some(ret)
|
|
}
|
|
|
|
fn build_sync(
|
|
player: &mut FreesrData,
|
|
ret: &mut PlayerSyncScNotify,
|
|
avatar_ids: Vec<u32>,
|
|
lightcone_indexes: Vec<usize>,
|
|
relic_indexes: Vec<usize>,
|
|
) {
|
|
let avatar_list = avatar_ids
|
|
.iter()
|
|
.filter_map(|id| player.get_avatar_proto(*id))
|
|
.collect::<Vec<_>>();
|
|
ret.avatar_sync = Some(AvatarSync { avatar_list });
|
|
ret.multi_path_avatar_type_info_list = avatar_ids
|
|
.into_iter()
|
|
.filter_map(|id| player.get_avatar_multipath_proto(id))
|
|
.collect();
|
|
ret.relic_list = relic_indexes
|
|
.into_iter()
|
|
.map(|id| (&player.relics[id]).into())
|
|
.collect();
|
|
ret.equipment_list = lightcone_indexes
|
|
.into_iter()
|
|
.map(|id| (&player.lightcones[id]).into())
|
|
.collect();
|
|
}
|