Files
robinsr/gameserver/src/net/tools.rs

658 lines
18 KiB
Rust
Raw Normal View History

2024-04-09 23:08:41 +07:00
use proto::*;
2024-03-29 16:49:57 +07:00
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
// AVATAR
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AvatarJson {
#[serde(alias = "ownerUid")]
pub owner_uid: u32,
#[serde(alias = "avatarId")]
pub avatar_id: u32,
pub data: AvatarData,
pub level: u32,
pub promotion: u32,
// pub rank: u32,
#[serde(alias = "use_technique")]
#[serde(alias = "useTechnique")]
pub techniques: Vec<u32>,
#[serde(alias = "spValue")]
pub sp_value: Option<u32>,
#[serde(alias = "spMax")]
pub sp_max: Option<u32>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AvatarData {
pub rank: u32,
pub skills: BTreeMap<u32, u32>,
}
impl AvatarJson {
2024-04-09 23:08:41 +07:00
pub fn to_avatar_proto(&self, lightcone: Option<&Lightcone>, relics: Vec<&Relic>) -> Avatar {
2024-03-29 16:49:57 +07:00
Avatar {
base_avatar_id: self.avatar_id,
exp: 0,
level: self.level,
promotion: self.promotion,
rank: self.data.rank,
skilltree_list: self
.data
.skills
.iter()
.map(|v| AvatarSkillTree {
point_id: *v.0,
level: *v.1,
})
.collect::<Vec<_>>(),
equipment_unique_id: if let Some(lc) = lightcone {
2024-04-12 19:41:17 +07:00
// ?
2000 + lc.internal_uid
2024-03-29 16:49:57 +07:00
} else {
0
},
2024-05-10 22:15:58 +07:00
first_met_timestamp: 1712924677,
equip_relic_list: relics
2024-03-29 16:49:57 +07:00
.iter()
.map(|v| v.to_equipment_relic_proto())
.collect::<Vec<_>>(),
..Default::default()
}
}
pub fn to_battle_avatar_proto(
&self,
index: u32,
lightcone: Option<&Lightcone>,
relics: Vec<&Relic>,
) -> (BattleAvatar, Vec<BattleBuff>) {
let battle_avatar = BattleAvatar {
index,
avatar_type: AvatarType::AvatarFormalType.into(),
id: self.avatar_id,
level: self.level,
rank: self.data.rank,
skilltree_list: self
.data
.skills
.iter()
.map(|v| AvatarSkillTree {
point_id: *v.0,
level: *v.1,
})
.collect::<Vec<_>>(),
equipment_list: if let Some(lc) = lightcone {
vec![lc.to_battle_equipment_proto()]
} else {
vec![]
},
hp: 10_000,
promotion: self.promotion,
relic_list: relics
.iter()
.map(|v| v.to_battle_relic_proto())
.collect::<Vec<_>>(),
world_level: 6,
2024-06-23 06:47:56 +07:00
sp_bar: Some(SpBarInfo {
cur_sp: self.sp_value.unwrap_or(10_000),
max_sp: self.sp_max.unwrap_or(10_000),
2024-03-29 16:49:57 +07:00
}),
..Default::default()
};
let mut battle_buff = Vec::<BattleBuff>::new();
for buff_id in &self.techniques {
battle_buff.push(BattleBuff {
wave_flag: 0xffffffff,
2024-06-23 06:47:56 +07:00
owner_id: index,
2024-03-29 16:49:57 +07:00
level: 1,
id: *buff_id,
dynamic_values: HashMap::from([(String::from("SkillIndex"), 2.0)]),
2024-03-29 16:49:57 +07:00
..Default::default()
});
}
(battle_avatar, battle_buff)
}
pub fn to_lineup_avatar_proto(&self, slot: u32) -> LineupAvatar {
LineupAvatar {
id: self.avatar_id,
hp: 10_000,
satiety: 100,
avatar_type: AvatarType::AvatarFormalType.into(),
2024-06-23 06:47:56 +07:00
sp_bar: Some(SpBarInfo {
cur_sp: self.sp_value.unwrap_or(10_000),
max_sp: self.sp_max.unwrap_or(10_000),
2024-03-29 16:49:57 +07:00
}),
slot,
}
}
2024-06-27 19:41:36 +07:00
pub fn to_lineup_avatars(player: &FreesrData) -> Vec<LineupAvatar> {
2024-04-09 23:08:41 +07:00
let avatar_ids = player
.avatars
2024-04-20 18:48:51 +07:00
.values()
.map(|v| &v.avatar_id)
2024-04-09 23:08:41 +07:00
.collect::<Vec<_>>();
2024-03-29 16:49:57 +07:00
2024-04-09 23:08:41 +07:00
player
.lineups
2024-03-29 16:49:57 +07:00
.iter()
.filter(|(slot, v)| **slot < 4 && v > &&0 && avatar_ids.contains(v))
2024-03-29 16:49:57 +07:00
.map(|(slot, avatar_id)| {
2024-04-09 23:08:41 +07:00
player
.avatars
2024-03-29 16:49:57 +07:00
.get(avatar_id)
.unwrap()
.to_lineup_avatar_proto(*slot)
})
.collect::<Vec<LineupAvatar>>()
}
pub fn to_lineup_info(lineups: &BTreeMap<u32, u32>) -> LineupInfo {
let mut lineup_info = LineupInfo {
extra_lineup_type: ExtraLineupType::LineupNone.into(),
name: "Squad 1".to_string(),
2024-05-10 22:15:58 +07:00
mp: 5,
2024-06-23 06:47:56 +07:00
max_mp: 5,
2024-03-29 16:49:57 +07:00
..Default::default()
};
2024-04-20 18:48:51 +07:00
for id in lineups.values() {
2024-03-29 16:49:57 +07:00
if *id == 0 {
continue;
}
lineup_info.avatar_list.push(LineupAvatar {
id: *id,
hp: 10_000,
satiety: 100,
avatar_type: AvatarType::AvatarFormalType.into(),
2024-06-23 06:47:56 +07:00
sp_bar: Some(SpBarInfo {
cur_sp: 10_000,
max_sp: 10_000,
2024-03-29 16:49:57 +07:00
}),
slot: lineup_info.avatar_list.len() as u32,
});
}
lineup_info
}
}
// LIGHTCONE
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Lightcone {
pub level: u32,
#[serde(alias = "itemId")]
pub item_id: u32,
#[serde(alias = "equipAvatar")]
pub equip_avatar: u32,
pub rank: u32,
pub promotion: u32,
#[serde(alias = "internalUid")]
pub internal_uid: u32,
}
impl Lightcone {
pub fn to_equipment_proto(&self) -> Equipment {
Equipment {
2024-06-23 06:47:56 +07:00
equip_avatar_id: self.equip_avatar,
2024-03-29 16:49:57 +07:00
exp: 0,
is_protected: false,
level: self.level,
promotion: self.promotion,
rank: self.rank,
tid: self.item_id,
2024-04-12 19:41:17 +07:00
// ?
unique_id: 2000 + self.internal_uid,
2024-03-29 16:49:57 +07:00
}
}
pub fn to_battle_equipment_proto(&self) -> BattleEquipment {
BattleEquipment {
id: self.item_id,
level: self.level,
promotion: self.promotion,
rank: self.rank,
}
}
}
// RELIC
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Relic {
pub level: u32,
#[serde(alias = "relicId")]
pub relic_id: u32,
#[serde(alias = "relicSetId")]
pub relic_set_id: u32,
#[serde(alias = "mainAffixId")]
pub main_affix_id: u32,
#[serde(alias = "subAffixes")]
pub sub_affixes: Vec<SubAffix>,
#[serde(alias = "internalUid")]
pub internal_uid: u32,
#[serde(alias = "equipAvatar")]
pub equip_avatar: u32,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct SubAffix {
#[serde(alias = "subAffixId")]
pub sub_affix_id: u32,
pub count: u32,
pub step: u32,
}
impl Relic {
pub fn to_relic_proto(&self) -> proto::Relic {
proto::Relic {
2024-06-23 06:47:56 +07:00
equip_avatar_id: self.equip_avatar,
2024-03-29 16:49:57 +07:00
exp: 0,
is_protected: false,
level: self.level,
main_affix_id: self.main_affix_id,
tid: self.relic_id,
2024-04-12 19:41:17 +07:00
// ?
unique_id: 1 + self.internal_uid,
2024-03-29 16:49:57 +07:00
sub_affix_list: self
.sub_affixes
.iter()
.map(|v| RelicAffix {
affix_id: v.sub_affix_id,
cnt: v.count,
step: v.step,
})
.collect::<Vec<_>>(),
2024-04-09 23:08:41 +07:00
..Default::default()
2024-03-29 16:49:57 +07:00
}
}
pub fn to_battle_relic_proto(&self) -> BattleRelic {
BattleRelic {
id: self.relic_id,
level: self.level,
main_affix_id: self.main_affix_id,
unique_id: self.internal_uid,
sub_affix_list: self
.sub_affixes
.iter()
.map(|v| RelicAffix {
affix_id: v.sub_affix_id,
cnt: v.count,
step: v.step,
})
.collect::<Vec<_>>(),
2024-04-09 23:08:41 +07:00
..Default::default()
2024-03-29 16:49:57 +07:00
}
}
pub fn to_equipment_relic_proto(&self) -> EquipRelic {
EquipRelic {
2024-06-23 06:47:56 +07:00
slot: self.relic_id % 10,
2024-04-12 19:41:17 +07:00
// ?
2024-06-23 06:47:56 +07:00
relic_unique_id: 1 + self.internal_uid,
2024-03-29 16:49:57 +07:00
}
}
}
// MONSTER
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Monster {
pub level: u32,
#[serde(alias = "monsterId")]
pub monster_id: u32,
#[serde(default)]
pub max_hp: u32,
}
impl Monster {
2024-06-23 06:47:56 +07:00
fn to_scene_monster_info(&self) -> SceneMonster {
SceneMonster {
2024-03-29 16:49:57 +07:00
monster_id: self.monster_id,
max_hp: self.max_hp,
2024-06-23 06:47:56 +07:00
cur_hp: self.max_hp,
2024-03-29 16:49:57 +07:00
}
}
2024-04-20 18:48:51 +07:00
pub fn to_scene_monster_wave(wave_index: u32, monsters: &[Self]) -> SceneMonsterWave {
2024-03-29 16:49:57 +07:00
let mut wave_index = wave_index;
2024-04-20 18:48:51 +07:00
if wave_index < 1 {
2024-03-29 16:49:57 +07:00
wave_index += 1;
}
SceneMonsterWave {
2024-06-23 06:47:56 +07:00
wave_id: wave_index, // wave indexx??
2024-04-09 23:08:41 +07:00
2024-06-23 06:47:56 +07:00
wave_param: Some(SceneMonsterWaveParam {
2024-04-09 23:08:41 +07:00
// monster param
2024-03-29 16:49:57 +07:00
level: monsters.iter().map(|v| v.level).max().unwrap_or(95),
..Default::default()
}),
monster_list: monsters
.iter()
.map(|v| v.to_scene_monster_info())
.collect::<Vec<_>>(),
..Default::default()
}
}
2024-04-20 18:48:51 +07:00
pub fn to_scene_monster_waves(monsters: &[Vec<Self>]) -> Vec<SceneMonsterWave> {
2024-03-29 16:49:57 +07:00
monsters
.iter()
.enumerate()
.map(|(i, v)| Self::to_scene_monster_wave(i as u32, v))
.collect::<_>()
}
}
// BATTLE CONFIG
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct BattleConfig {
pub battle_type: BattleType,
pub monsters: Vec<Vec<Monster>>,
pub blessings: Vec<BattleBuffJson>,
pub stage_id: u32,
pub cycle_count: u32,
pub path_resonance_id: u32,
pub custom_stats: Vec<SubAffix>,
}
impl Default for BattleConfig {
fn default() -> Self {
Self {
battle_type: Default::default(),
monsters: vec![vec![Monster {
level: 60,
monster_id: 3014022,
max_hp: 0,
}]],
stage_id: 201012311,
blessings: Default::default(),
cycle_count: Default::default(),
path_resonance_id: Default::default(),
custom_stats: Default::default(),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum BattleType {
2024-04-20 18:48:51 +07:00
#[serde(alias = "DEFAULT")]
Default = 0,
#[serde(alias = "MOC")]
Moc = 1,
2024-03-29 16:49:57 +07:00
PF = 2,
SU = 3,
2024-05-10 22:15:58 +07:00
AS = 4,
2024-03-29 16:49:57 +07:00
}
impl Default for BattleType {
fn default() -> Self {
2024-04-20 18:48:51 +07:00
Self::Default
2024-03-29 16:49:57 +07:00
}
}
// BATTLE BUFFS
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct BattleBuffJson {
pub level: u32,
pub id: u32,
pub dynamic_key: Option<DynamicKey>,
2024-08-03 14:19:36 +07:00
#[serde(default)]
pub dynamic_values: Vec<DynamicKey>,
2024-03-29 16:49:57 +07:00
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct DynamicKey {
pub key: String,
pub value: u32,
}
#[allow(dead_code)]
impl BattleBuffJson {
pub fn to_battle_buff_proto(&self) -> proto::BattleBuff {
proto::BattleBuff {
id: self.id,
level: self.level,
wave_flag: 0xffffffff,
2024-06-23 06:47:56 +07:00
owner_id: 0xffffffff,
2024-03-29 16:49:57 +07:00
dynamic_values: if let Some(dyn_key) = &self.dynamic_key {
HashMap::from([(dyn_key.key.clone(), dyn_key.value as f32)])
} else {
Default::default()
},
..Default::default()
}
}
}
2024-04-09 23:08:41 +07:00
// SCENE
2024-03-29 16:49:57 +07:00
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Scene {
pub plane_id: u32,
pub floor_id: u32,
pub entry_id: u32,
}
impl Default for Scene {
fn default() -> Self {
Self {
entry_id: 2032101,
plane_id: 20321,
floor_id: 20321001,
}
}
}
// Position
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Position {
pub x: i32,
pub y: i32,
pub z: i32,
pub rot_y: i32,
}
impl Position {
pub fn is_empty(&self) -> bool {
2024-04-20 18:48:51 +07:00
self.x == 0 && self.y == 0 && self.z == 0
2024-03-29 16:49:57 +07:00
}
pub fn to_motion(&self) -> MotionInfo {
MotionInfo {
// rot
2024-05-10 22:15:58 +07:00
rot: Some(Vector {
x: 0,
y: self.rot_y,
z: 0,
2024-03-29 16:49:57 +07:00
}),
// pos
2024-05-10 22:15:58 +07:00
pos: Some(Vector {
x: self.x,
y: self.y,
z: self.z,
2024-03-29 16:49:57 +07:00
}),
}
}
}
// FREESR-DATA.json
#[derive(Debug, Serialize, Deserialize)]
2024-06-27 19:41:36 +07:00
pub struct FreesrData {
2024-03-29 16:49:57 +07:00
pub lightcones: Vec<Lightcone>,
pub relics: Vec<Relic>,
pub avatars: BTreeMap<u32, AvatarJson>,
#[serde(default)]
pub battle_config: BattleConfig,
#[serde(default)]
pub lineups: BTreeMap<u32, u32>,
#[serde(default)]
pub position: Position,
#[serde(default)]
pub scene: Scene,
#[serde(default)]
2024-06-27 19:41:36 +07:00
pub main_character: MultiPathAvatar,
#[serde(default)]
pub march_type: MultiPathAvatar,
2024-03-29 16:49:57 +07:00
}
2024-03-29 18:36:02 +07:00
#[derive(Debug, Serialize, Deserialize)]
2024-06-27 19:41:36 +07:00
pub struct Persistent {
2024-03-29 16:49:57 +07:00
#[serde(default)]
pub lineups: BTreeMap<u32, u32>,
#[serde(default)]
pub position: Position,
#[serde(default)]
pub scene: Scene,
#[serde(default)]
2024-06-27 19:41:36 +07:00
pub main_character: MultiPathAvatar,
#[serde(default)]
pub march_type: MultiPathAvatar,
2024-03-29 16:49:57 +07:00
}
2024-06-27 19:41:36 +07:00
impl Default for Persistent {
2024-03-29 18:36:02 +07:00
fn default() -> Self {
let mut lineups = BTreeMap::<u32, u32>::new();
lineups.insert(0, 8006);
lineups.insert(1, 0);
lineups.insert(2, 0);
lineups.insert(3, 0);
Self {
2024-04-09 23:08:41 +07:00
lineups,
2024-03-29 18:36:02 +07:00
position: Default::default(),
main_character: Default::default(),
2024-04-09 23:08:41 +07:00
scene: Default::default(),
2024-06-27 19:41:36 +07:00
march_type: MultiPathAvatar::MarchHunt,
2024-03-29 18:36:02 +07:00
}
}
}
2024-03-29 16:49:57 +07:00
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
2024-06-27 19:41:36 +07:00
pub enum MultiPathAvatar {
2024-03-29 16:49:57 +07:00
MalePyhsical = 8001,
FemalePhysical = 8002,
MalePreservation = 8003,
FemalePreservation = 8004,
MaleHarmony = 8005,
FemaleHarmony = 8006,
2024-06-27 19:41:36 +07:00
MarchHunt = 1224,
MarchPreservation = 1001,
2024-03-29 16:49:57 +07:00
}
2024-06-27 19:41:36 +07:00
impl From<u32> for MultiPathAvatar {
2024-05-09 22:14:27 +07:00
fn from(value: u32) -> Self {
match value {
8001 => Self::MalePyhsical,
8002 => Self::FemalePhysical,
8003 => Self::MalePreservation,
8004 => Self::FemalePreservation,
8005 => Self::MaleHarmony,
8006 => Self::FemaleHarmony,
2024-06-27 19:41:36 +07:00
1224 => Self::MarchHunt,
1001 => Self::MarchPreservation,
2024-05-09 22:14:27 +07:00
_ => Self::FemaleHarmony,
}
}
}
2024-03-29 23:32:32 +07:00
2024-06-27 19:41:36 +07:00
impl MultiPathAvatar {
2024-03-29 23:32:32 +07:00
pub fn get_gender(&self) -> Gender {
2024-06-27 19:41:36 +07:00
if (*self as u32) < 8000 {
Gender::None
} else if *self as u32 % 2 == 1 {
2024-03-29 23:32:32 +07:00
Gender::Man
} else {
Gender::Woman
}
}
2024-06-23 06:47:56 +07:00
pub fn get_type(&self) -> MultiPathAvatarType {
2024-03-29 23:32:32 +07:00
match *self {
2024-06-27 19:41:36 +07:00
MultiPathAvatar::MalePyhsical => MultiPathAvatarType::BoyWarriorType,
MultiPathAvatar::FemalePhysical => MultiPathAvatarType::GirlWarriorType,
MultiPathAvatar::MalePreservation => MultiPathAvatarType::BoyKnightType,
MultiPathAvatar::FemalePreservation => MultiPathAvatarType::GirlKnightType,
MultiPathAvatar::MaleHarmony => MultiPathAvatarType::BoyShamanType,
MultiPathAvatar::FemaleHarmony => MultiPathAvatarType::GirlShamanType,
MultiPathAvatar::MarchHunt => MultiPathAvatarType::Mar7thRogueType,
MultiPathAvatar::MarchPreservation => MultiPathAvatarType::Mar7thKnightType,
2024-03-29 23:32:32 +07:00
}
}
}
2024-06-27 19:41:36 +07:00
impl Default for MultiPathAvatar {
2024-03-29 16:49:57 +07:00
fn default() -> Self {
Self::FemaleHarmony
}
}
2024-06-27 19:41:36 +07:00
impl FreesrData {
2024-03-29 16:49:57 +07:00
pub async fn load() -> Self {
2024-06-27 19:41:36 +07:00
let mut json: FreesrData = tokio::fs::read_to_string("freesr-data.json")
2024-04-09 23:08:41 +07:00
.await
2024-05-09 22:14:27 +07:00
.map(|v| {
2024-06-27 19:41:36 +07:00
serde_json::from_str::<FreesrData>(&v)
2024-05-09 22:14:27 +07:00
.expect("freesr-data.json is broken, pls redownload")
})
.expect("failed to read freesr-data.json");
2024-04-09 23:08:41 +07:00
2024-06-27 19:41:36 +07:00
let json2: Persistent = serde_json::from_str(
2024-04-09 23:08:41 +07:00
&tokio::fs::read_to_string("persistent")
.await
.unwrap_or_default(),
)
.unwrap_or_default();
2024-03-29 16:49:57 +07:00
json.lineups = json2.lineups;
json.position = json2.position;
json.scene = json2.scene;
json.main_character = json2.main_character;
2024-03-29 18:36:02 +07:00
json.verify_lineup().await;
2024-06-27 19:41:36 +07:00
if json.march_type as u32 > 8000 {
json.march_type = MultiPathAvatar::MarchHunt;
}
2024-03-29 16:49:57 +07:00
json
}
2024-03-29 18:36:02 +07:00
async fn verify_lineup(&mut self) {
2024-04-20 18:48:51 +07:00
if self.lineups.is_empty() {
2024-04-09 23:08:41 +07:00
self.lineups = BTreeMap::<u32, u32>::from([(0, 8006), (1, 0), (2, 0), (3, 0)])
2024-03-29 18:36:02 +07:00
} else if self.lineups.len() < 4 {
for i in self.lineups.len()..4 {
self.lineups.insert(i as u32, 0);
}
}
self.save().await;
}
2024-03-29 16:49:57 +07:00
pub async fn save_lineup(&self) {
self.save().await;
}
pub async fn save(&self) {
let json = serde_json::to_string_pretty(&self).unwrap();
let _ = tokio::fs::write("freesr-data.json", json.as_bytes()).await;
2024-04-09 23:08:41 +07:00
let _ = tokio::fs::write(
"persistent",
2024-06-27 19:41:36 +07:00
serde_json::to_string_pretty(&Persistent {
2024-04-09 23:08:41 +07:00
lineups: self.lineups.clone(),
main_character: self.main_character,
position: self.position.clone(),
scene: self.scene.clone(),
2024-06-27 19:41:36 +07:00
march_type: self.march_type,
2024-04-09 23:08:41 +07:00
})
.unwrap()
.as_bytes(),
)
.await;
2024-03-29 16:49:57 +07:00
}
2024-04-09 23:08:41 +07:00
}