mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Implement most of clans functionality; close #89
This commit is contained in:
1 parent
e120b945c8
commit
f0cca11d3c
43 files changed
+2605
-26
No files matched your search
@@ -0,0 +1,76 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Arr};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
const CODE: u8 = 31;
|
||||
|
||||
const CLAN_NAME_PARAM_KEY: u8 = 31; // str; in
|
||||
const CLAN_DESC_PARAM_KEY: u8 = 32; // str; in
|
||||
const CLAN_TYPE_PARAM_KEY: u8 = 34; // int (ClanType); in
|
||||
const CLAN_AVATAR_PARAM_KEY: u8 = 33; // bytes; in
|
||||
const MEMBERS_PARAM_KEY: u8 = 36; // arr of hashmap (ClanMember); out
|
||||
|
||||
pub(super) struct ClanCreator {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanCreator {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(clan_name)) = params.remove(&CLAN_NAME_PARAM_KEY) {
|
||||
if let Some(Typed::Str(clan_desc)) = params.remove(&CLAN_DESC_PARAM_KEY) {
|
||||
if let Some(Typed::Int(clan_ty)) = params.remove(&CLAN_TYPE_PARAM_KEY) {
|
||||
let ty = ClanType::from_u8(clan_ty as u8)
|
||||
.ok_or_else(|| SimpleOpError::with_message(
|
||||
oj_rc_core::data::error_codes::SocialErrorCode::UnexpectedError as i16,
|
||||
format!("Invalid clan type {}", clan_ty),
|
||||
))?;
|
||||
let clavatar = if let Some(Typed::Bytes(clavatar)) = params.remove(&CLAN_AVATAR_PARAM_KEY) {
|
||||
clavatar.vec
|
||||
} else {
|
||||
Vec::default()
|
||||
};
|
||||
let new_clan = oj_rc_core::persist::user::ClanData {
|
||||
name: clan_name.string,
|
||||
description: clan_desc.string,
|
||||
ty: ty.to_core(),
|
||||
size: 0,
|
||||
};
|
||||
let user_info = user.user()?;
|
||||
let new_members = user_info.create_clan(new_clan, clavatar).await?;
|
||||
let mut online_clan_members: std::collections::HashSet<String> = new_members.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
params.insert(MEMBERS_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: polariton::serdes::TypePrefix::HashMap,
|
||||
custom_ty: None,
|
||||
items: new_members.into_iter()
|
||||
.map(|member| ClanMember {
|
||||
is_online: online_clan_members.contains(&member.public_id),
|
||||
username: member.public_id,
|
||||
display_name: member.display_name,
|
||||
member_state: if member.is_confirmed { ClanMemberState::Confirmed } else { ClanMemberState::Invited },
|
||||
use_custom_avatar: member.avatar_id.is_none(),
|
||||
avatar_id: member.avatar_id.unwrap_or_default(),
|
||||
rank: ClanMemberRank::from_core(member.rank),
|
||||
season_xp: member.season_xp,
|
||||
}.as_transmissible())
|
||||
.collect()
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn creat_clan_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanCreator> {
|
||||
SimpleOpImpl::new(ClanCreator {
|
||||
social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Dict};
|
||||
|
||||
const CODE: u8 = 57;
|
||||
|
||||
const EXPERIENCE_TABLE_PARAM_KEY: u8 = 48; // dict string -> int; out
|
||||
const CLAN_NAME_PARAM_KEY: u8 = 31; // str; in
|
||||
|
||||
pub(super) struct ClanExperiencePoller;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanExperiencePoller {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, _user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(clan)) = params.remove(&CLAN_NAME_PARAM_KEY) {
|
||||
log::debug!("Not providing clan experience for clan {} (not implemented)", clan.string);
|
||||
params.insert(EXPERIENCE_TABLE_PARAM_KEY, Typed::Dict(Dict {
|
||||
key_ty: polariton::serdes::TypePrefix::Str,
|
||||
val_ty: polariton::serdes::TypePrefix::Int,
|
||||
items: vec![
|
||||
(Typed::Str("NGniusness".into()), Typed::Int(i32::MAX)),
|
||||
],
|
||||
}));
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_experience_provider() -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanExperiencePoller> {
|
||||
SimpleOpImpl::new(ClanExperiencePoller)
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
use polariton_server::operations::SimpleFunc;
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Arr};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
const CODE: u8 = 33;
|
||||
|
||||
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
|
||||
const CLAN_TYPE_PARAM_KEY: u8 = 34; // out only
|
||||
|
||||
pub(super) fn clan_info_provider<C: Send + Sync>() -> SimpleFunc<33, crate::UserTy, impl (Fn(ParameterTable<C>, &crate::UserTy) -> Result<ParameterTable<C>, i16>) + Sync + Sync, C> {
|
||||
/*pub(super) fn clan_info_provider<C: Send + Sync>() -> SimpleFunc<33, crate::UserTy, impl (Fn(ParameterTable<C>, &crate::UserTy) -> Result<ParameterTable<C>, i16>) + Sync + Sync, C> {
|
||||
SimpleFunc::new(|params, _| {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Str(clan_name)) = params.get(&CLAN_NAME_PARAM_KEY) {
|
||||
@@ -59,4 +61,61 @@ pub(super) fn clan_info_provider<C: Send + Sync>() -> SimpleFunc<33, crate::User
|
||||
|
||||
Ok(params.into())
|
||||
})
|
||||
}*/
|
||||
|
||||
pub(super) struct ClanInfoGetter {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInfoGetter {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let user_info = user.user()?;
|
||||
let clan_info = if let Some(Typed::Str(clan_name)) = params.remove(&CLAN_NAME_PARAM_KEY) {
|
||||
// retrieve info for other clan (return nothing if clan does not exist)
|
||||
log::debug!("Getting {} clan info", clan_name.string);
|
||||
user_info.clan_info(&clan_name.string).await?
|
||||
} else {
|
||||
// retrieve info for user's own clan (return nothing if user not a part of a clan)
|
||||
log::debug!("Getting own clan info");
|
||||
user_info.my_clan_info(true).await?
|
||||
};
|
||||
if let Some((clan_info, members_info)) = clan_info {
|
||||
let mut online_clan_members: std::collections::HashSet<String> = members_info.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
log::debug!("Found clan info for {} ({} members, {} online)", clan_info.name, members_info.len(), online_clan_members.len());
|
||||
params.insert(MEMBERS_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: polariton::serdes::TypePrefix::HashMap, // hashmap
|
||||
custom_ty: None,
|
||||
items: members_info.into_iter()
|
||||
.map(|member| ClanMember {
|
||||
is_online: online_clan_members.contains(&member.public_id),
|
||||
username: member.public_id,
|
||||
display_name: member.display_name,
|
||||
member_state: if member.is_confirmed { ClanMemberState::Confirmed } else { ClanMemberState::Invited },
|
||||
use_custom_avatar: member.avatar_id.is_none(),
|
||||
avatar_id: member.avatar_id.unwrap_or_default(),
|
||||
rank: ClanMemberRank::from_core(member.rank),
|
||||
season_xp: member.season_xp,
|
||||
}.as_transmissible())
|
||||
.collect(),
|
||||
}));
|
||||
params.insert(ROBITS_CONVERSION_PARAM_KEY, Typed::Float(0.5)); // TODO ???
|
||||
params.insert(CLAN_DESCRIPTION_PARAM_KEY, Typed::Str(clan_info.description.into()));
|
||||
params.insert(CLAN_NAME_PARAM_KEY, Typed::Str(clan_info.name.into()));
|
||||
params.insert(CLAN_TYPE_PARAM_KEY, Typed::Int(ClanType::from_core(clan_info.ty).to_u8() as _));
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_info_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInfoGetter> {
|
||||
SimpleOpImpl::new(ClanInfoGetter {
|
||||
social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
use polariton_server::operations::SimpleFunc;
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Arr};
|
||||
|
||||
use crate::data::clan_invite::*;
|
||||
|
||||
//use crate::data::clan_invite::*;
|
||||
|
||||
const PARAM_KEY: u8 = 42;
|
||||
const CODE: u8 = 39;
|
||||
|
||||
pub(super) fn clan_invites_provider<C: Send + Sync>() -> SimpleFunc<39, crate::UserTy, impl (Fn(ParameterTable<C>, &crate::UserTy) -> Result<ParameterTable<C>, i16>) + Sync + Sync, C> {
|
||||
const INVITES_PARAM_KEY: u8 = 42;
|
||||
|
||||
/*pub(super) fn clan_invites_provider<C: Send + Sync>() -> SimpleFunc<39, crate::UserTy, impl (Fn(ParameterTable<C>, &crate::UserTy) -> Result<ParameterTable<C>, i16>) + Sync + Sync, C> {
|
||||
SimpleFunc::new(|params, _| {
|
||||
let mut params = params.to_dict();
|
||||
params.insert(PARAM_KEY, Typed::<C>::Arr(Arr {
|
||||
@@ -25,4 +29,41 @@ pub(super) fn clan_invites_provider<C: Send + Sync>() -> SimpleFunc<39, crate::U
|
||||
}));
|
||||
Ok(params.into())
|
||||
})
|
||||
}*/
|
||||
|
||||
pub(super) struct ClanInviteLister {
|
||||
//social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInviteLister {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let user_info = user.user()?;
|
||||
let invites = user_info.my_clan_invites().await?;
|
||||
let typed_invites = invites.into_iter()
|
||||
.map(|invite| ClanInviteInfo {
|
||||
username: invite.public_id,
|
||||
display_name: invite.display_name,
|
||||
clan_name: invite.clan_name,
|
||||
use_custom_avatar: invite.avatar_id.is_none(),
|
||||
avatar_id: invite.avatar_id.unwrap_or_default(),
|
||||
clan_size: invite.size,
|
||||
}.as_transmissible())
|
||||
.collect();
|
||||
params.insert(INVITES_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: polariton::serdes::TypePrefix::HashMap, // hashmap
|
||||
custom_ty: None,
|
||||
items: typed_invites,
|
||||
}));
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_invites_provider(_init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInviteLister> {
|
||||
SimpleOpImpl::new(ClanInviteLister {
|
||||
//social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Arr};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
const CODE: u8 = 36;
|
||||
|
||||
const CLAN_NAME_PARAM_KEY: u8 = 31; // str; in and out
|
||||
const CLAN_DESCRIPTION_PARAM_KEY: u8 = 32; // str; out
|
||||
const CLAN_TYPE_PARAM_KEY: u8 = 34; // int; out
|
||||
const ROBITS_CONVERSION_PARAM_KEY: u8 = 51; // out only
|
||||
const MEMBERS_PARAM_KEY: u8 = 36; // hashmap (ClanMember); out
|
||||
|
||||
pub(super) struct ClanInviteAccepter {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInviteAccepter {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(clan_name)) = params.remove(&CLAN_NAME_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
log::debug!("User {} wants to accept invite to clan {}", user_info.public_id(), clan_name.string);
|
||||
let (clan_info, members_info) = user_info.join_clan(&clan_name.string).await?;
|
||||
let mut online_clan_members: std::collections::HashSet<String> = members_info.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
log::debug!("Found clan info for {} ({} members, {} online)", clan_info.name, members_info.len(), online_clan_members.len());
|
||||
|
||||
let my_pub_id = user_info.public_id();
|
||||
let self_member = members_info.iter()
|
||||
.find(|mem| mem.public_id == my_pub_id)
|
||||
.unwrap();
|
||||
let event = crate::events::clan_member_data_changed::ClanMemberDataUpdated {
|
||||
member_public_id: my_pub_id.to_owned(),
|
||||
member_display_name: user_info.display_name().to_owned(),
|
||||
avatar_id: self_member.avatar_id,
|
||||
state: Some(crate::data::clan::ClanMemberState::Confirmed),
|
||||
rank: None,
|
||||
is_online: Some(true),
|
||||
};
|
||||
for online_member in online_clan_members.iter() {
|
||||
if online_member == my_pub_id { continue; }
|
||||
self.social.send_event_to(online_member, event.clone()).await;
|
||||
}
|
||||
|
||||
params.insert(MEMBERS_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: polariton::serdes::TypePrefix::HashMap, // hashmap
|
||||
custom_ty: None,
|
||||
items: members_info.into_iter()
|
||||
.map(|member| ClanMember {
|
||||
is_online: online_clan_members.contains(&member.public_id),
|
||||
username: member.public_id,
|
||||
display_name: member.display_name,
|
||||
member_state: if member.is_confirmed { ClanMemberState::Confirmed } else { ClanMemberState::Invited },
|
||||
use_custom_avatar: member.avatar_id.is_none(),
|
||||
avatar_id: member.avatar_id.unwrap_or_default(),
|
||||
rank: ClanMemberRank::from_core(member.rank),
|
||||
season_xp: member.season_xp,
|
||||
}.as_transmissible())
|
||||
.collect(),
|
||||
}));
|
||||
params.insert(ROBITS_CONVERSION_PARAM_KEY, Typed::Float(0.5)); // TODO
|
||||
params.insert(CLAN_DESCRIPTION_PARAM_KEY, Typed::Str(clan_info.description.into()));
|
||||
params.insert(CLAN_NAME_PARAM_KEY, Typed::Str(clan_info.name.into()));
|
||||
params.insert(CLAN_TYPE_PARAM_KEY, Typed::Int(ClanType::from_core(clan_info.ty).to_u8() as _));
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_accept_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInviteAccepter> {
|
||||
SimpleOpImpl::new(ClanInviteAccepter {
|
||||
social: init_ctx.social.clone()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
const CODE: u8 = 45;
|
||||
|
||||
const PUBLIC_ID_PARAM_KEY: u8 = 1; // str; in
|
||||
|
||||
pub(super) struct ClanInviteCanceller {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInviteCanceller {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(invitee)) = params.remove(&PUBLIC_ID_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
log::debug!("User {} wants to cancel invite to user {}", user_info.public_id(), invitee.string);
|
||||
let (clan_info, members_info) = user_info.cancel_invite_to_clan(&invitee.string).await?;
|
||||
let mut online_clan_members: std::collections::HashSet<String> = members_info.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
|
||||
let event = crate::events::clan_invite_cancelled::ClanInviteCancelled {
|
||||
clan_name: clan_info.name,
|
||||
};
|
||||
self.social.send_event_to(&invitee.string, event).await;
|
||||
|
||||
let my_pub_id = user_info.public_id();
|
||||
let event = crate::events::clan_member_left::ClanMemberLeft {
|
||||
leaver_public_id: my_pub_id.to_owned(),
|
||||
new_leader_public_id: None,
|
||||
};
|
||||
for online_member in online_clan_members.iter() {
|
||||
if online_member == my_pub_id { continue; }
|
||||
self.social.send_event_to(online_member, event.clone()).await;
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_cancel_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInviteCanceller> {
|
||||
SimpleOpImpl::new(ClanInviteCanceller {
|
||||
social: init_ctx.social.clone()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
const CODE: u8 = 37;
|
||||
|
||||
const CLAN_NAME_PARAM_KEY: u8 = 31; // str; in and out
|
||||
|
||||
pub(super) struct ClanInviteDecliner {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInviteDecliner {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(clan_name)) = params.remove(&CLAN_NAME_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
log::debug!("User {} wants to decline invite to clan {}", user_info.public_id(), clan_name.string);
|
||||
let members_info = user_info.decline_clan_invite(&clan_name.string).await?;
|
||||
let mut online_clan_members: std::collections::HashSet<String> = members_info.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
|
||||
let my_pub_id = user_info.public_id();
|
||||
let event = crate::events::clan_member_left::ClanMemberLeft {
|
||||
leaver_public_id: my_pub_id.to_owned(),
|
||||
new_leader_public_id: None,
|
||||
};
|
||||
for online_member in online_clan_members.iter() {
|
||||
if online_member == my_pub_id { continue; }
|
||||
self.social.send_event_to(online_member, event.clone()).await;
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_decline_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInviteDecliner> {
|
||||
SimpleOpImpl::new(ClanInviteDecliner {
|
||||
social: init_ctx.social.clone()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::ParameterTable;
|
||||
|
||||
const CODE: u8 = 44;
|
||||
|
||||
pub(super) struct ClanInviteDeclineAller {
|
||||
//social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInviteDeclineAller {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let user_info = user.user()?;
|
||||
log::debug!("User {} wants to decline all clan invites", user_info.public_id());
|
||||
user_info.decline_all_clan_invites().await?;
|
||||
// TODO send clan member leave events to all clans
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_decline_all_provider(_init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInviteDeclineAller> {
|
||||
SimpleOpImpl::new(ClanInviteDeclineAller {
|
||||
//social: init_ctx.social.clone()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
const CODE: u8 = 35;
|
||||
|
||||
const PUBLIC_ID_PARAM_KEY: u8 = 1; // str; in
|
||||
const DISPLAY_NAME_PARAM_KEY: u8 = 75; // str; out
|
||||
const CUSTOM_AVATAR_PARAM_KEY: u8 = 13; // bool; out
|
||||
const AVATAR_ID_PARAM_KEY: u8 = 14; // int; out
|
||||
const SEASON_XP_PARAM_KEY: u8 = 48; // int; out
|
||||
|
||||
pub(super) struct ClanInviter {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanInviter {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(invitee)) = params.remove(&PUBLIC_ID_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
log::debug!("User {} wants to invite {} to their clan", user_info.account_id(), invitee.string);
|
||||
let invitee = user_info.invite_to_clan(&invitee.string).await?;
|
||||
params.insert(PUBLIC_ID_PARAM_KEY, Typed::Str(invitee.public_id.clone().into()));
|
||||
params.insert(DISPLAY_NAME_PARAM_KEY, Typed::Str(invitee.display_name.clone().into()));
|
||||
params.insert(CUSTOM_AVATAR_PARAM_KEY, Typed::Bool(invitee.avatar_id.is_none()));
|
||||
params.insert(AVATAR_ID_PARAM_KEY, Typed::Int(invitee.avatar_id.unwrap_or_default()));
|
||||
params.insert(SEASON_XP_PARAM_KEY, Typed::Int(invitee.season_xp));
|
||||
if let Some((my_clan, my_clan_members)) = user_info.my_clan_info(true).await? {
|
||||
let my_pub_id = user_info.public_id();
|
||||
let my_soc_info = user_info.list_social_info(&[my_pub_id.to_owned()]).await?;
|
||||
let event = crate::events::clan_invite_received::ClanInviteReceived {
|
||||
inviter_public_id: my_pub_id.to_owned(),
|
||||
inviter_display_name: user_info.display_name().to_owned(),
|
||||
clan_size: my_clan.size,
|
||||
clan_name: my_clan.name,
|
||||
avatar_id: my_soc_info.first().and_then(|x| x.avatar_id),
|
||||
};
|
||||
self.social.send_event_to(&invitee.public_id, event).await;
|
||||
|
||||
let event = crate::events::clan_member_joined::ClanMemberJoined {
|
||||
joiner_public_id: invitee.public_id,
|
||||
joiner_display_name: invitee.display_name,
|
||||
avatar_id: invitee.avatar_id,
|
||||
state: crate::data::clan::ClanMemberState::Invited,
|
||||
season_xp: invitee.season_xp,
|
||||
};
|
||||
for member in my_clan_members {
|
||||
if member.public_id == my_pub_id { continue; }
|
||||
self.social.send_event_to(&member.public_id, event.clone()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn invite_to_clan_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanInviter> {
|
||||
SimpleOpImpl::new(ClanInviter {
|
||||
social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Arr};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
const CODE: u8 = 34;
|
||||
|
||||
const CLAN_NAME_PARAM_KEY: u8 = 31; // str; in and out
|
||||
const CLAN_DESCRIPTION_PARAM_KEY: u8 = 32; // str; out
|
||||
const CLAN_TYPE_PARAM_KEY: u8 = 34; // int; out
|
||||
const ROBITS_CONVERSION_PARAM_KEY: u8 = 51; // out only
|
||||
const MEMBERS_PARAM_KEY: u8 = 36; // hashmap (ClanMember); out
|
||||
|
||||
pub(super) struct ClanJoiner {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanJoiner {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(clan_name)) = params.remove(&CLAN_NAME_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
log::debug!("User {} wants to join clan {}", user_info.public_id(), clan_name.string);
|
||||
let (clan_info, members_info) = user_info.join_clan(&clan_name.string).await?;
|
||||
let mut online_clan_members: std::collections::HashSet<String> = members_info.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
log::debug!("Found clan info for {} ({} members, {} online)", clan_info.name, members_info.len(), online_clan_members.len());
|
||||
|
||||
let my_pub_id = user_info.public_id();
|
||||
let self_member = members_info.iter()
|
||||
.find(|mem| mem.public_id == my_pub_id)
|
||||
.unwrap();
|
||||
let event = crate::events::clan_member_joined::ClanMemberJoined {
|
||||
joiner_public_id: my_pub_id.to_owned(),
|
||||
joiner_display_name: user_info.display_name().to_owned(),
|
||||
avatar_id: self_member.avatar_id,
|
||||
state: crate::data::clan::ClanMemberState::Confirmed,
|
||||
season_xp: 0,
|
||||
};
|
||||
for online_member in online_clan_members.iter() {
|
||||
if online_member == my_pub_id { continue; }
|
||||
self.social.send_event_to(online_member, event.clone()).await;
|
||||
}
|
||||
|
||||
params.insert(MEMBERS_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: polariton::serdes::TypePrefix::HashMap, // hashmap
|
||||
custom_ty: None,
|
||||
items: members_info.into_iter()
|
||||
.map(|member| ClanMember {
|
||||
is_online: online_clan_members.contains(&member.public_id),
|
||||
username: member.public_id,
|
||||
display_name: member.display_name,
|
||||
member_state: if member.is_confirmed { ClanMemberState::Confirmed } else { ClanMemberState::Invited },
|
||||
use_custom_avatar: member.avatar_id.is_none(),
|
||||
avatar_id: member.avatar_id.unwrap_or_default(),
|
||||
rank: ClanMemberRank::from_core(member.rank),
|
||||
season_xp: member.season_xp,
|
||||
}.as_transmissible())
|
||||
.collect(),
|
||||
}));
|
||||
params.insert(ROBITS_CONVERSION_PARAM_KEY, Typed::Float(0.5)); // TODO
|
||||
params.insert(CLAN_DESCRIPTION_PARAM_KEY, Typed::Str(clan_info.description.into()));
|
||||
params.insert(CLAN_NAME_PARAM_KEY, Typed::Str(clan_info.name.into()));
|
||||
params.insert(CLAN_TYPE_PARAM_KEY, Typed::Int(ClanType::from_core(clan_info.ty).to_u8() as _));
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_join_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanJoiner> {
|
||||
SimpleOpImpl::new(ClanJoiner {
|
||||
social: init_ctx.social.clone()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::ParameterTable;
|
||||
|
||||
const CODE: u8 = 40;
|
||||
|
||||
pub(super) struct ClanLeaver {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanLeaver {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let user_info = user.user()?;
|
||||
let mut members = if let Some((_clan, members)) = user_info.my_clan_info(true).await? {
|
||||
members.into_iter().map(|mem| mem.public_id).collect()
|
||||
} else {
|
||||
std::collections::HashSet::default()
|
||||
};
|
||||
log::debug!("User {} wants to leave their clan", user_info.public_id());
|
||||
user_info.leave_clan().await?;
|
||||
self.social.filter_online_only(&mut members).await;
|
||||
let my_pub_id = user_info.public_id();
|
||||
let event = crate::events::clan_member_left::ClanMemberLeft {
|
||||
leaver_public_id: my_pub_id.to_owned(),
|
||||
new_leader_public_id: None,
|
||||
};
|
||||
for member in members {
|
||||
if member == my_pub_id { continue; }
|
||||
self.social.send_event_to(&member, event.clone()).await;
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_leave_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanLeaver> {
|
||||
SimpleOpImpl::new(ClanLeaver {
|
||||
social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
const CODE: u8 = 41;
|
||||
|
||||
const USERNAME_PARAM_KEY: u8 = 1; // str; in
|
||||
|
||||
pub(super) struct ClanRemover {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanRemover {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(to_remove)) = params.remove(&USERNAME_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
let mut members = if let Some((_clan, members)) = user_info.my_clan_info(true).await? {
|
||||
members.into_iter().map(|mem| mem.public_id).collect()
|
||||
} else {
|
||||
std::collections::HashSet::default()
|
||||
};
|
||||
log::debug!("User {} wants to remove {} from their clan", user_info.public_id(), to_remove.string);
|
||||
user_info.remove_user_from_clan(&to_remove.string).await?;
|
||||
self.social.send_event_to(&to_remove.string, crate::events::clan_member_removed::ClanMemberRemoved).await;
|
||||
self.social.filter_online_only(&mut members).await;
|
||||
let my_pub_id = user_info.public_id();
|
||||
let event = crate::events::clan_member_left::ClanMemberLeft {
|
||||
leaver_public_id: to_remove.string.clone(),
|
||||
new_leader_public_id: None,
|
||||
};
|
||||
for member in members {
|
||||
if member == to_remove.string { continue; }
|
||||
if member == my_pub_id { continue; }
|
||||
self.social.send_event_to(&member, event.clone()).await;
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_remove_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanRemover> {
|
||||
SimpleOpImpl::new(ClanRemover {
|
||||
social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
const CODE: u8 = 38;
|
||||
|
||||
const PUBLIC_ID_PARAM_KEY: u8 = 1; // str; in and out
|
||||
const MEMBER_RANK_PARAM_KEY: u8 = 38; // int enum (ClanMemberRank); in
|
||||
|
||||
pub(super) struct ClanMemberRankChanger {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanMemberRankChanger {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
if let Some(Typed::Str(member)) = params.remove(&PUBLIC_ID_PARAM_KEY) {
|
||||
if let Some(Typed::Int(new_rank)) = params.remove(&MEMBER_RANK_PARAM_KEY) {
|
||||
let new_rank = crate::data::clan::ClanMemberRank::from_u8(new_rank as _)
|
||||
.ok_or_else(|| SimpleOpError::with_message(
|
||||
oj_rc_core::data::error_codes::SocialErrorCode::UnexpectedError as i16,
|
||||
format!("Invalid clan member rank {}", new_rank),
|
||||
))?;
|
||||
let user_info = user.user()?;
|
||||
let my_pub_id = user_info.public_id();
|
||||
log::debug!("User {} wants to update user {} to clan member rank {:?}", my_pub_id, member.string, new_rank);
|
||||
let members_info = user_info.update_clan_member(&member.string, new_rank.to_core()).await?;
|
||||
let mut online_clan_members: std::collections::HashSet<String> = members_info.iter()
|
||||
.map(|mem| mem.public_id.clone())
|
||||
.collect();
|
||||
self.social.filter_online_only(&mut online_clan_members).await;
|
||||
let target_member_opt = members_info.iter()
|
||||
.find(|mem| mem.public_id == member.string);
|
||||
if let Some(target_member) = target_member_opt {
|
||||
let event = crate::events::clan_member_data_changed::ClanMemberDataUpdated {
|
||||
member_public_id: target_member.public_id.clone(),
|
||||
member_display_name: target_member.display_name.clone(),
|
||||
avatar_id: target_member.avatar_id,
|
||||
state: None,
|
||||
rank: Some(new_rank),
|
||||
is_online: Some(true),
|
||||
};
|
||||
for online_member in online_clan_members {
|
||||
if online_member == my_pub_id { continue; }
|
||||
//if online_member == member.string { continue; }
|
||||
self.social.send_event_to(&online_member, event.clone()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_rank_change_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanMemberRankChanger> {
|
||||
SimpleOpImpl::new(ClanMemberRankChanger {
|
||||
social: init_ctx.social.clone()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
const CODE: u8 = 42;
|
||||
|
||||
const CLAN_DESC_PARAM_KEY: u8 = 32; // str; in
|
||||
const CLAN_TYPE_PARAM_KEY: u8 = 34; // int (ClanType); in
|
||||
const CLAN_AVATAR_PARAM_KEY: u8 = 33; // bytes; in
|
||||
|
||||
pub(super) struct ClanDataChanger {
|
||||
social: std::sync::Arc<crate::SocialMesh>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClanDataChanger {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let new_ty = if let Some(Typed::Int(clan_ty)) = params.remove(&CLAN_TYPE_PARAM_KEY) {
|
||||
let ty = ClanType::from_u8(clan_ty as u8)
|
||||
.ok_or_else(|| SimpleOpError::with_message(
|
||||
oj_rc_core::data::error_codes::SocialErrorCode::UnexpectedError as i16,
|
||||
format!("Invalid clan type {}", clan_ty),
|
||||
))?;
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let new_clavatar = if let Some(Typed::Bytes(clavatar)) = params.remove(&CLAN_AVATAR_PARAM_KEY) {
|
||||
if clavatar.vec.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(clavatar.vec)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let new_desc = if let Some(Typed::Str(clan_desc)) = params.remove(&CLAN_DESC_PARAM_KEY) {
|
||||
// (technically this is a client bug)
|
||||
// when the game client updates a different field, the description will get sent as a zero-length string
|
||||
// which is impossible to differentiate from someone saving the description as zero-length
|
||||
// null/non-existent *should* be different than an empty string
|
||||
// So, let's try the closest guess the server can achieve:
|
||||
// => assume a zero-length string means null *unless* all the other fields are null
|
||||
if clan_desc.string.is_empty() && (new_ty.is_some() || new_clavatar.is_some()) {
|
||||
None
|
||||
} else {
|
||||
Some(clan_desc.string)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if new_desc.is_none() && new_ty.is_none() && new_clavatar.is_none() {
|
||||
log::debug!("Got clan data change no-op (doing nothing)");
|
||||
return Ok(params);
|
||||
}
|
||||
let user_info = user.user()?;
|
||||
let members = user_info.update_clan(
|
||||
None,
|
||||
new_desc.clone(),
|
||||
new_ty.map(|x| x.to_core()),
|
||||
new_clavatar,
|
||||
).await?;
|
||||
let mut online_members = members.into_iter().map(|mem| mem.public_id).collect();
|
||||
self.social.filter_online_only(&mut online_members).await;
|
||||
let my_pub_id = user_info.public_id();
|
||||
let event = crate::events::clan_data_changed::ClanDataUpdated {
|
||||
description: new_desc,
|
||||
ty: new_ty,
|
||||
};
|
||||
for member in online_members {
|
||||
if member == my_pub_id { continue; }
|
||||
self.social.send_event_to(&member, event.clone()).await;
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn update_clan_provider(init_ctx: &crate::InitConfig) -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClanDataChanger> {
|
||||
SimpleOpImpl::new(ClanDataChanger {
|
||||
social: init_ctx.social.clone(),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
const CODE: u8 = 43;
|
||||
|
||||
const CLAN_NAME_PARAM_KEY: u8 = 31; // in and out
|
||||
const CLAN_DESCRIPTION_PARAM_KEY: u8 = 32; // out only
|
||||
const CLAN_TYPE_PARAM_KEY: u8 = 34; // out only
|
||||
|
||||
pub(super) struct MyClanInfoGetter {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for MyClanInfoGetter {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let user_info = user.user()?;
|
||||
let clan_info = user_info.my_clan_info(false).await?;
|
||||
if let Some((clan_info, _members_info)) = clan_info {
|
||||
log::debug!("Found my clan info for {}", clan_info.name);
|
||||
params.insert(CLAN_DESCRIPTION_PARAM_KEY, Typed::Str(clan_info.description.into()));
|
||||
params.insert(CLAN_NAME_PARAM_KEY, Typed::Str(clan_info.name.into()));
|
||||
params.insert(CLAN_TYPE_PARAM_KEY, Typed::Int(ClanType::from_core(clan_info.ty).to_u8() as _));
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn clan_info_provider() -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, MyClanInfoGetter> {
|
||||
SimpleOpImpl::new(MyClanInfoGetter {})
|
||||
}
|
||||
@@ -23,6 +23,19 @@ mod platoon_leave;
|
||||
mod platoon_kick;
|
||||
mod platoon_invites;
|
||||
mod platoon_status;
|
||||
mod clan_create;
|
||||
mod clan_my_info;
|
||||
mod clan_join;
|
||||
mod clan_leave;
|
||||
mod clan_member_remove;
|
||||
mod clan_modify;
|
||||
mod clan_invite_to;
|
||||
mod clan_invite_accept;
|
||||
mod clan_invite_decline;
|
||||
mod clan_invite_decline_all;
|
||||
mod clan_invite_cancel;
|
||||
mod clan_member_rerank;
|
||||
mod clan_experience_poll;
|
||||
|
||||
use polariton_server::operations::OperationsHandler;
|
||||
|
||||
@@ -30,14 +43,12 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy,
|
||||
OperationsHandler::<crate::UserTy, crate::data::custom::CustomType>::new()
|
||||
.modify(oj_rc_core::polariton::RcOpModifier)
|
||||
.add(more_auth::more_lobby_auth(init_ctx))
|
||||
//.add(polariton_server::operations::Ack::<33, _>::default()) // get user clan info (this is equivalent to not being in a clan)
|
||||
.add(friend_list::friends_provider(init_ctx)) // TODO friend object parsing Token: 0x0200169C RID: 5788
|
||||
.add(settings::settings_provider()) // TODO save settings persistently
|
||||
.add(polariton_server::operations::Ack::<43, _>::default()) // get my clan info (this is equivalent to not being in a clan)
|
||||
.add(clan_invite::clan_invites_provider())
|
||||
//.add(polariton_server::operations::Ack::<19, _>::default()) // get pending platoon invite (this is equivalent to having no pending invite)
|
||||
.add(clan_my_info::clan_info_provider())
|
||||
.add(clan_invite::clan_invites_provider(init_ctx))
|
||||
.add(platoon_invites::platoon_pending_provider(init_ctx))
|
||||
.add(clan_info::clan_info_provider())
|
||||
.add(clan_info::clan_info_provider(init_ctx))
|
||||
.add(search_clan::search_clans_provider())
|
||||
.add(polariton_server::operations::Ack::<52, _>::default()) // validate pending season rewards (this just always needs to be ack-ed)
|
||||
.add(season_rewards::season_rewards_provider())
|
||||
@@ -60,4 +71,16 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy,
|
||||
.add(platoon_leave::platoon_leave_provider(init_ctx))
|
||||
.add(platoon_kick::platoon_kick_provider(init_ctx))
|
||||
.add(platoon_status::platoon_update_provider(init_ctx))
|
||||
.add(clan_create::creat_clan_provider(init_ctx))
|
||||
.add(clan_join::clan_join_provider(init_ctx))
|
||||
.add(clan_leave::clan_leave_provider(init_ctx))
|
||||
.add(clan_member_remove::clan_remove_provider(init_ctx))
|
||||
.add(clan_modify::update_clan_provider(init_ctx))
|
||||
.add(clan_invite_to::invite_to_clan_provider(init_ctx))
|
||||
.add(clan_invite_accept::clan_accept_provider(init_ctx))
|
||||
.add(clan_invite_decline::clan_decline_provider(init_ctx))
|
||||
.add(clan_invite_decline_all::clan_decline_all_provider(init_ctx))
|
||||
.add(clan_invite_cancel::clan_cancel_provider(init_ctx))
|
||||
.add(clan_member_rerank::clan_rank_change_provider(init_ctx))
|
||||
.add(clan_experience_poll::clan_experience_provider())
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
use polariton_server::operations::SimpleFunc;
|
||||
use polariton_server::operations::{SimpleOpError, SimpleOperation, SimpleOpImpl};
|
||||
use polariton::operation::{ParameterTable, Typed, Arr};
|
||||
|
||||
use crate::data::clan::*;
|
||||
|
||||
// params in TODO
|
||||
const CODE: u8 = 32;
|
||||
|
||||
// params in
|
||||
const STRING_PARAM_KEY: u8 = 39;
|
||||
/*const DAYS_SINCE_ACTIVE_PARAM_KEY: u8 = 40;
|
||||
const DAYS_SINCE_ACTIVE_PARAM_KEY: u8 = 40;
|
||||
const START_RANGE_PARAM_KEY: u8 = 41;
|
||||
const END_RANGE_PARAM_KEY: u8 = 43;
|
||||
const TYPES_PARAM_KEY: u8 = 34;*/
|
||||
const TYPES_PARAM_KEY: u8 = 34;
|
||||
|
||||
// params out
|
||||
const RESULTS_PARAM_KEY: u8 = 42;
|
||||
|
||||
pub(super) fn search_clans_provider<C: Send + Sync>() -> SimpleFunc<32, crate::UserTy, impl (Fn(ParameterTable<C>, &crate::UserTy) -> Result<ParameterTable<C>, i16>) + Sync + Sync, C> {
|
||||
/*pub(super) fn search_clans_provider<C: Send + Sync>() -> SimpleFunc<32, crate::UserTy, impl (Fn(ParameterTable<C>, &crate::UserTy) -> Result<ParameterTable<C>, i16>) + Sync + Sync, C> {
|
||||
SimpleFunc::new(|params, _| {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Str(s)) = params.get(&STRING_PARAM_KEY) {
|
||||
@@ -35,4 +37,69 @@ pub(super) fn search_clans_provider<C: Send + Sync>() -> SimpleFunc<32, crate::U
|
||||
}));
|
||||
Ok(params.into())
|
||||
})
|
||||
}*/
|
||||
|
||||
pub(super) struct ClansSearcher {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SimpleOperation<crate::data::custom::CustomType> for ClansSearcher {
|
||||
type User = crate::UserTy;
|
||||
const CODE: u8 = CODE;
|
||||
|
||||
async fn handle(&self, mut params: ParameterTable<crate::data::custom::CustomType>, user: &Self::User) -> Result<ParameterTable<crate::data::custom::CustomType>, SimpleOpError> {
|
||||
let search_string = if let Some(Typed::Str(search)) = params.remove(&STRING_PARAM_KEY) {
|
||||
search.string
|
||||
} else {
|
||||
String::default()
|
||||
};
|
||||
if let Some(Typed::Int(days_since_active)) = params.remove(&DAYS_SINCE_ACTIVE_PARAM_KEY) {
|
||||
if let Some(Typed::Int(start_range)) = params.remove(&START_RANGE_PARAM_KEY) {
|
||||
if let Some(Typed::Int(end_range)) = params.remove(&END_RANGE_PARAM_KEY) {
|
||||
if let Some(Typed::Arr(clan_types)) = params.remove(&TYPES_PARAM_KEY) {
|
||||
let mut types = Vec::with_capacity(clan_types.items.len());
|
||||
for item in clan_types.items {
|
||||
if let Typed::Int(ty) = item {
|
||||
types.push(
|
||||
crate::data::clan::ClanType::from_u8(ty as u8)
|
||||
.ok_or_else(|| SimpleOpError::with_message(
|
||||
oj_rc_core::data::error_codes::SocialErrorCode::UnexpectedError as i16,
|
||||
format!("Invalid clan type {}", ty),
|
||||
))?
|
||||
.to_core()
|
||||
);
|
||||
}
|
||||
}
|
||||
let search_query = oj_rc_core::persist::user::ClanSearchQuery {
|
||||
search_string,
|
||||
days_since_active,
|
||||
start_range,
|
||||
end_range,
|
||||
types,
|
||||
};
|
||||
let user_info = user.user()?;
|
||||
log::debug!("Searching for clans with query {:?}", search_query);
|
||||
let results = user_info.search_clan(search_query).await?;
|
||||
log::debug!("Got {} clans from search", results.len());
|
||||
params.insert(RESULTS_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: polariton::serdes::TypePrefix::HashMap, // hashmap
|
||||
custom_ty: None,
|
||||
items: results.into_iter()
|
||||
.map(|clan| ClanInfo {
|
||||
clan_name: clan.name,
|
||||
clan_description: clan.description,
|
||||
clan_type: ClanType::from_core(clan.ty),
|
||||
clan_size: clan.size,
|
||||
}.as_transmissible())
|
||||
.collect(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn search_clans_provider() -> SimpleOpImpl<crate::data::custom::CustomType, crate::UserTy, ClansSearcher> {
|
||||
SimpleOpImpl::new(ClansSearcher {})
|
||||
}
|
||||
Reference in new issue
Block a user