enhanced ratelimiter
This commit is contained in:
parent
3028b1abfe
commit
b1c2c2b099
3 changed files with 112 additions and 59 deletions
70
src/main.rs
70
src/main.rs
|
@ -6,11 +6,17 @@ use twitch_irc::SecureTCPTransport;
|
|||
use twitch_irc::TwitchIRCClient;
|
||||
use twitch_irc::message::ServerMessage;
|
||||
use std::env;
|
||||
use std::time::Instant;
|
||||
// use std::time::Instant;
|
||||
use rand::Rng;
|
||||
use dotenv::dotenv;
|
||||
// mod helpers;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
mod ratelimiter;
|
||||
use ratelimiter::RateLimiter;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
|
||||
|
@ -47,7 +53,7 @@ pub async fn main() {
|
|||
// client.join("modulatingforcebot".to_owned()).unwrap();
|
||||
// client.say("modulatingforcebot".to_owned(), "Connected!".to_owned()).await.unwrap();
|
||||
|
||||
for chnl in botchannels {
|
||||
for chnl in &botchannels {
|
||||
client.join(chnl.to_owned()).unwrap();
|
||||
// client.say(chnl.to_owned(), "Connected!".to_owned()).await.unwrap();
|
||||
client.say(chnl.to_owned(), "annytfLurk".to_owned()).await.unwrap();
|
||||
|
@ -55,11 +61,16 @@ pub async fn main() {
|
|||
|
||||
// Adding rate limit functionality to be under : https://dev.twitch.tv/docs/irc/#rate-limits
|
||||
|
||||
let mut ratelimittimer = false.to_owned();
|
||||
|
||||
let mut ratelimitstart = Instant::now();
|
||||
let mut ratelimitcounter = 0;
|
||||
// ratelimiters are a hashmap of channel and a corresponding rate limiter
|
||||
let mut ratelimiters:HashMap<String,RateLimiter> = HashMap::new();
|
||||
|
||||
for chnl in &botchannels {
|
||||
let n = RateLimiter::new();
|
||||
ratelimiters.insert(chnl.to_owned(),n);
|
||||
}
|
||||
|
||||
println!("{:?}",ratelimiters);
|
||||
|
||||
let join_handle = tokio::spawn(async move {
|
||||
while let Some(message) = incoming_messages.recv().await {
|
||||
|
@ -74,34 +85,29 @@ pub async fn main() {
|
|||
}
|
||||
ServerMessage::Privmsg(msg) => {
|
||||
println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
|
||||
if !ratelimittimer {
|
||||
println!("(#{}) > {}", msg.channel_login, "started rate limit timer");
|
||||
// ratelimitstart = Instant::now();
|
||||
// ratelimittimer = true;
|
||||
( ratelimittimer , ratelimitstart ) = ( true , Instant::now() );
|
||||
} else if ratelimittimer && ratelimitstart.elapsed().as_secs() < 30 && ratelimitcounter >= 20 {
|
||||
// skip iteration if rate limit is being reached
|
||||
println!("(#{}) > {}", msg.channel_login, "rate limit reached");
|
||||
continue;
|
||||
} else if ratelimitstart.elapsed().as_secs() >= 30 {
|
||||
println!("(#{}) > {}", msg.channel_login, "rate limit timer reset");
|
||||
// ratelimittimer = false;
|
||||
// ratelimitcounter = 0;
|
||||
( ratelimittimer , ratelimitcounter ) = ( false , 0 ) ;
|
||||
|
||||
|
||||
let contextratelimiter = ratelimiters.get_mut(&msg.channel_login).expect("ERROR: Issue with Rate limiters");
|
||||
|
||||
match contextratelimiter.check_limiter() {
|
||||
ratelimiter::LimiterResp::Allow => {
|
||||
let maxblanks = rand::thread_rng().gen_range(1..=5);
|
||||
let mut outmsg = "GotTrolled ".to_owned();
|
||||
|
||||
for _i in 1..maxblanks {
|
||||
let blankspace: &str = "";
|
||||
outmsg.push_str(blankspace);
|
||||
}
|
||||
|
||||
client.say_in_reply_to(&msg,outmsg).await.unwrap();
|
||||
println!("(#{}) > {}", msg.channel_login, "rate limit counter increase");
|
||||
contextratelimiter.increment_counter();
|
||||
println!("{:?}",ratelimiters);
|
||||
},
|
||||
ratelimiter::LimiterResp::Skip => {
|
||||
(); // do nothing otherwise
|
||||
}
|
||||
}
|
||||
|
||||
let maxblanks = rand::thread_rng().gen_range(1..=5);
|
||||
let mut outmsg = "GotTrolled ".to_owned();
|
||||
|
||||
for _i in 1..maxblanks {
|
||||
let blankspace: &str = "";
|
||||
outmsg.push_str(blankspace);
|
||||
}
|
||||
|
||||
client.say_in_reply_to(&msg,outmsg).await.unwrap();
|
||||
println!("(#{}) > {}", msg.channel_login, "rate limit counter increase");
|
||||
ratelimitcounter += 1;
|
||||
// client.say(msg.channel_login, "GotTrolled".to_owned()).await.unwrap();
|
||||
},
|
||||
ServerMessage::Whisper(msg) => {
|
||||
println!("(w) {}: {}", msg.sender.name, msg.message_text);
|
||||
|
|
47
src/ratelimiter.rs
Normal file
47
src/ratelimiter.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
use std::time::Instant;
|
||||
|
||||
const TIME_THRESHOLD_S: u64 = 30;
|
||||
const MSG_THRESHOLD: u32 = 20;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RateLimiter {
|
||||
timer: Instant,
|
||||
msgcounter: u32,
|
||||
}
|
||||
|
||||
pub enum LimiterResp {
|
||||
Allow, // when it's evaluated to be within limits
|
||||
Skip, // as outside of rate limits
|
||||
}
|
||||
|
||||
|
||||
impl RateLimiter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
timer: Instant::now(),
|
||||
msgcounter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_limiter(&mut self) -> LimiterResp {
|
||||
|
||||
if self.timer.elapsed().as_secs() >= TIME_THRESHOLD_S {
|
||||
// # [x] elapsed >= TIME_THRESHOLD_S
|
||||
self.timer = Instant::now();
|
||||
self.msgcounter = 0;
|
||||
LimiterResp::Allow
|
||||
} else if self.msgcounter < MSG_THRESHOLD {
|
||||
// # [x] elapsed < TIME_THRESHOLD_S && msgcounter < MSG_THRESHOLD
|
||||
LimiterResp::Allow
|
||||
// } else if self.msgcounter >= MSG_THRESHOLD {
|
||||
} else {
|
||||
// # [x] elapsed < TIME_THRESHOLD_S && msgcounter >= MSG_THRESHOLD
|
||||
LimiterResp::Skip
|
||||
}
|
||||
}
|
||||
|
||||
pub fn increment_counter(&mut self) -> () {
|
||||
self.msgcounter += 1;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue