2025-03-15 11:03:35 -04:00
|
|
|
#[allow(dead_code)]
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct UserToken {
|
|
|
|
|
pub uuid: String,
|
|
|
|
|
pub token: String,
|
|
|
|
|
pub refresh_token: String,
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 19:38:03 -04:00
|
|
|
pub struct UserInfo {
|
|
|
|
|
pub payload: libfj::robocraft::TokenPayload,
|
|
|
|
|
pub extra: ExtraUserInfo,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum ExtraUserInfo {
|
|
|
|
|
Steam {
|
|
|
|
|
id: u64,
|
|
|
|
|
},
|
2025-05-11 21:18:45 -04:00
|
|
|
Username {
|
|
|
|
|
password: String,
|
|
|
|
|
},
|
|
|
|
|
Email {
|
2025-04-01 19:38:03 -04:00
|
|
|
password: String,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-12 20:56:24 -04:00
|
|
|
pub enum UserId {
|
|
|
|
|
SteamId(u64),
|
|
|
|
|
Email(String),
|
|
|
|
|
Username(String),
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 19:38:03 -04:00
|
|
|
pub struct UserLoginInfo {
|
|
|
|
|
pub response: libfj::robocraft::AuthenticationResponseInfo,
|
|
|
|
|
pub is_new: bool,
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-12 20:56:24 -04:00
|
|
|
pub struct RegistrationInfo {
|
|
|
|
|
pub display_name: String,
|
|
|
|
|
pub password: String,
|
|
|
|
|
pub email: Option<String>,
|
|
|
|
|
pub steam_id: Option<u64>,
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-07 20:23:22 -04:00
|
|
|
#[async_trait::async_trait]
|
2025-03-15 11:03:35 -04:00
|
|
|
pub trait UserProvider<C> {
|
2025-07-06 17:36:52 -04:00
|
|
|
async fn authenticate(&self, user: UserToken) -> Result<Box<dyn User<C> + Send + Sync>, String>;
|
|
|
|
|
|
|
|
|
|
async fn multiplayer_authenticate(&self, user: String) -> Result<Box<dyn User<C> + Send + Sync>, String>;
|
2025-03-15 11:03:35 -04:00
|
|
|
}
|
|
|
|
|
|
2025-05-07 20:23:22 -04:00
|
|
|
#[async_trait::async_trait]
|
2025-04-01 19:38:03 -04:00
|
|
|
pub trait UserAuthenticator {
|
2025-05-07 20:23:22 -04:00
|
|
|
async fn login(&self, info: UserInfo) -> Result<UserLoginInfo, String>;
|
2025-05-12 20:56:24 -04:00
|
|
|
async fn user_exists(&self, user: UserId) -> Result<bool, String>;
|
2025-06-06 19:03:08 -04:00
|
|
|
async fn register(&self, info: RegistrationInfo) -> Result<i32, String>;
|
2025-04-01 19:38:03 -04:00
|
|
|
}
|
|
|
|
|
|
2025-05-07 20:23:22 -04:00
|
|
|
#[async_trait::async_trait]
|
2025-07-06 17:36:52 -04:00
|
|
|
pub trait User<C>: ChatUser + LobbyUser + MultiplayerUser {
|
|
|
|
|
fn public_id(&self) -> &'_ str;
|
2025-03-15 11:03:35 -04:00
|
|
|
fn is_mod(&self) -> bool;
|
|
|
|
|
fn is_admin(&self) -> bool;
|
|
|
|
|
fn is_dev(&self) -> bool;
|
2025-05-07 20:23:22 -04:00
|
|
|
async fn unlocked_parts(&self) -> Vec<u32>;
|
|
|
|
|
async fn selected_garage(&self) -> (String, u32);
|
2025-05-10 13:19:35 -04:00
|
|
|
async fn select_garage(&self, slot: i32) -> Result<(), i16>;
|
|
|
|
|
async fn all_slots(&self) -> UserSlots<C>;
|
2025-05-07 20:23:22 -04:00
|
|
|
async fn slot_by_id(&self, id: i32) -> Result<UserSlotData<C>, i16>;
|
|
|
|
|
async fn save_slot(&self, vehicle: VehicleData) -> Result<(), i16>;
|
2025-05-10 13:19:35 -04:00
|
|
|
async fn save_slot_order(&self, slots: Vec<i32>) -> Result<(), i16>;
|
|
|
|
|
async fn new_slot(&self, reset_slot: Option<i32>) -> Result<NewSlotData<C>, i16>;
|
2025-05-31 16:33:34 -04:00
|
|
|
async fn copy_slot(&self, slot: i32, into_slot: Option<i32>, append: &str) -> Result<(), i16>;
|
2025-05-11 12:09:23 -04:00
|
|
|
async fn upgrade_slot(&self, increments: i32) -> Result<polariton::operation::Typed<C>, i16>;
|
2025-05-26 21:30:28 -04:00
|
|
|
async fn save_slot_controls(&self, controls: ControlData) -> Result<(), i16>;
|
|
|
|
|
async fn save_slot_customisations(&self, customs: CustomisationData) -> Result<(), i16>;
|
|
|
|
|
async fn get_slot_customisations(&self, uuid: &str) -> Result<GetCustomisationData<C>, i16>;
|
2025-05-31 15:36:33 -04:00
|
|
|
async fn set_slot_name(&self, slot: i32, name: String) -> Result<(), i16>;
|
2025-03-15 17:21:18 -04:00
|
|
|
fn signup_date(&self) -> i64;
|
2025-06-03 21:09:03 -04:00
|
|
|
async fn singleplayer_robots(&self, factory: &dyn oj_rc_factory::VehicleFactoryAdapter, weapon_order: &crate::cubes::WeaponListParser, singleplayer_config: &crate::persist::config::SingleplayerConfig) -> Result<polariton::operation::Typed<C>, i16>;
|
|
|
|
|
async fn prepare_factory_upload(&self, vehicle: VehicleUploadData) -> Result<oj_rc_factory::VehicleUploadInfo, i16>;
|
2025-05-18 22:23:33 -04:00
|
|
|
async fn last_seen(&self) -> Result<u64, i16>;
|
2025-05-25 12:26:08 -04:00
|
|
|
async fn get_avatar_info(&self) -> Result<GetAvatarInfo<C>, i16>;
|
|
|
|
|
async fn set_avatar_info(&self, info: AvatarInfo) -> Result<(), i16>;
|
2025-03-15 11:03:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct UserSlots<C> {
|
|
|
|
|
pub slot_info: polariton::operation::Typed<C>,
|
|
|
|
|
pub slot_order: polariton::operation::Typed<C>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct UserSlotData<C> {
|
|
|
|
|
pub data: polariton::operation::Typed<C>,
|
|
|
|
|
pub colour_data: polariton::operation::Typed<C>,
|
|
|
|
|
pub cube_count: polariton::operation::Typed<C>,
|
|
|
|
|
pub weapon_order: polariton::operation::Typed<C>,
|
|
|
|
|
pub movement_categories: polariton::operation::Typed<C>,
|
|
|
|
|
pub control_type: polariton::operation::Typed<C>,
|
|
|
|
|
pub control_options: polariton::operation::Typed<C>,
|
|
|
|
|
pub mastery_level: polariton::operation::Typed<C>,
|
2025-03-18 16:47:11 -04:00
|
|
|
pub robot_rank: polariton::operation::Typed<C>,
|
|
|
|
|
pub cpu: polariton::operation::Typed<C>,
|
|
|
|
|
pub cosmetic_cpu: polariton::operation::Typed<C>,
|
2025-03-30 16:22:25 -04:00
|
|
|
pub uuid: polariton::operation::Typed<C>,
|
2025-03-15 11:03:35 -04:00
|
|
|
}
|
|
|
|
|
|
2025-05-10 13:19:35 -04:00
|
|
|
pub struct NewSlotData<C> {
|
|
|
|
|
pub name: polariton::operation::Typed<C>,
|
|
|
|
|
pub uuid_0: polariton::operation::Typed<C>,
|
|
|
|
|
pub uuid_1: polariton::operation::Typed<C>,
|
|
|
|
|
pub slot: polariton::operation::Typed<C>,
|
|
|
|
|
pub bay_cpu: polariton::operation::Typed<C>,
|
|
|
|
|
pub mastery_level: polariton::operation::Typed<C>,
|
2025-05-17 23:06:07 -04:00
|
|
|
pub slot_i: i32,
|
2025-05-10 13:19:35 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-15 11:03:35 -04:00
|
|
|
pub struct VehicleData {
|
2025-05-18 16:55:12 -04:00
|
|
|
pub name: Option<String>,
|
2025-05-07 20:23:22 -04:00
|
|
|
pub slot: i32,
|
2025-03-15 11:03:35 -04:00
|
|
|
pub robot_data: Vec<u8>,
|
|
|
|
|
pub colour_data: Vec<u8>,
|
|
|
|
|
pub weapon_order: Vec<i32>,
|
2025-05-18 16:55:12 -04:00
|
|
|
pub crf_id: Option<i32>,
|
2025-03-15 11:03:35 -04:00
|
|
|
}
|
2025-05-18 21:52:03 -04:00
|
|
|
|
|
|
|
|
pub struct VehicleUploadData {
|
|
|
|
|
pub version: String,
|
|
|
|
|
pub slot: i32,
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub description: String,
|
|
|
|
|
pub thumbnail: Vec<u8>,
|
|
|
|
|
}
|
2025-05-23 16:46:12 -04:00
|
|
|
|
2025-05-26 21:30:28 -04:00
|
|
|
pub struct ControlData {
|
|
|
|
|
pub slot: i32,
|
|
|
|
|
pub control_ty: ControlType,
|
|
|
|
|
pub vertical_strafing: bool,
|
|
|
|
|
pub sideways_driving: bool,
|
|
|
|
|
pub tracks_turn_on_spot: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum ControlType {
|
|
|
|
|
Camera = 0,
|
|
|
|
|
Keyboard = 1,
|
|
|
|
|
Count = 2,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ControlType {
|
|
|
|
|
pub fn from_i32(i: i32) -> Result<Self, i16> {
|
|
|
|
|
match i {
|
|
|
|
|
0 => Ok(Self::Camera),
|
|
|
|
|
1 => Ok(Self::Keyboard),
|
|
|
|
|
2 => Ok(Self::Count),
|
|
|
|
|
_ => Err(crate::data::error_codes::WebServicesError::UnexpectedError as i16),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2025-06-03 21:09:03 -04:00
|
|
|
pub(super) fn into_db(self) -> oj_rc_database::schema::garage::ControlType {
|
2025-05-26 21:30:28 -04:00
|
|
|
match self {
|
2025-06-03 21:09:03 -04:00
|
|
|
Self::Camera => oj_rc_database::schema::garage::ControlType::Camera,
|
|
|
|
|
Self::Keyboard => oj_rc_database::schema::garage::ControlType::Keyboard,
|
|
|
|
|
Self::Count => oj_rc_database::schema::garage::ControlType::Count,
|
2025-05-26 21:30:28 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct CustomisationData {
|
|
|
|
|
pub uuid: String,
|
|
|
|
|
pub bay: String,
|
|
|
|
|
pub spawn: String,
|
|
|
|
|
pub death: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct GetCustomisationData<C> {
|
|
|
|
|
pub bay: polariton::operation::Typed<C>,
|
|
|
|
|
pub spawn: polariton::operation::Typed<C>,
|
|
|
|
|
pub death: polariton::operation::Typed<C>,
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-25 12:26:08 -04:00
|
|
|
pub struct GetAvatarInfo<C> {
|
|
|
|
|
pub avatar_id: polariton::operation::Typed<C>,
|
|
|
|
|
pub use_custom: polariton::operation::Typed<C>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct AvatarInfo {
|
|
|
|
|
pub avatar_id: i32,
|
|
|
|
|
pub use_custom: bool,
|
|
|
|
|
}
|
2025-05-23 16:46:12 -04:00
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
pub trait ChatUser {
|
2025-05-25 12:26:08 -04:00
|
|
|
async fn subscribed_channels(&self) -> Result<polariton::operation::Typed<()>, i16>;
|
2025-05-23 16:46:12 -04:00
|
|
|
async fn subscribed_channels_strings(&self) -> Result<Vec<String>, i16>;
|
2025-05-25 12:26:08 -04:00
|
|
|
async fn add_subscribed_channel(&self, channel: String, channel_ty: crate::data::channel::ChatChannelType) -> Result<polariton::operation::Typed<()>, i16>;
|
2025-05-23 16:46:12 -04:00
|
|
|
async fn remove_subscribed_channel(&self, channel: String, channel_ty: crate::data::channel::ChatChannelType) -> Result<(), i16>;
|
2025-05-29 20:55:36 -04:00
|
|
|
//async fn has_pending_sanctions(&self) -> Result<bool, i16>;
|
|
|
|
|
async fn get_sanctions(&self, username: String) -> Result<polariton::operation::Typed<()>, i16>;
|
|
|
|
|
async fn set_sanction(&self, sanction: SetSanction) -> Result<(), i16>;
|
2025-05-23 16:46:12 -04:00
|
|
|
}
|
|
|
|
|
|
2025-05-29 20:55:36 -04:00
|
|
|
pub struct SetSanction {
|
|
|
|
|
pub is_adding: bool, // if false, it's modifying
|
|
|
|
|
pub type_: SanctionType,
|
|
|
|
|
pub duration: i32,
|
|
|
|
|
pub reason: String,
|
|
|
|
|
pub username: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum SanctionType {
|
|
|
|
|
Warn = 0,
|
|
|
|
|
Mute = 1,
|
|
|
|
|
Ban = 2,
|
|
|
|
|
Note = 3,
|
|
|
|
|
Kick = 4,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl SanctionType {
|
|
|
|
|
pub fn from_i32(i: i32) -> Result<Self, i16> {
|
|
|
|
|
match i {
|
|
|
|
|
0 => Ok(Self::Warn),
|
|
|
|
|
1 => Ok(Self::Mute),
|
|
|
|
|
2 => Ok(Self::Ban),
|
|
|
|
|
3 => Ok(Self::Note),
|
|
|
|
|
4 => Ok(Self::Kick),
|
|
|
|
|
_ => Err(crate::data::error_codes::ChatErrorCodes::UnexpectedError as i16),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-19 22:05:16 -04:00
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
pub trait LobbyUser {
|
|
|
|
|
async fn player_data(&self) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError>;
|
|
|
|
|
}
|
2025-07-06 17:36:52 -04:00
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
pub trait MultiplayerUser {
|
|
|
|
|
// TODO
|
|
|
|
|
fn user_id(&self) -> i32;
|
|
|
|
|
fn user_name(&self) -> &'_ str;
|
|
|
|
|
fn display_name(&self) -> &'_ str;
|
|
|
|
|
}
|