several changes and updates
This commit is contained in:
Generated
+88
-2
@@ -8,6 +8,15 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.53"
|
version = "0.1.53"
|
||||||
@@ -35,6 +44,17 @@ dependencies = [
|
|||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -170,6 +190,19 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.23"
|
version = "1.0.23"
|
||||||
@@ -358,6 +391,12 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.18"
|
version = "0.14.18"
|
||||||
@@ -566,9 +605,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.11.0"
|
version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca"
|
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
@@ -683,6 +722,23 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.11.10"
|
version = "0.11.10"
|
||||||
@@ -875,6 +931,15 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -902,7 +967,9 @@ name = "spamcontest"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"env_logger",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"log",
|
||||||
"serenity",
|
"serenity",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
@@ -924,6 +991,15 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.31"
|
version = "1.0.31"
|
||||||
@@ -994,6 +1070,7 @@ dependencies = [
|
|||||||
"num_cpus",
|
"num_cpus",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"winapi",
|
"winapi",
|
||||||
@@ -1321,6 +1398,15 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|||||||
+3
-1
@@ -6,9 +6,11 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
log = "0.4"
|
||||||
|
env_logger = "0.9"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
tokio = {version = "1.18", features = ["rt-multi-thread"]}
|
tokio = {version = "1.18", features = ["rt-multi-thread", "signal"]}
|
||||||
|
|
||||||
[dependencies.serenity]
|
[dependencies.serenity]
|
||||||
version = "0.11"
|
version = "0.11"
|
||||||
|
|||||||
+19
-5
@@ -1,3 +1,4 @@
|
|||||||
|
use log::{debug, error, LevelFilter};
|
||||||
use serenity::prelude::*;
|
use serenity::prelude::*;
|
||||||
use spamcontest::Handler;
|
use spamcontest::Handler;
|
||||||
use std::{env, process};
|
use std::{env, process};
|
||||||
@@ -6,11 +7,16 @@ const TOKEN_VAR_KEY: &str = "DISCORD_TOKEN";
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
env_logger::builder()
|
||||||
|
.filter_module(module_path!(), LevelFilter::Info)
|
||||||
|
.parse_default_env()
|
||||||
|
.init();
|
||||||
|
|
||||||
let token = match env::var(TOKEN_VAR_KEY) {
|
let token = match env::var(TOKEN_VAR_KEY) {
|
||||||
Ok(token) => token,
|
Ok(token) => token,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Unable to get {}: {}", TOKEN_VAR_KEY, err);
|
error!("Unable to get {}: {}", TOKEN_VAR_KEY, err);
|
||||||
process::exit(1)
|
process::exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,12 +27,20 @@ async fn main() {
|
|||||||
{
|
{
|
||||||
Ok(client) => client,
|
Ok(client) => client,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Unable to start client: {}", err);
|
error!("Unable to start client: {:?}", err);
|
||||||
process::exit(2)
|
process::exit(2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let shard_manager = client.shard_manager.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
tokio::signal::ctrl_c().await.expect("ctrc+c handler error");
|
||||||
|
debug!("Shutting down...");
|
||||||
|
shard_manager.lock().await.shutdown_all().await;
|
||||||
|
});
|
||||||
|
|
||||||
if let Err(err) = client.start().await {
|
if let Err(err) = client.start().await {
|
||||||
eprintln!("An Error occurred while running the client: {:?}", err)
|
error!("An Error occurred while running the client: {:?}", err);
|
||||||
|
process::exit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-35
@@ -1,13 +1,16 @@
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use log::{debug, error, info};
|
||||||
|
use serenity::client::{Context, EventHandler};
|
||||||
use serenity::model::channel::Message;
|
use serenity::model::channel::Message;
|
||||||
|
use serenity::model::event::ResumedEvent;
|
||||||
|
use serenity::model::gateway::{Activity, Ready};
|
||||||
use serenity::model::id::{ChannelId, UserId};
|
use serenity::model::id::{ChannelId, UserId};
|
||||||
use serenity::prelude::*;
|
|
||||||
use serenity::utils::Colour;
|
use serenity::utils::Colour;
|
||||||
use std::cmp::Reverse;
|
use std::cmp::Reverse;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
use std::sync::Arc;
|
use std::sync::Mutex;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
const DEFAULT_CONTEST_DURATION: Duration = Duration::from_secs(60);
|
const DEFAULT_CONTEST_DURATION: Duration = Duration::from_secs(60);
|
||||||
@@ -17,9 +20,11 @@ const ALLOWED_DURATION_RANGE: RangeInclusive<Duration> =
|
|||||||
|
|
||||||
const PIN_ANNOUNCEMENT_THRESHOLD: Duration = Duration::from_secs(5 * 60);
|
const PIN_ANNOUNCEMENT_THRESHOLD: Duration = Duration::from_secs(5 * 60);
|
||||||
|
|
||||||
|
type Contests = Mutex<HashMap<ChannelId, Contest>>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Handler {
|
pub struct Handler {
|
||||||
contests: Arc<Mutex<HashMap<ChannelId, Contest>>>,
|
contests: Contests,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
@@ -31,7 +36,13 @@ impl Handler {
|
|||||||
#[serenity::async_trait]
|
#[serenity::async_trait]
|
||||||
impl EventHandler for Handler {
|
impl EventHandler for Handler {
|
||||||
async fn message(&self, ctx: Context, msg: Message) {
|
async fn message(&self, ctx: Context, msg: Message) {
|
||||||
if let Some(contest) = self.contests.lock().await.get_mut(&msg.channel_id) {
|
if let Some(contest) = self.contests.lock().unwrap().get_mut(&msg.channel_id) {
|
||||||
|
debug!(
|
||||||
|
"Counting message {} (from {} in channel {})",
|
||||||
|
msg.id,
|
||||||
|
msg.author.tag(),
|
||||||
|
msg.channel_id.0
|
||||||
|
);
|
||||||
contest.count(&msg);
|
contest.count(&msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -42,11 +53,17 @@ impl EventHandler for Handler {
|
|||||||
.split_ascii_whitespace()
|
.split_ascii_whitespace()
|
||||||
.filter_map(|w| w.parse().ok())
|
.filter_map(|w| w.parse().ok())
|
||||||
.map(Duration::from_secs)
|
.map(Duration::from_secs)
|
||||||
.filter(|d| ALLOWED_DURATION_RANGE.contains(d))
|
.find(|d| ALLOWED_DURATION_RANGE.contains(d))
|
||||||
.next()
|
|
||||||
.unwrap_or(DEFAULT_CONTEST_DURATION);
|
.unwrap_or(DEFAULT_CONTEST_DURATION);
|
||||||
|
|
||||||
if let Err(err) = run_contest(
|
info!(
|
||||||
|
"User {} started a {} second contest in channel {}",
|
||||||
|
msg.author.tag(),
|
||||||
|
duration.as_secs(),
|
||||||
|
msg.channel_id.0
|
||||||
|
);
|
||||||
|
|
||||||
|
match run_contest(
|
||||||
ctx,
|
ctx,
|
||||||
msg.channel_id,
|
msg.channel_id,
|
||||||
duration,
|
duration,
|
||||||
@@ -55,63 +72,81 @@ impl EventHandler for Handler {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
eprintln!("Error: {:?}", err)
|
Ok(contest) => debug!(
|
||||||
}
|
"Contest in channel {} has ended with {} participant(s)",
|
||||||
|
msg.channel_id.0,
|
||||||
|
contest.counts.len()
|
||||||
|
),
|
||||||
|
Err(err) => error!(
|
||||||
|
"Error while running contest in channel {}: {:?}",
|
||||||
|
msg.channel_id.0, err
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||||
|
info!("Connected as {}", ready.user.tag());
|
||||||
|
ctx.set_activity(Activity::listening("Spam")).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn resume(&self, _ctx: Context, _: ResumedEvent) {
|
||||||
|
info!("Resumed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Eq)]
|
#[derive(Default, PartialEq, Eq)]
|
||||||
pub struct SpamCount {
|
struct SpamCount {
|
||||||
messages: usize,
|
messages: usize,
|
||||||
characters: usize,
|
characters: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Contest {
|
struct Contest {
|
||||||
counts: HashMap<UserId, SpamCount>,
|
counts: HashMap<UserId, SpamCount>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Contest {
|
impl Contest {
|
||||||
pub fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count(&mut self, message: &Message) {
|
fn count(&mut self, message: &Message) {
|
||||||
|
let char_count = message.content.chars().count();
|
||||||
match self.counts.get_mut(&message.author.id) {
|
match self.counts.get_mut(&message.author.id) {
|
||||||
None => {
|
None => {
|
||||||
self.counts.insert(
|
self.counts.insert(
|
||||||
message.author.id,
|
message.author.id,
|
||||||
SpamCount {
|
SpamCount {
|
||||||
messages: 1,
|
messages: 1,
|
||||||
characters: message.content.len(),
|
characters: char_count,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(count) => {
|
Some(count) => {
|
||||||
count.messages += 1;
|
count.messages += 1;
|
||||||
count.characters += message.content.len()
|
count.characters += char_count;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ranking_by<F, K, D, S>(&self, kf: F, df: D) -> String
|
fn ranking_by<Fk, K, Fd, D>(&self, fk: Fk, fd: Fd) -> String
|
||||||
where
|
where
|
||||||
F: Fn(&SpamCount) -> K,
|
Fk: Fn(&SpamCount) -> K,
|
||||||
K: Ord,
|
K: Ord,
|
||||||
D: Fn(&SpamCount) -> S,
|
Fd: Fn(&SpamCount) -> D,
|
||||||
S: Display,
|
D: Display,
|
||||||
{
|
{
|
||||||
let mut ranking = self.counts.iter().collect::<Vec<_>>();
|
let mut ranking = self.counts.iter().collect::<Vec<_>>();
|
||||||
ranking.sort_unstable_by_key(|(_, c)| kf(c));
|
ranking.sort_unstable_by_key(|(_, c)| fk(c));
|
||||||
|
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
let mut cur_rank_num = 1;
|
let mut cur_rank_num = 1;
|
||||||
for (_, rank_group) in &ranking.into_iter().group_by(|elt| kf((*elt).1)) {
|
for (_, rank_group) in &ranking.into_iter().group_by(|elt| fk((*elt).1)) {
|
||||||
let mut group_size = 0;
|
let mut group_size = 0;
|
||||||
for (userid, count) in rank_group {
|
for (userid, count) in rank_group {
|
||||||
result.push_str(
|
result.push_str(
|
||||||
format!("**{}.:** <@{}> ({})\n", cur_rank_num, userid, df(count)).as_str(),
|
format!("**{cur_rank_num}.:** <@{userid}> ({})\n", fd(count)).as_str(),
|
||||||
);
|
);
|
||||||
group_size += 1;
|
group_size += 1;
|
||||||
}
|
}
|
||||||
@@ -121,13 +156,13 @@ impl Contest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_contest(
|
async fn run_contest(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
contests: &Arc<Mutex<HashMap<ChannelId, Contest>>>,
|
contests: &Contests,
|
||||||
pin_announcement: bool,
|
pin: bool,
|
||||||
) -> serenity::Result<()> {
|
) -> serenity::Result<Contest> {
|
||||||
let end_timestamp =
|
let end_timestamp =
|
||||||
(chrono::Utc::now() + chrono::Duration::from_std(duration).unwrap()).timestamp() + 1;
|
(chrono::Utc::now() + chrono::Duration::from_std(duration).unwrap()).timestamp() + 1;
|
||||||
|
|
||||||
@@ -137,27 +172,26 @@ pub async fn run_contest(
|
|||||||
m.embed(|e| {
|
m.embed(|e| {
|
||||||
e.title("Es wurde ein Spam-Wettbewerb gestartet!")
|
e.title("Es wurde ein Spam-Wettbewerb gestartet!")
|
||||||
.description(format!(
|
.description(format!(
|
||||||
"Wer am meisten spamt, gewinnt.\nEnde <t:{}:R>.",
|
"Wer am meisten spamt, gewinnt.\nEnde <t:{end_timestamp}:R>.",
|
||||||
end_timestamp
|
|
||||||
))
|
))
|
||||||
.colour(Colour::BLUE)
|
.colour(Colour::BLUE)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if pin_announcement {
|
if pin {
|
||||||
announcement.pin(&ctx.http).await?;
|
announcement.pin(&ctx.http).await.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
contests.lock().await.insert(channel_id, Contest::new());
|
contests.lock().unwrap().insert(channel_id, Contest::new());
|
||||||
tokio::time::sleep(duration).await;
|
tokio::time::sleep(duration).await;
|
||||||
let contest = contests.lock().await.remove(&channel_id).unwrap();
|
let contest = contests.lock().unwrap().remove(&channel_id).unwrap();
|
||||||
|
|
||||||
if contest.counts.is_empty() {
|
if contest.counts.is_empty() {
|
||||||
announcement.delete(&ctx.http).await?;
|
announcement.delete(&ctx.http).await?;
|
||||||
} else {
|
} else {
|
||||||
if pin_announcement {
|
if pin {
|
||||||
announcement.unpin(&ctx.http).await?;
|
announcement.unpin(&ctx.http).await.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// send ranking message
|
// send ranking message
|
||||||
@@ -181,5 +215,5 @@ pub async fn run_contest(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(contest)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user