diff --git a/rc_services_room/src/data/tech_tree.rs b/rc_services_room/src/data/tech_tree.rs index 832f6a1..9c8f09f 100644 --- a/rc_services_room/src/data/tech_tree.rs +++ b/rc_services_room/src/data/tech_tree.rs @@ -13,7 +13,7 @@ pub struct TechTreeNode { impl TechTreeNode { pub fn as_transmissible(&self) -> Typed { Typed::HashMap(vec![ - (Typed::Str("mainCubeId".into()), Typed::Str(hex::encode(self.main_cube_id.to_le_bytes()).into())), + (Typed::Str("mainCubeId".into()), Typed::Str(hex::encode(self.main_cube_id.to_be_bytes()).into())), (Typed::Str("positionX".into()), Typed::Int(self.position_x)), (Typed::Str("positionY".into()), Typed::Int(self.position_y)), (Typed::Str("isUnlocked".into()), Typed::Bool(self.is_unlocked.into())), @@ -21,8 +21,12 @@ impl TechTreeNode { (Typed::Str("tp".into()), Typed::Int(self.tech_points as i32)), (Typed::Str("neighbours".into()), Typed::Arr(Arr { ty: 115, // str - items: self.neighbours.iter().map(|cube_id| Typed::Str(hex::encode(cube_id.to_le_bytes()).into())).collect(), + items: self.neighbours.iter().map(|cube_id| Typed::Str(hex::encode(cube_id.to_be_bytes()).into())).collect(), })), ].into()) } + + pub fn as_transmissible_key_val(&self) -> (Typed, Typed) { + (Typed::Str(hex::encode(self.main_cube_id.to_be_bytes()).into()), self.as_transmissible()) + } } diff --git a/rc_services_room/src/operations/tech_tree_data.rs b/rc_services_room/src/operations/tech_tree_data.rs index ccbb6a6..af4d964 100644 --- a/rc_services_room/src/operations/tech_tree_data.rs +++ b/rc_services_room/src/operations/tech_tree_data.rs @@ -12,15 +12,15 @@ pub(super) fn tech_tree_layout_provider() -> SimpleFunc<183, crate::UserTy, impl key_ty: 115, // str val_ty: 104, // hashmap items: vec![ - (Typed::Str("1".into()), TechTreeNode { - main_cube_id: 1, + TechTreeNode { + main_cube_id: 227205318, // default cube id position_x: 0, position_y: 0, is_unlocked: true, is_unlockable: true, tech_points: 1, neighbours: Vec::default(), - }.as_transmissible()) + }.as_transmissible_key_val(), ], })); Ok(params.into()) diff --git a/rc_social_room/src/data/clan.rs b/rc_social_room/src/data/clan.rs new file mode 100644 index 0000000..61d9d05 --- /dev/null +++ b/rc_social_room/src/data/clan.rs @@ -0,0 +1,52 @@ +#![allow(dead_code)] +use polariton::operation::Typed; + +pub struct ClanMember { + pub username: String, + pub display_name: String, + pub member_state: ClanMemberState, + pub use_custom_avatar: bool, + pub avatar_id: i32, + pub rank: ClanMemberRank, + pub is_online: bool, + pub season_xp: i32, +} + +impl ClanMember { + pub fn as_transmissible(&self) -> Typed { + Typed::HashMap(vec![ + (Typed::Str("userName".into()), Typed::Str(self.username.clone().into())), + (Typed::Str("displayName".into()), Typed::Str(self.display_name.clone().into())), + (Typed::Str("memberState".into()), Typed::Int(self.member_state as i32)), + (Typed::Str("useCustomAvatar".into()), Typed::Bool(self.use_custom_avatar.into())), + (Typed::Str("avatarId".into()), Typed::Int(self.avatar_id)), + (Typed::Str("rank".into()), Typed::Int(self.rank as i32)), + (Typed::Str("isOnline".into()), Typed::Bool(self.is_online.into())), + (Typed::Str("seasonXP".into()), Typed::Int(self.season_xp)), + ].into()) + } +} + +#[repr(u8)] +#[derive(Copy, Clone)] +pub enum ClanMemberState { + Idk0, + Idk1, + Idk2, + // TODO figure out how many of these there are (and what they mean) +} + +#[repr(u8)] +#[derive(Copy, Clone)] +pub enum ClanMemberRank { + Member = 0, + Officer = 1, + Leader = 2, +} + +#[repr(u8)] +#[derive(Copy, Clone)] +pub enum ClanType { + Open = 1, + Closed = 2, +} diff --git a/rc_social_room/src/data/mod.rs b/rc_social_room/src/data/mod.rs index 4de3fde..2137c6e 100644 --- a/rc_social_room/src/data/mod.rs +++ b/rc_social_room/src/data/mod.rs @@ -1,2 +1,3 @@ pub mod friend; pub mod clan_invite; +pub mod clan; diff --git a/rc_social_room/src/operations/clan_info.rs b/rc_social_room/src/operations/clan_info.rs new file mode 100644 index 0000000..9f35c48 --- /dev/null +++ b/rc_social_room/src/operations/clan_info.rs @@ -0,0 +1,61 @@ +use polariton_server::operations::SimpleFunc; +use polariton::operation::{ParameterTable, Typed, Arr}; + +use crate::data::clan::*; + +const CLAN_NAME_PARAM_KEY: u8 = 31; // in and out +const MEMBERS_PARAM_KEY: u8 = 36; // out only +const ROBITS_CONVERSION_PARAM_KEY: u8 = 51; // out only +const CLAN_DESCRIPTION_PARAM_KEY: u8 = 32; // out only +const CLAN_TYPE_PARAM_KEY: u8 = 32; // out only + +pub(super) fn clan_info_provider() -> SimpleFunc<33, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result) + Sync + Sync> { + SimpleFunc::new(|params, _| { + let mut params = params.to_dict(); + if let Some(Typed::Str(clan_name)) = params.get(&CLAN_NAME_PARAM_KEY) { + log::debug!("Requested info on clan {}", clan_name.string); + params.insert(MEMBERS_PARAM_KEY, Typed::Arr(Arr { + ty: 104, // hashmap + items: vec![ + ClanMember { + username: "RE_clan_user_idk0".to_owned(), + display_name: "RE_clan_user_idk0".to_owned(), + member_state: ClanMemberState::Idk0, + use_custom_avatar: false, + avatar_id: 1, + rank: ClanMemberRank::Leader, + is_online: true, + season_xp: 42_000, + }.as_transmissible(), + ClanMember { + username: "RE_clan_user_idk1".to_owned(), + display_name: "RE_clan_user_idk1".to_owned(), + member_state: ClanMemberState::Idk1, + use_custom_avatar: false, + avatar_id: 1, + rank: ClanMemberRank::Leader, + is_online: true, + season_xp: 42_001, + }.as_transmissible(), + ClanMember { + username: "RE_clan_user_idk2".to_owned(), + display_name: "RE_clan_user_idk2".to_owned(), + member_state: ClanMemberState::Idk2, + use_custom_avatar: false, + avatar_id: 1, + rank: ClanMemberRank::Leader, + is_online: true, + season_xp: 42_002, + }.as_transmissible(), + ], + })); + params.insert(ROBITS_CONVERSION_PARAM_KEY, Typed::Float(0.5)); + params.insert(CLAN_DESCRIPTION_PARAM_KEY, Typed::Str("RE_clan_description".into())); + params.insert(CLAN_TYPE_PARAM_KEY, Typed::Int(ClanType::Closed as _)); + } else { + log::debug!("Requested info on own clan (returning no info)"); + } + + Ok(params.into()) + }) +} diff --git a/rc_social_room/src/operations/mod.rs b/rc_social_room/src/operations/mod.rs index 47bd1d3..251fc04 100644 --- a/rc_social_room/src/operations/mod.rs +++ b/rc_social_room/src/operations/mod.rs @@ -2,16 +2,18 @@ mod more_auth; mod friend_list; mod settings; mod clan_invite; +mod clan_info; use polariton_server::operations::OperationsHandler; pub fn handler() -> OperationsHandler { OperationsHandler::new() .without_state(more_auth::MoreLobbyAuth) - .without_state(polariton_server::operations::Ack::<33, _>::default()) // get user clan info (this is equivalent to not being in a clan) + //.without_state(polariton_server::operations::Ack::<33, _>::default()) // get user clan info (this is equivalent to not being in a clan) .without_state(friend_list::friends_provider()) // TODO friend object parsing Token: 0x0200169C RID: 5788 .without_state(settings::settings_provider()) // TODO save settings persistently .without_state(polariton_server::operations::Ack::<43, _>::default()) // get my clan info (this is equivalent to not being in a clan) .without_state(clan_invite::clan_invites_provider()) .without_state(polariton_server::operations::Ack::<19, _>::default()) // get pending platoon invite (this is equivalent to having no pending invite) + .without_state(clan_info::clan_info_provider()) }