Allow corps to consent to fight each other.
Note it doesn't actually do anything yet - that's coming!
This commit is contained in:
parent
d35bbbad53
commit
7d1d6675b7
@ -756,6 +756,18 @@ impl DBTrans {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn find_corp_consent_by_parties_type(&self, consenting: &CorpId, consented: &CorpId,
|
||||
consent_type: &ConsentType) -> DResult<Option<Consent>> {
|
||||
match self.pg_trans()?.query_opt(
|
||||
"SELECT details FROM corp_consent WHERE consenting_corp = $1 AND \
|
||||
consented_corp = $2 AND consent_type = $3",
|
||||
&[&consenting.0, &consented.0, &ConsentType::to_str(consent_type)]
|
||||
).await? {
|
||||
None => Ok(None),
|
||||
Some(row) => Ok(Some(serde_json::from_value(row.get(0))?))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn revoke_until_death_consent(&self, party: &str) -> DResult<()> {
|
||||
self.pg_trans()?.execute(
|
||||
"DELETE FROM user_consent WHERE (consenting_user = $1 OR \
|
||||
@ -763,6 +775,16 @@ impl DBTrans {
|
||||
details->>'until_death'='true'",
|
||||
&[&party]
|
||||
).await?;
|
||||
self.pg_trans()?.execute(
|
||||
"DELETE FROM corp_consent cc USING
|
||||
corp_membership cm
|
||||
WHERE (cc.consenting_corp = cm.corp_id OR cc.consented_corp = cm.corp_id) AND \
|
||||
cm.member_username = $1 AND \
|
||||
cm.details->>'joined_at' IS NOT NULL AND \
|
||||
cc.consent_type = 'fight' AND \
|
||||
cc.details->>'until_death'='true'",
|
||||
&[&party]
|
||||
).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -774,6 +796,14 @@ impl DBTrans {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_expired_corp_consent(&self) -> DResult<()> {
|
||||
self.pg_trans()?.execute(
|
||||
"DELETE FROM corp_consent WHERE details->>'expires' < $1",
|
||||
&[&Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Nanos, true)]
|
||||
).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_user_consent(&self,
|
||||
consenting: &str,
|
||||
consented: &str,
|
||||
@ -786,6 +816,18 @@ impl DBTrans {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_corp_consent(&self,
|
||||
consenting: &CorpId,
|
||||
consented: &CorpId,
|
||||
consent_type: &ConsentType) -> DResult<()> {
|
||||
self.pg_trans()?.execute(
|
||||
"DELETE FROM corp_consent WHERE consenting_corp = $1 AND \
|
||||
consented_corp = $2 AND consent_type = $3",
|
||||
&[&consenting.0, &consented.0, &ConsentType::to_str(consent_type)]
|
||||
).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn upsert_user_consent(&self,
|
||||
consenting: &str,
|
||||
consented: &str,
|
||||
@ -800,7 +842,22 @@ impl DBTrans {
|
||||
&serde_json::to_value(details)?]).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub async fn upsert_corp_consent(&self,
|
||||
consenting: &CorpId,
|
||||
consented: &CorpId,
|
||||
consent_type: &ConsentType,
|
||||
details: &Consent
|
||||
) -> DResult<()> {
|
||||
self.pg_trans()?
|
||||
.execute("INSERT INTO corp_consent (consenting_corp, consented_corp, consent_type, details) VALUES ($1, $2, $3, $4) \
|
||||
ON CONFLICT (consenting_corp, consented_corp, consent_type) DO UPDATE SET \
|
||||
details = EXCLUDED.details",
|
||||
&[&consenting.0, &consented.0, &ConsentType::to_str(consent_type),
|
||||
&serde_json::to_value(details)?]).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn find_corp_by_name(&self, name: &str) -> DResult<Option<(CorpId, Corp)>> {
|
||||
Ok(match self.pg_trans()?
|
||||
.query_opt("SELECT corp_id, details FROM corps WHERE LOWER(details->>'name') = $1",
|
||||
|
@ -16,7 +16,7 @@ mod allow;
|
||||
pub mod attack;
|
||||
mod buy;
|
||||
mod c;
|
||||
mod corp;
|
||||
pub mod corp;
|
||||
pub mod drop;
|
||||
pub mod get;
|
||||
mod describe;
|
||||
|
@ -5,18 +5,22 @@ use super::{
|
||||
UResult,
|
||||
user_error,
|
||||
get_player_item_or_fail,
|
||||
get_user_or_fail,
|
||||
search_item_for_user,
|
||||
parsing
|
||||
parsing,
|
||||
corp::check_corp_perm,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use crate::{
|
||||
models::{
|
||||
consent::{Consent, ConsentType, ConsentStatus, FightConsent},
|
||||
corp::{CorpPermission, CorpCommType},
|
||||
item::Item
|
||||
},
|
||||
db::ItemSearchParams,
|
||||
static_content::room::room_map_by_code,
|
||||
};
|
||||
use ansi::ansi;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ConsentTarget<'t> {
|
||||
@ -669,6 +673,127 @@ async fn handle_user_consent(ctx: &mut VerbContext<'_>, source_player: &Item,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_corp_consent(ctx: &mut VerbContext<'_>, source_player: &Item,
|
||||
from_corp: &str,
|
||||
to_corp: &str,
|
||||
is_allow: bool,
|
||||
cmd: &AllowCommand<'_>
|
||||
) -> UResult<()> {
|
||||
let user = get_user_or_fail(ctx)?;
|
||||
let (from_corp_id, from_corp, mem) =
|
||||
match ctx.trans.match_user_corp_by_name(from_corp, &user.username).await? {
|
||||
None => user_error("You don't seem to belong to a matching corp!".to_owned())?,
|
||||
Some(c) => c
|
||||
};
|
||||
let (to_corp_id, to_corp) = match ctx.trans.find_corp_by_name(to_corp).await? {
|
||||
None => user_error("I didn't find the corp you want to fight against.".to_owned())?,
|
||||
Some(c) => c
|
||||
};
|
||||
if !check_corp_perm(&CorpPermission::War, &mem) {
|
||||
user_error("You don't have permission to declare war on behalf of that corp.".to_owned())?;
|
||||
}
|
||||
|
||||
ctx.trans.delete_expired_corp_consent().await?;
|
||||
|
||||
let current_consent = ctx.trans.find_corp_consent_by_parties_type(
|
||||
&from_corp_id,
|
||||
&to_corp_id,
|
||||
&cmd.consent_type
|
||||
).await?;
|
||||
let converse_consent = if cmd.consent_type == ConsentType::Fight {
|
||||
ctx.trans.find_corp_consent_by_parties_type(
|
||||
&to_corp_id,
|
||||
&from_corp_id,
|
||||
&cmd.consent_type
|
||||
).await?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let update = compute_new_consent_state(
|
||||
&to_corp.name,
|
||||
"their",
|
||||
&to_corp.name,
|
||||
"their",
|
||||
&("against ".to_owned() + &to_corp.name + " by " + &from_corp.name),
|
||||
&cmd.consent_type, &cmd.consent_details,
|
||||
¤t_consent, &converse_consent, is_allow
|
||||
);
|
||||
|
||||
match update.new_consent.as_ref() {
|
||||
None => ctx.trans.delete_corp_consent(
|
||||
&from_corp_id,
|
||||
&to_corp_id,
|
||||
&cmd.consent_type
|
||||
).await?,
|
||||
Some(consent) => ctx.trans.upsert_corp_consent(
|
||||
&from_corp_id,
|
||||
&to_corp_id,
|
||||
&cmd.consent_type,
|
||||
consent
|
||||
).await?,
|
||||
}
|
||||
if update.mirror_to_counterparty {
|
||||
match update.new_consent.as_ref() {
|
||||
None => ctx.trans.delete_corp_consent(
|
||||
&to_corp_id,
|
||||
&from_corp_id,
|
||||
&cmd.consent_type
|
||||
).await?,
|
||||
Some(consent) => ctx.trans.upsert_corp_consent(
|
||||
&to_corp_id,
|
||||
&from_corp_id,
|
||||
&cmd.consent_type,
|
||||
consent
|
||||
).await?,
|
||||
}
|
||||
}
|
||||
|
||||
match update.first_party_message {
|
||||
None => {},
|
||||
Some(msg) =>
|
||||
if update.counterparty_message.is_some() {
|
||||
let details_str = cmd.consent_details.as_string(&ConsentType::Fight);
|
||||
let details_str = if details_str != "" {
|
||||
format!(" ({})", &details_str.trim())
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
let action_str = if is_allow { "consented" } else { "withdrew consent" };
|
||||
// If it goes to both corps, it is a diplomatic message so goes to whole source corp.
|
||||
ctx.trans.broadcast_to_corp(
|
||||
&from_corp_id,
|
||||
&CorpCommType::Consent,
|
||||
None,
|
||||
&format!(ansi!("<red>{} {} to fight{} against {} on behalf \
|
||||
of {}<reset>, with result: {}\n"),
|
||||
&source_player.display_for_sentence(false, 1, true),
|
||||
action_str,
|
||||
&details_str,
|
||||
&to_corp.name,
|
||||
&from_corp.name,
|
||||
&msg
|
||||
)
|
||||
).await?;
|
||||
} else {
|
||||
ctx.trans.queue_for_session(&ctx.session, Some(&(msg + "\n"))).await?;
|
||||
}
|
||||
}
|
||||
match update.counterparty_message {
|
||||
None => {},
|
||||
Some(msg) => {
|
||||
ctx.trans.broadcast_to_corp(
|
||||
&to_corp_id,
|
||||
&CorpCommType::Consent,
|
||||
None,
|
||||
&format!(ansi!("<yellow>Your wristpad buzzes with an corporate announcement to {}:<reset> {}\n"), &to_corp.name, &msg)
|
||||
).await?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct Verb;
|
||||
#[async_trait]
|
||||
impl UserVerb for Verb {
|
||||
@ -699,8 +824,8 @@ impl UserVerb for Verb {
|
||||
}
|
||||
}
|
||||
match cmd.consent_target {
|
||||
ConsentTarget::CorpTarget { .. } => user_error(
|
||||
"Corporate allow/disallow not implemented yet".to_owned())?,
|
||||
ConsentTarget::CorpTarget { from_corp, to_corp } =>
|
||||
handle_corp_consent(ctx, &player_item, from_corp, to_corp, is_allow, &cmd).await?,
|
||||
ConsentTarget::UserTarget { to_user } =>
|
||||
handle_user_consent(ctx, &player_item, to_user, is_allow, &cmd).await?
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use std::collections::BTreeSet;
|
||||
use itertools::Itertools;
|
||||
use humantime;
|
||||
|
||||
fn check_corp_perm(perm: &CorpPermission, mem: &CorpMembership) -> bool {
|
||||
pub fn check_corp_perm(perm: &CorpPermission, mem: &CorpMembership) -> bool {
|
||||
mem.permissions.iter().any(|p| *p == CorpPermission::Holder || *p == *perm)
|
||||
}
|
||||
|
||||
@ -617,7 +617,7 @@ async fn corp_subscribe(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<(
|
||||
async fn corp_unsubscribe(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()> {
|
||||
let (subs, remaining) = match remaining.split_once(" from ") {
|
||||
None => user_error("Usage: corp unsubscribe commtype commtype ... from corpname\n\
|
||||
commtypes: chat notice connect reward death".to_owned())?,
|
||||
commtypes: chat notice connect reward death consent".to_owned())?,
|
||||
Some(v) => v
|
||||
};
|
||||
let mut subs_del = BTreeSet::<CorpCommType>::new();
|
||||
|
@ -47,6 +47,7 @@ pub enum CorpCommType {
|
||||
Connect,
|
||||
Reward,
|
||||
Death,
|
||||
Consent,
|
||||
}
|
||||
|
||||
impl CorpCommType {
|
||||
@ -58,6 +59,7 @@ impl CorpCommType {
|
||||
"connect" => Some(Connect),
|
||||
"reward" => Some(Reward),
|
||||
"death" => Some(Death),
|
||||
"consent" => Some(Consent),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
@ -69,6 +71,7 @@ impl CorpCommType {
|
||||
Connect => "connect",
|
||||
Reward => "reward",
|
||||
Death => "death",
|
||||
Consent => "consent",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,6 +129,7 @@ impl Default for CorpMembership {
|
||||
Connect,
|
||||
Reward,
|
||||
Death,
|
||||
Consent,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user