Initial working version of bot
This commit is contained in:
		
						commit
						680d73b71e
					
				
					 5 changed files with 1650 additions and 0 deletions
				
			
		
							
								
								
									
										4
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | /target | ||||||
|  | grammar | ||||||
|  | config.toml | ||||||
|  | *~ | ||||||
							
								
								
									
										1466
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1466
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										32
									
								
								Cargo.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								Cargo.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | [package] | ||||||
|  | name = "grammar-bot" | ||||||
|  | version = "0.1.0" | ||||||
|  | authors = ["xenofem <xenofem@xeno.science>"] | ||||||
|  | license = "MIT" | ||||||
|  | edition = "2018" | ||||||
|  | 
 | ||||||
|  | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
|  | purrchance = "0.4.0" | ||||||
|  | serde = "1.0.112" | ||||||
|  | toml = "0.5.6" | ||||||
|  | 
 | ||||||
|  | [dependencies.serenity] | ||||||
|  | git = "https://github.com/Lakelezz/serenity/" | ||||||
|  | branch = "await" | ||||||
|  | default-features = false | ||||||
|  | features = [ | ||||||
|  |     "builder", | ||||||
|  |     "cache", | ||||||
|  |     "client", | ||||||
|  |     "gateway", | ||||||
|  |     "http", | ||||||
|  |     "model", | ||||||
|  |     "utils", | ||||||
|  |     "rustls_backend", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [dependencies.tokio] | ||||||
|  | version = "0.2" | ||||||
|  | features = ["macros"] | ||||||
							
								
								
									
										6
									
								
								config.toml.example
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								config.toml.example
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | grammar_path = "grammar" | ||||||
|  | grammar_type = "perchance" | ||||||
|  | grammar_symbol = "output" | ||||||
|  | token = "t0k3n" | ||||||
|  | channel_id = 0000000000000000 | ||||||
|  | interval = 7200 | ||||||
							
								
								
									
										142
									
								
								src/main.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/main.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,142 @@ | ||||||
|  | extern crate purrchance; | ||||||
|  | extern crate serde; | ||||||
|  | extern crate serenity; | ||||||
|  | extern crate tokio; | ||||||
|  | extern crate toml; | ||||||
|  | 
 | ||||||
|  | use purrchance::{Grammar, Purrchance, Symbol, parser::load_grammar}; | ||||||
|  | use serde::Deserialize; | ||||||
|  | use serenity::{ | ||||||
|  |     async_trait, | ||||||
|  |     model::{channel::Message, gateway::Ready, id::ChannelId, user::User}, | ||||||
|  |     prelude::*, | ||||||
|  | }; | ||||||
|  | use std::fs::read_to_string; | ||||||
|  | use std::process::exit; | ||||||
|  | use std::sync::Arc; | ||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | #[derive(Deserialize)] | ||||||
|  | #[serde(rename_all = "lowercase")] | ||||||
|  | enum GrammarType { | ||||||
|  |     Perchance, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Deserialize)] | ||||||
|  | struct Config { | ||||||
|  |     grammar_path: String, | ||||||
|  |     grammar_type: GrammarType, | ||||||
|  |     grammar_symbol: String, | ||||||
|  |     token: String, | ||||||
|  |     channel_id: ChannelId, | ||||||
|  |     interval: u64, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct TextGenerator { | ||||||
|  |     grammar: Grammar, | ||||||
|  |     symbol: Symbol, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TextGenerator { | ||||||
|  |     pub fn generate(&self) -> String { | ||||||
|  |         self.symbol.eval(&self.grammar).unwrap() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TypeMapKey for TextGenerator { | ||||||
|  |     type Value = TextGenerator; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct Interval; | ||||||
|  | 
 | ||||||
|  | impl TypeMapKey for Interval { | ||||||
|  |     type Value = u64; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ChanId; | ||||||
|  | 
 | ||||||
|  | impl TypeMapKey for ChanId { | ||||||
|  |     type Value = ChannelId; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct LoopStatus; | ||||||
|  | 
 | ||||||
|  | impl TypeMapKey for LoopStatus { | ||||||
|  |     type Value = bool; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct Handler; | ||||||
|  | 
 | ||||||
|  | async fn mentions_me(ctx: &Context, msg: &Message) -> bool { | ||||||
|  |     let me = User::from(ctx.http.get_current_user().await.unwrap()); | ||||||
|  |     if msg.mentions_user(&me) { | ||||||
|  |         return true | ||||||
|  |     } | ||||||
|  |     let guild = msg.guild(ctx).await.unwrap(); | ||||||
|  |     let member = guild.member(ctx, me).await.unwrap(); | ||||||
|  |     let my_roles = member.roles; | ||||||
|  |     msg.mention_roles.iter().any(|r| my_roles.contains(r)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async fn interval_loop(ctx: Arc<Context>) { | ||||||
|  |     let channel_id = ctx.data.read().await.get::<ChanId>().unwrap().clone(); | ||||||
|  |     loop { | ||||||
|  |         let sentence = ctx.data.read().await.get::<TextGenerator>().unwrap().generate(); | ||||||
|  |         channel_id.say(&ctx.http, sentence).await; | ||||||
|  |         tokio::time::delay_for(Duration::from_secs(*ctx.data.read().await.get::<Interval>().unwrap())).await; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[async_trait] | ||||||
|  | impl EventHandler for Handler { | ||||||
|  |     async fn message(&self, ctx: Context, msg: Message) { | ||||||
|  |         if mentions_me(&ctx, &msg).await { | ||||||
|  |             let sentence = ctx.data.read().await.get::<TextGenerator>().unwrap().generate(); | ||||||
|  |             msg.channel_id.say(&ctx.http, sentence).await; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async fn ready(&self, ctx: Context, ready: Ready) { | ||||||
|  |         eprintln!("{} is connected!", ready.user.name); | ||||||
|  |         let ctx = Arc::new(ctx); | ||||||
|  |         let ctx_clone = Arc::clone(&ctx); | ||||||
|  |         if !ctx.data.read().await.get::<LoopStatus>().unwrap() { | ||||||
|  |             let interval_loop = tokio::spawn(async move {interval_loop(ctx_clone).await}); | ||||||
|  |             { | ||||||
|  |                 let mut data = ctx.data.write().await; | ||||||
|  |                 data.insert::<LoopStatus>(true); | ||||||
|  |             } | ||||||
|  |             let _ = interval_loop.await; | ||||||
|  |             { | ||||||
|  |                 let mut data = ctx.data.write().await; | ||||||
|  |                 data.insert::<LoopStatus>(false); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[tokio::main] | ||||||
|  | async fn main() { | ||||||
|  |     let config: Config = toml::from_str(&read_to_string("config.toml").unwrap()).unwrap(); | ||||||
|  | 
 | ||||||
|  |     match config.grammar_type { | ||||||
|  |         GrammarType::Perchance => { | ||||||
|  |             let grammar = load_grammar(&read_to_string(config.grammar_path).unwrap()).unwrap(); | ||||||
|  |             let symbol = Symbol::NonTerminal(config.grammar_symbol); | ||||||
|  | 
 | ||||||
|  |             let mut client = Client::new(&config.token) | ||||||
|  |                 .event_handler(Handler) | ||||||
|  |                 .await | ||||||
|  |                 .expect("err creating client"); | ||||||
|  | 
 | ||||||
|  |             { | ||||||
|  |                 let mut data = client.data.write().await; | ||||||
|  |                 data.insert::<TextGenerator>(TextGenerator { grammar, symbol }); | ||||||
|  |                 data.insert::<Interval>(config.interval); | ||||||
|  |                 data.insert::<ChanId>(config.channel_id); | ||||||
|  |                 data.insert::<LoopStatus>(false); | ||||||
|  |             } | ||||||
|  |             client.start().await; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue