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<()> {
|
pub async fn revoke_until_death_consent(&self, party: &str) -> DResult<()> {
|
||||||
self.pg_trans()?.execute(
|
self.pg_trans()?.execute(
|
||||||
"DELETE FROM user_consent WHERE (consenting_user = $1 OR \
|
"DELETE FROM user_consent WHERE (consenting_user = $1 OR \
|
||||||
@ -763,6 +775,16 @@ impl DBTrans {
|
|||||||
details->>'until_death'='true'",
|
details->>'until_death'='true'",
|
||||||
&[&party]
|
&[&party]
|
||||||
).await?;
|
).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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,6 +796,14 @@ impl DBTrans {
|
|||||||
Ok(())
|
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,
|
pub async fn delete_user_consent(&self,
|
||||||
consenting: &str,
|
consenting: &str,
|
||||||
consented: &str,
|
consented: &str,
|
||||||
@ -786,6 +816,18 @@ impl DBTrans {
|
|||||||
Ok(())
|
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,
|
pub async fn upsert_user_consent(&self,
|
||||||
consenting: &str,
|
consenting: &str,
|
||||||
consented: &str,
|
consented: &str,
|
||||||
@ -800,7 +842,22 @@ impl DBTrans {
|
|||||||
&serde_json::to_value(details)?]).await?;
|
&serde_json::to_value(details)?]).await?;
|
||||||
Ok(())
|
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)>> {
|
pub async fn find_corp_by_name(&self, name: &str) -> DResult<Option<(CorpId, Corp)>> {
|
||||||
Ok(match self.pg_trans()?
|
Ok(match self.pg_trans()?
|
||||||
.query_opt("SELECT corp_id, details FROM corps WHERE LOWER(details->>'name') = $1",
|
.query_opt("SELECT corp_id, details FROM corps WHERE LOWER(details->>'name') = $1",
|
||||||
|
@ -16,7 +16,7 @@ mod allow;
|
|||||||
pub mod attack;
|
pub mod attack;
|
||||||
mod buy;
|
mod buy;
|
||||||
mod c;
|
mod c;
|
||||||
mod corp;
|
pub mod corp;
|
||||||
pub mod drop;
|
pub mod drop;
|
||||||
pub mod get;
|
pub mod get;
|
||||||
mod describe;
|
mod describe;
|
||||||
|
@ -5,18 +5,22 @@ use super::{
|
|||||||
UResult,
|
UResult,
|
||||||
user_error,
|
user_error,
|
||||||
get_player_item_or_fail,
|
get_player_item_or_fail,
|
||||||
|
get_user_or_fail,
|
||||||
search_item_for_user,
|
search_item_for_user,
|
||||||
parsing
|
parsing,
|
||||||
|
corp::check_corp_perm,
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use crate::{
|
use crate::{
|
||||||
models::{
|
models::{
|
||||||
consent::{Consent, ConsentType, ConsentStatus, FightConsent},
|
consent::{Consent, ConsentType, ConsentStatus, FightConsent},
|
||||||
|
corp::{CorpPermission, CorpCommType},
|
||||||
item::Item
|
item::Item
|
||||||
},
|
},
|
||||||
db::ItemSearchParams,
|
db::ItemSearchParams,
|
||||||
static_content::room::room_map_by_code,
|
static_content::room::room_map_by_code,
|
||||||
};
|
};
|
||||||
|
use ansi::ansi;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ConsentTarget<'t> {
|
pub enum ConsentTarget<'t> {
|
||||||
@ -669,6 +673,127 @@ async fn handle_user_consent(ctx: &mut VerbContext<'_>, source_player: &Item,
|
|||||||
Ok(())
|
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;
|
pub struct Verb;
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UserVerb for Verb {
|
impl UserVerb for Verb {
|
||||||
@ -699,8 +824,8 @@ impl UserVerb for Verb {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
match cmd.consent_target {
|
match cmd.consent_target {
|
||||||
ConsentTarget::CorpTarget { .. } => user_error(
|
ConsentTarget::CorpTarget { from_corp, to_corp } =>
|
||||||
"Corporate allow/disallow not implemented yet".to_owned())?,
|
handle_corp_consent(ctx, &player_item, from_corp, to_corp, is_allow, &cmd).await?,
|
||||||
ConsentTarget::UserTarget { to_user } =>
|
ConsentTarget::UserTarget { to_user } =>
|
||||||
handle_user_consent(ctx, &player_item, to_user, is_allow, &cmd).await?
|
handle_user_consent(ctx, &player_item, to_user, is_allow, &cmd).await?
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ use std::collections::BTreeSet;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use humantime;
|
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)
|
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<()> {
|
async fn corp_unsubscribe(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()> {
|
||||||
let (subs, remaining) = match remaining.split_once(" from ") {
|
let (subs, remaining) = match remaining.split_once(" from ") {
|
||||||
None => user_error("Usage: corp unsubscribe commtype commtype ... from corpname\n\
|
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
|
Some(v) => v
|
||||||
};
|
};
|
||||||
let mut subs_del = BTreeSet::<CorpCommType>::new();
|
let mut subs_del = BTreeSet::<CorpCommType>::new();
|
||||||
|
@ -47,6 +47,7 @@ pub enum CorpCommType {
|
|||||||
Connect,
|
Connect,
|
||||||
Reward,
|
Reward,
|
||||||
Death,
|
Death,
|
||||||
|
Consent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CorpCommType {
|
impl CorpCommType {
|
||||||
@ -58,6 +59,7 @@ impl CorpCommType {
|
|||||||
"connect" => Some(Connect),
|
"connect" => Some(Connect),
|
||||||
"reward" => Some(Reward),
|
"reward" => Some(Reward),
|
||||||
"death" => Some(Death),
|
"death" => Some(Death),
|
||||||
|
"consent" => Some(Consent),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,6 +71,7 @@ impl CorpCommType {
|
|||||||
Connect => "connect",
|
Connect => "connect",
|
||||||
Reward => "reward",
|
Reward => "reward",
|
||||||
Death => "death",
|
Death => "death",
|
||||||
|
Consent => "consent",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,6 +129,7 @@ impl Default for CorpMembership {
|
|||||||
Connect,
|
Connect,
|
||||||
Reward,
|
Reward,
|
||||||
Death,
|
Death,
|
||||||
|
Consent,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user