use polariton_server::operations::{Operation, OperationCode, SimpleFunc}; use polariton::operation::{ParameterTable, Typed}; use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl}; //use oj_rc_core::ConfigProvider; const CAMPAIGNS_BYTES_PARAM_KEY: u8 = 64; // list of bytes (serialised data) const CAMPAIGNS_WAVES_PARAM_KEY: u8 = 70; // hashtable const CAMPAIGNS_VERSIONS_PARAM_KEY: u8 = 69; // hashtable const CAMPAIGNS_OP_CODE: u8 = 65; pub struct SingleplayerCampaignProvider { resolver: oj_rc_core::persist::config::CampaignResolver, factory: std::sync::Arc, weapon_order: std::sync::Arc, cpu_counter: std::sync::Arc, } pub(super) fn singleplayer_campaigns_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl { let campaigns = >::campaigns(&init_ctx.cubes); SimpleOpImpl::new(SingleplayerCampaignProvider { resolver: campaigns, factory: init_ctx.factory.clone(), weapon_order: init_ctx.parsers.weapon_order(), cpu_counter: init_ctx.parsers.cpu_counter(), }) } /*pub(super) fn singleplayer_campaigns_provider(conf: &oj_rc_core::ConfigImpl) -> Immediate<65, crate::UserTy> { Immediate::new(|| { let mut params = std::collections::HashMap::new(); params.insert(CAMPAIGNS_BYTES_PARAM_KEY, conf.campaigns_parameters()); // first 4 bytes are i32 for length of the rest //params.insert(CAMPAIGNS_BYTES_PARAM_KEY, Typed::Bytes(vec![0u8, 0u8, 0u8, 0u8].into())); // first 4 bytes are i32 for length of the rest params.insert(CAMPAIGNS_WAVES_PARAM_KEY, conf.campaign_waves()); //params.insert(CAMPAIGNS_WAVES_PARAM_KEY, Typed::HashMap(vec![].into())); params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, conf.campaign_version()); // params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, Typed::HashMap(vec![ // (Typed::Str("CurrentVersionNumber".into()), Typed::Int(0)), // (Typed::Str("LockedCampaignsInfo".into()), Typed::HashMap(vec![ // (Typed::Str("0".into()), Typed::Bool(false.into())) // ].into())), // ].into())); params.into() }) }*/ #[async_trait::async_trait] impl SimpleOperation for SingleplayerCampaignProvider { type User = crate::UserTy; const CODE: u8 = CAMPAIGNS_OP_CODE; async fn handle(&self, params: ParameterTable, user: &Self::User) -> Result, SimpleOpError> { let mut params = params.to_dict(); let user = user.user()?; params.insert(CAMPAIGNS_BYTES_PARAM_KEY, self.resolver.campaigns_parameters()); let waves = self.resolver.campaign_waves(user.as_ref().as_ref(), self.factory.as_ref(), &self.weapon_order, &self.cpu_counter).await?; params.insert(CAMPAIGNS_WAVES_PARAM_KEY, waves); params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, self.resolver.campaign_version()); Ok(params.into()) } } const CAMPAIGN_ID_PARAM_KEY: u8 = 22; // string; in const CAMPAIGN_DIFFICULTY_PARAM_KEY: u8 = 23; // i32; in const CAMPAIGN_WAVES_PARAM_KEY: u8 = 75; // bytes; out const CAMPAIGN_COMPLETE_OP_CODE: u8 = 64; pub struct SingleplayerCompleteCampaignProvider { campaign_details: oj_rc_core::persist::config::CompleteCampaignProvider, factory: std::sync::Arc, weapon_order: std::sync::Arc, cpu_counter: std::sync::Arc, } #[async_trait::async_trait] impl Operation for SingleplayerCompleteCampaignProvider { type User = crate::UserTy; async fn handle_async(&self, params: polariton::operation::ParameterTable, user: &Self::User) -> polariton::operation::OperationResponse { let mut params = params.to_dict(); if let Some(Typed::Str(campaign_id)) = params.get(&CAMPAIGN_ID_PARAM_KEY) { if let Some(Typed::Int(campaign_difficulty)) = params.get(&CAMPAIGN_DIFFICULTY_PARAM_KEY) { let user = match user.user() { Ok(x) => x, Err(e) => { return polariton::operation::OperationResponse { code: Self::op_code(), return_code: e, message: polariton::operation::Typed::Null, params: std::collections::HashMap::default().into(), } } }; match self.campaign_details.get(&campaign_id.string, campaign_difficulty, user.as_ref().as_ref(), self.factory.as_ref(), &self.weapon_order, &self.cpu_counter).await { Ok(complete_campaign) => { params.clear(); params.insert(CAMPAIGN_WAVES_PARAM_KEY, complete_campaign); }, Err(e) => { return polariton::operation::OperationResponse { code: Self::op_code(), return_code: e, message: polariton::operation::Typed::Null, params: std::collections::HashMap::default().into(), } } }; } } polariton::operation::OperationResponse { code: Self::op_code(), return_code: 0, message: polariton::operation::Typed::Null, params: params.into(), } } } impl OperationCode for SingleplayerCompleteCampaignProvider { fn op_code() -> u8 { CAMPAIGN_COMPLETE_OP_CODE } } pub(super) fn singleplayer_complete_campaign_provider(init_ctx: &crate::InitConfig) -> SingleplayerCompleteCampaignProvider { let campaign_details: oj_rc_core::persist::config::CompleteCampaignProvider = >::campaign_details(&init_ctx.cubes); SingleplayerCompleteCampaignProvider { campaign_details, factory: init_ctx.factory.clone(), weapon_order: init_ctx.parsers.weapon_order(), cpu_counter: init_ctx.parsers.cpu_counter(), } } const CAMPAIGN_WAVE_NUMBER_PARAM_KEY: u8 = 73; pub(super) fn singleplayer_save_complete_campaign_provider() -> SimpleFunc<68, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result) + Sync + Sync> { //let campaign_details = >::campaign_details(conf); SimpleFunc::new(move |params, user: &crate::UserTy| { let mut params = params.to_dict(); if let Some(Typed::Str(campaign_id)) = params.get(&CAMPAIGN_ID_PARAM_KEY) { if let Some(Typed::Int(campaign_difficulty)) = params.get(&CAMPAIGN_DIFFICULTY_PARAM_KEY) { if let Some(Typed::Int(wave_number)) = params.get(&CAMPAIGN_WAVE_NUMBER_PARAM_KEY) { let user_info = user.user()?; log::info!("User {} completed campaign {} difficulty {} wave {}", user_info.public_id(), campaign_id.string, campaign_difficulty, wave_number); // TODO save wave as completed params.clear(); } } } Ok(params.into()) }) }