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