Compare commits
3 Commits
d90eeef19d
...
fcca9b4ea7
| Author | SHA1 | Date |
|---|---|---|
|
|
fcca9b4ea7 | |
|
|
8f8fe1df0b | |
|
|
bb17e1c471 |
|
|
@ -0,0 +1,18 @@
|
|||
ALTER TABLE IF EXISTS "channels"
|
||||
RENAME TO "quarantine_channels";
|
||||
|
||||
-- Make the quarantine channels table hold more generic channel info
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
RENAME COLUMN "channel_id" TO "qc_channel_id";
|
||||
|
||||
-- Channels with this flag should retain old qc behaviour
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
DROP COLUMN "is_quarantine_channel";
|
||||
|
||||
-- Setting flag to false allows channels to be excluded from XP even if not QC (though QC channels via the above flag imply this flag too)
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
DROP COLUMN "is_valid_for_xp";
|
||||
|
||||
-- Ensure that the role ID can be null for non-qc channels
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
ALTER COLUMN "qc_role_id" SET NOT NULL;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
-- Make the quarantine channels table hold more generic channel info
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
RENAME COLUMN "qc_channel_id" TO "channel_id";
|
||||
|
||||
-- Channels with this flag should retain old qc behaviour
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
ADD COLUMN "is_quarantine_channel" BOOL NOT NULL DEFAULT FALSE;
|
||||
|
||||
-- Setting flag to false allows channels to be excluded from XP even if not QC (though QC channels via the above flag imply this flag too)
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
ADD COLUMN "is_valid_for_xp" BOOL NOT NULL DEFAULT TRUE;
|
||||
|
||||
-- Ensure that the role ID can be null for non-qc channels
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
ALTER COLUMN "qc_role_id" DROP NOT NULL;
|
||||
|
||||
-- Rename table to something more suitable
|
||||
ALTER TABLE IF EXISTS "quarantine_channels"
|
||||
RENAME TO "channels";
|
||||
|
|
@ -2,7 +2,7 @@ use built::chrono;
|
|||
use manifold::error::{ManifoldError, ManifoldResult};
|
||||
use manifold::{ManifoldContext, ManifoldData};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use crate::badgey::models::quarantine_channel::QuarantineChannel;
|
||||
use crate::badgey::models::quarantine_channel::Channel;
|
||||
|
||||
#[poise::command(slash_command, prefix_command, required_permissions = "MODERATE_MEMBERS")]
|
||||
async fn void_user(_ctx: ManifoldContext<'_>, _target: serenity::User) -> ManifoldResult<()> {
|
||||
|
|
@ -38,25 +38,44 @@ async fn security_record(ctx: ManifoldContext<'_>) -> ManifoldResult<()> {
|
|||
|
||||
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_GUILD")]
|
||||
async fn add_quarantine_channel(ctx: ManifoldContext<'_>, channel: serenity::ChannelId, role: serenity::RoleId) -> ManifoldResult<()> {
|
||||
let qc = QuarantineChannel::new(role.as_u64().clone() as i64, channel.as_u64().clone() as i64);
|
||||
let qc = Channel::new(Some(role.as_u64().clone() as i64), channel.as_u64().clone() as i64, true, false);
|
||||
qc.insert(&ctx.data().database)?;
|
||||
|
||||
ctx.reply(format!("OK: Quarantine channel {channel} defined with quarantine role {role}", channel = channel, role = role)).await?;
|
||||
ctx.reply(format!("OK: Quarantine channel <#{channel}> defined with quarantine role <@{role}>", channel = channel, role = role)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_GUILD")]
|
||||
async fn remove_quarantine_channel(ctx: ManifoldContext<'_>, channel: serenity::ChannelId) -> ManifoldResult<()> {
|
||||
|
||||
let db = &ctx.data().database;
|
||||
QuarantineChannel::get(db, channel.as_u64().clone() as i64)?.remove(db)?;
|
||||
Channel::get_by_channel_id(db, channel.as_u64().clone() as i64)?.remove(db)?;
|
||||
|
||||
ctx.reply(format!("OK: Quarantine channel {channel} is no longer defined.", channel = channel)).await?;
|
||||
ctx.reply(format!("OK: Quarantine channel <#{channel}> is no longer defined.", channel = channel)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn commands() -> [poise::Command<ManifoldData, ManifoldError>; 7] {
|
||||
[void_user(), unvoid_user(), airlock_user(), record_chronicle(), security_record(), add_quarantine_channel(), remove_quarantine_channel()]
|
||||
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_GUILD")]
|
||||
async fn ignore_channel_for_xp(ctx: ManifoldContext<'_>, channel: serenity::ChannelId) -> ManifoldResult<()> {
|
||||
let qc = Channel::new(None, channel.as_u64().clone() as i64, false, false);
|
||||
qc.insert(&ctx.data().database)?;
|
||||
|
||||
ctx.reply(format!("OK: Channel <#{channel}> will no longer allow users to accrue XP.", channel = channel)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[poise::command(slash_command, prefix_command, required_permissions = "MANAGE_GUILD")]
|
||||
async fn unignore_channel_for_xp(ctx: ManifoldContext<'_>, channel: serenity::ChannelId) -> ManifoldResult<()> {
|
||||
let db = &ctx.data().database;
|
||||
Channel::get_by_channel_id(db, channel.as_u64().clone() as i64)?.remove(db)?;
|
||||
|
||||
ctx.reply(format!("OK: Channel <#{channel}> will now permit users to accrue XP.", channel = channel)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn commands() -> [poise::Command<ManifoldData, ManifoldError>; 9] {
|
||||
[void_user(), unvoid_user(), airlock_user(), record_chronicle(), security_record(), add_quarantine_channel(), remove_quarantine_channel(), ignore_channel_for_xp(), unignore_channel_for_xp()]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use manifold::ManifoldData;
|
|||
use poise::FrameworkContext;
|
||||
use poise::serenity_prelude::{ChannelId, Context, Member, Mentionable};
|
||||
|
||||
use crate::badgey::models::quarantine_channel::QuarantineChannel;
|
||||
use crate::badgey::models::quarantine_channel::Channel;
|
||||
|
||||
pub async fn airlock_handler(ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, old: &Option<Member>, new: &Member) -> ManifoldResult<()> {
|
||||
|
||||
|
|
@ -11,17 +11,17 @@ pub async fn airlock_handler(ctx: &Context, fctx: &FrameworkContext<'_, Manifold
|
|||
|
||||
// Is this user quarantined?
|
||||
for role in new.roles.iter() {
|
||||
if let Ok(channel) = QuarantineChannel::get(db, role.as_u64().clone() as i64) {
|
||||
if let Ok(channel) = Channel::get_by_qc_role_id(db, role.as_u64().clone() as i64) {
|
||||
// Was this user JUST added to a quarantine channel?
|
||||
if let Some(m) = old {
|
||||
for role in m.roles.iter() {
|
||||
if let Ok(_) = QuarantineChannel::get(db, role.as_u64().clone() as i64) {
|
||||
if let Ok(_) = Channel::get_by_qc_role_id(db, role.as_u64().clone() as i64) {
|
||||
// User already had quarantine role, return early
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let target_channel: ChannelId = ChannelId::from(channel.qc_channel_id as u64);
|
||||
let target_channel: ChannelId = ChannelId::from(channel.channel_id as u64);
|
||||
|
||||
// User was just added to a quarantine channel. Post the initial ping message.
|
||||
target_channel.say(ctx, format!("{mention}, please respond to this message", mention = new.mention())).await?;
|
||||
|
|
|
|||
|
|
@ -3,45 +3,57 @@ use diesel::dsl::delete;
|
|||
use diesel::prelude::*;
|
||||
use manifold::Db;
|
||||
use manifold::error::{ManifoldError, ManifoldResult};
|
||||
use crate::badgey::schema::quarantine_channels as quarantine_table;
|
||||
use crate::badgey::schema::channels as channel_table;
|
||||
use crate::badgey::schema::*;
|
||||
|
||||
#[derive(Queryable, Selectable, Identifiable, Insertable, Debug, Clone)]
|
||||
#[diesel(table_name = quarantine_channels)]
|
||||
pub struct QuarantineChannel {
|
||||
#[diesel(table_name = channels)]
|
||||
pub struct Channel {
|
||||
#[diesel(deserialize_as = i32)]
|
||||
pub id: Option<i32>,
|
||||
pub qc_role_id: i64,
|
||||
pub qc_channel_id: i64,
|
||||
pub qc_role_id: Option<i64>,
|
||||
pub channel_id: i64,
|
||||
pub is_quarantine_channel: bool,
|
||||
pub is_valid_for_xp: bool,
|
||||
}
|
||||
|
||||
impl QuarantineChannel {
|
||||
pub fn new(role_id: i64, channel_id: i64) -> Self {
|
||||
QuarantineChannel {
|
||||
impl Channel {
|
||||
pub fn new(qc_role_id: Option<i64>, channel_id: i64, is_quarantine_channel: bool, is_valid_for_xp: bool) -> Self {
|
||||
Channel {
|
||||
id: None,
|
||||
qc_role_id: role_id,
|
||||
qc_channel_id: channel_id
|
||||
qc_role_id,
|
||||
channel_id,
|
||||
is_quarantine_channel,
|
||||
is_valid_for_xp,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&self, conn: &Db) -> ManifoldResult<usize> {
|
||||
insert_into(quarantine_table::dsl::quarantine_channels)
|
||||
insert_into(channel_table::dsl::channels)
|
||||
.values(self)
|
||||
.execute(&mut conn.get()?)
|
||||
.map_err(|e| ManifoldError::from(e))
|
||||
}
|
||||
|
||||
pub fn remove(&self, conn: &Db) -> ManifoldResult<usize> {
|
||||
Ok(delete(quarantine_table::dsl::quarantine_channels)
|
||||
.filter(quarantine_table::qc_role_id.eq(self.qc_role_id))
|
||||
Ok(delete(channel_table::dsl::channels)
|
||||
.filter(channel_table::qc_role_id.eq(self.qc_role_id))
|
||||
.execute(&mut conn.get()?)?)
|
||||
}
|
||||
|
||||
pub fn get(conn: &Db, needle: i64) -> ManifoldResult<Self> {
|
||||
Ok(quarantine_table::dsl::quarantine_channels
|
||||
.filter(quarantine_table::qc_role_id.eq(needle))
|
||||
pub fn get_by_channel_id(conn: &Db, needle: i64) -> ManifoldResult<Self> {
|
||||
Ok(channel_table::dsl::channels
|
||||
.filter(channel_table::channel_id.eq(needle))
|
||||
.limit(1)
|
||||
.select(QuarantineChannel::as_select())
|
||||
.select(Channel::as_select())
|
||||
.get_result(&mut conn.get()?)?)
|
||||
}
|
||||
|
||||
pub fn get_by_qc_role_id(conn: &Db, needle: i64) -> ManifoldResult<Self> {
|
||||
Ok(channel_table::dsl::channels
|
||||
.filter(channel_table::qc_role_id.eq(needle))
|
||||
.limit(1)
|
||||
.select(Channel::as_select())
|
||||
.get_result(&mut conn.get()?)?)
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ use manifold::models::user::UserInfo;
|
|||
use manifold::schema::userinfo;
|
||||
use poise::FrameworkContext;
|
||||
use poise::serenity_prelude::{Context, Mentionable, Message, RoleId};
|
||||
use crate::badgey::models::quarantine_channel::QuarantineChannel;
|
||||
use crate::badgey::models::quarantine_channel::Channel;
|
||||
use crate::badgey::schema::xp as xp_table;
|
||||
use crate::badgey::schema::*;
|
||||
|
||||
|
|
@ -171,18 +171,25 @@ impl Xp {
|
|||
let xp_reward = rng.gen_range(1..30).clone();
|
||||
drop(rng);
|
||||
let user_id_i64 = msg.author.id.as_u64().clone() as i64;
|
||||
let channel_id_i64 = msg.channel_id.as_u64().clone() as i64;
|
||||
|
||||
let mut valid_channel = true;
|
||||
|
||||
if let Ok(c) = Channel::get_by_channel_id(&fctx.user_data.database, channel_id_i64) {
|
||||
valid_channel = c.is_valid_for_xp && !c.is_quarantine_channel;
|
||||
}
|
||||
|
||||
let mut xp = match Xp::get(db, &user_id_i64) {
|
||||
Ok(x) => x,
|
||||
Err(_) => Xp::new(&user_id_i64)
|
||||
};
|
||||
|
||||
let valid = match xp.last_given_xp {
|
||||
Some(t) => (chrono::Utc::now().timestamp() - 60) > t && QuarantineChannel::get(&fctx.user_data.database, msg.channel_id.as_u64().clone() as i64).is_err(),
|
||||
let valid_user = match xp.last_given_xp {
|
||||
Some(t) => (chrono::Utc::now().timestamp() - 60) > t,
|
||||
None => true
|
||||
};
|
||||
|
||||
if valid {
|
||||
if valid_user && valid_channel {
|
||||
xp.last_given_xp = Some(chrono::Utc::now().timestamp());
|
||||
xp.xp_value += &xp_reward;
|
||||
let calculated_level = xp.get_level_from_xp(&db, None);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
channels (id) {
|
||||
id -> Int4,
|
||||
qc_role_id -> Nullable<Int8>,
|
||||
channel_id -> Int8,
|
||||
is_quarantine_channel -> Bool,
|
||||
is_valid_for_xp -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
custom_responses (id) {
|
||||
id -> Int4,
|
||||
|
|
@ -12,14 +22,6 @@ diesel::table! {
|
|||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
quarantine_channels (id) {
|
||||
id -> Int4,
|
||||
qc_role_id -> Int8,
|
||||
qc_channel_id -> Int8,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
ranks (role_id) {
|
||||
role_id -> Int8,
|
||||
|
|
@ -72,8 +74,8 @@ diesel::joinable!(custom_responses -> userinfo (added_for));
|
|||
diesel::joinable!(xp -> userinfo (user_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
channels,
|
||||
custom_responses,
|
||||
quarantine_channels,
|
||||
ranks,
|
||||
tracks,
|
||||
userinfo,
|
||||
|
|
|
|||
Loading…
Reference in New Issue