5YD5TE7BVUUMNIT2WQPFPLZ75Z4GK74B2NPCZO33U2JWCEOSN4HAC
WGDIOOND7FW2MTMG4CN4YBME4ASD33WKHMIYOSPGGKXO6W37IYJQC
MONGK6NLQPZMCQ4ETEPYRZSDFVJFO7NFIECNSHWANBLXGN33ZH4QC
3RIQO76K22AO2KTNUZGO7R2XXBTBXRJV7PVFT3XI476JXEVBRP2AC
OV3C6S74AWVASSPK763KMCFHN3YPF4WBW7IJ7BC3HL5ZFZ4DCXHQC
DUGW4Q4WJ5JJ7UFWLOAWFHUJAPF5O3M3HM2GQFHYWFIBFVP462GQC
NLKIHI6HPJKXA4ZUOQKS2GGOYWFMT7PLDDEA3Y3RPBBZK4XO4TPAC
2WCFXK4HZUF7JB5E44WAIZCZSTGQNW5O6R32DKDDKCLX2N5JZUUQC
OMLI7JOZETY2RJIZKELRQN2BH7FTA2NSLHAUIMQNPLTC6VK3CKAAC
YWL3OA5HRMQWG6AZEVZY2YBKQHAJM3JJ6HPCCGEZU2KFQ3EJMCEAC
RQG7TDDDSHCXSNZGMUUFM62GGUO43G32FBLKOYJFPNODPBNBD5TQC
OFSMNOASLNIZ56VMIIHRU6X6BX6IXJ2ACMSLGIBSKUTW2DJIBHVAC
U32C3WYNI2JBA2BIQXZTXFN3CDPD6V2MDFBRBEWWD2TS4BRRMYHQC
HU54Y66265W2VOTVERPHEFFKM3FDNZHL5FDTWBE4OX5YIELFNRLAC
35EVA5MHEJMVJWQUXIJWAX43LJZ7YLE5Y4YN5T2SOSTBTQB6HTTQC
7X4JWWW7WOVGPMBIAAEJTWG6NZW5EI5ZIYB33J7YCBDOODFAZXYQC
UFACXWJ2H4IFCSBRRZVVCVLBESKNRL2IX2WM2RDYDMSVHOYA2W6AC
BV2FJEVMVJOC5XDAUJQE27ZW3MPA56EIJAQBRA56MLGJ37XQ7MDQC
UVB2E4S2AV34AW2GF7GGLS534TUTLKX3A34NNHH27QADUY7FI5DAC
5QN7AO5S3UGVJWSP4XFJWFJNC5EMG3VDOCBHGMPIQ4HLV63DOVTAC
6MFPSDGMP62ONLSXZUSKB2CTZ4OOKSFRHHL6N4XA3SSFAIWUJPFQC
P5J5K557OJ5TDY5GLKE74QGCIVI34FI2ANAIBVVRW7NJG5I76VWAC
VOLUME /brust/config
CMD ./brust
WORKDIR brust
RUN git clone https://github.com/irevoire/brust && \
cd brust && \
cargo build --release && \
mv target/release/brust . && \
rm -rf src target
FROM rust:stretch
rand = "*"
use serenity::model::id::ChannelId;
// Scheduler, and trait for .seconds(), .minutes(), etc.
use clokwerk::{Scheduler, TimeUnits};
// Import week days and WeekDay
use std::thread;
use std::time::Duration;
pub fn init() {
let channel = ChannelId(467653564936749056); // salon du bot
let mut scheduler = Scheduler::new();
scheduler
.every(1.day())
.at("08:15")
.and_every(1.day())
.at("11:50")
.and_every(1.day())
.at("17:45")
.run(move || {
println!("sending a new pun");
let mut pun = reqwest::get("http:/pun.irevoire.ovh").unwrap();
if !pun.status().is_success() {
println!("server error when getting a new pun");
return;
}
let pun = pun.text().unwrap();
channel.say(pun).unwrap();
});
thread::spawn(move || loop {
scheduler.run_pending();
thread::sleep(Duration::from_millis(500));
});
}
use serenity::{
framework::standard::Args,
model::channel::Message,
prelude::{Context, TypeMapKey},
};
use std::{
collections::HashMap,
fmt::Write,
fs::File,
io::{Read, Write as wr},
path::Path,
};
pub struct Score;
impl TypeMapKey for Score {
type Value = HashMap<String, i64>;
}
pub struct FileScore;
impl TypeMapKey for FileScore {
type Value = String;
}
pub fn init(filename: &String) -> HashMap<String, i64> {
let mut hash: HashMap<String, i64> = HashMap::default();
let path = Path::new(filename);
let mut file = match File::open(&path) {
Err(why) => panic!("couldn't open file {}", why),
Ok(file) => file,
};
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
for line in s.split("\n") {
if line == "" {
break;
}
let mut split = line.split(" ");
let name = split
.next()
.unwrap_or_else(|| panic!(format!("can't parse this line: {}", line)));
let nb: i64 = split
.next()
.unwrap_or_else(|| panic!(format!("need a score: {}", line)))
.parse()
.unwrap_or_else(|_| panic!(format!("can't parse this score: {}", line)));
hash.insert(name.to_string(), nb);
}
return hash;
}
fn get_user_id(user: String) -> Result<String, String> {
let start;
if !user.starts_with("<@") || !user.ends_with(">") {
return Err("Le nom est mal formé !".to_string());
}
if user.starts_with("<@!") {
start = 3
} else {
start = 2
}
let user_id: u64 = match user[start..user.len() - 1].parse() {
Err(_) => return Err("Le nom est mal formé !".to_string()),
Ok(n) => n,
};
let user = serenity::model::id::UserId(user_id);
return match user.to_user() {
Err(_) => Err("Utilisateur inconnu".to_string()),
Ok(u) => Ok(u.to_string()),
};
}
fn update_score(ctx: &mut Context, msg: &Message, args: &mut Args, update: impl Fn(i64) -> i64) {
let mut fail = false;
for name in args.iter() {
let name = match get_user_id(name.unwrap()) {
Err(_) => {
let _ = msg.react('❎');
fail = true;
continue;
}
Ok(u) => u,
};
if msg.author.to_string() == name {
let _ = msg.react('❎');
fail = true;
continue;
}
let mut data = ctx.data.lock();
let score = data
.get_mut::<Score>()
.expect("Expected Score in ShareMap.");
let entry = score.entry(name.to_string()).or_insert(0);
*entry = update(*entry);
}
if !fail {
let _ = msg.react('👌');
}
}
command!(mdr(ctx, msg, args) {
update_score(ctx, msg, &mut args, |n| n + 1);
save_score(ctx);
return Ok(());
});
command!(nul(ctx, msg, args) {
update_score(ctx, msg, &mut args, |n| n - 1);
save_score(ctx);
return Ok(());
});
command!(blague(ctx, msg, args) {
let mut data = ctx.data.lock();
let scores = data
.get::<Score>()
.expect("Expected Score in ShareMap.");
let mut res = "Blagues :\n".to_string();
if args.len() >= 1 {
for name in args.iter() {
let name = get_user_id(name.unwrap()).unwrap_or("".to_string());
match scores.get(&name) {
Some(v) => write_score(&mut res, &name, *v),
None => (),
}
}
} else {
for (k, v) in scores {
write_score(&mut res, &k, *v);
}
}
if let Err(why) = msg.channel_id.say(&res) {
println!("Error sending message: {:?}", why);
}
fn write_score(base: &mut String, name: &String, value: i64) {
let _ = write!(base, "- {}: {} ", name, value);
let sym = match value {
_ if value > 0 => "🔆",
_ if value < 0 => "❌",
_ => "",
};
let react: String = std::iter::repeat(sym)
.take(value.abs() as usize)
.take(10)
.collect();
let _ = write!(base, "{}\n", react);
}
});
fn save_score(ctx: &mut Context) {
let data = ctx.data.lock();
let scores = data.get::<Score>().expect("Expected Score in ShareMap.");
let filename = data
.get::<FileScore>()
.expect("Expected FileScore in ShareMap.");
let mut buffer = File::create(filename).unwrap();
for (k, v) in scores {
if let Err(e) = buffer.write(format!("{} {}\n", k, v).as_bytes()) {
println!("Can't save the score: {}", e);
}
}
}
use rand::seq::SliceRandom;
use rand::thread_rng;
use serenity::framework::standard::{macros::command, Args, CommandResult};
use serenity::{
model::channel::Message,
prelude::{Context, TypeMapKey},
};
pub struct Tg;
// we are going to store the insults in the first vector and random index in the second
impl TypeMapKey for Tg {
type Value = (Vec<&'static str>, Vec<usize>);
}
#[command]
pub fn tg(ctx: &mut Context, msg: &Message, _args: Args) -> CommandResult {
let mut data = ctx.data.write();
let insults = data.get_mut::<Tg>();
if insults.is_none() {
let _ = msg.reply(&ctx, "Jesus is dead");
return Ok(());
}
let insults = insults.unwrap();
let mut index = insults.1.pop();
// generate a new list of indexes
if index.is_none() {
let mut rng = thread_rng();
insults.1 = (0..insults.0.len()).collect::<Vec<usize>>();
insults.1.shuffle(&mut rng);
index = insults.1.pop();
}
let index = index.expect("The insults vector look empty?");
let _ = msg.channel_id.say(&ctx, insults.0[index]);
Ok(())
}
pub fn init() -> (Vec<&'static str>, Vec<usize>) {
let insults = vec![
"Va marcher sur des Légos",
"Gredin",
"Tête de tétard",
"Sac à puces",
"Espèce d'épinard",
"Patate",
"Banane",
"Capitaine de bateau-lavoir",
"Cornichon",
"Paltoquet",
"Philistin",
"Terrine",
"Foutriquet",
"Scélérat",
"Mauviette",
"Malotru",
"Goujat",
"Vil faquin",
"Maraud",
"Crétin des Alpes",
"Parisien",
"Pute",
"Grosse pute",
"Petite pute",
"Trou duc",
"Syndicaliste",
"Gilet jaune",
"Macroniste",
"Fécalomes",
"Raclure de bidet",
"Balai à chiotte",
"Fils de yack",
"Filloniste",
"Lepéniste",
"Mélenchoniste",
"Sarkozyste",
"Capitaliste",
"Homéopathe",
"Antivax",
"Moule à gaufre",
"Escogriffe",
"Andouille",
"Tocard",
"Bouffon",
"Zigoto",
"Saltimbanque",
"Termaji",
"Branquignole",
"Enclume",
"Va te faire cuire le cul",
"Takezen",
"Pimfle",
"Caillou",
"Goulamas",
"Gougnafier",
"Pouffre",
"Poulpe",
"Figure de pain sucé",
"Figure d'angoisse",
"Front d'endive",
"Tronc de figuier",
"Guit",
"Féministe",
"Sac à pus",
"Blaireau",
"Bordel à Cul",
"Boudin",
"Bouffon",
"Bougre d’âne",
"Bougre d’imbécile",
"Bougre de congre",
"Bougre de conne",
"Boule de pus",
"Boursemolle",
"Branleur",
"Branlotin",
"Branque",
"Branquignole",
"Brêle",
"Cagole",
"Carburateur à Beaujolais",
"Chiure de pigeon",
"Clampin",
"Cloaque",
"Clodo",
"Cornegidouille",
"Couille de tétard",
"Couille molle",
"Crétin des îles",
"Crétin goîtreux",
"Cul de babouin",
"Enculeur de mouches",
"Erreur de la nature",
"Fils de cheminot",
"Fils de syndicaliste",
"Face de cul",
"Face de pet",
"Face de rat",
"Fiente",
"Fiote",
"Flaque de pus",
"Fonctionnaire",
"Four à merde",
"Furoncle",
"Garage à bite",
"Glandus",
"Gourdasse",
"Gourgandine",
"Grand cornichon",
"Gras du bide",
"Grognasse",
"Gros caca poilu",
"Grosse truie violette",
"Gueule de fion",
"Lèche-cul",
"Manche à couille",
"Mange merde",
"Margoulin",
"Merdaillon",
"Merde molle",
"Moudlabite",
"Peau de bite",
"Pecore",
"Pignouf",
"Pimbêche",
"Pisse-vinaigre",
"Pompe à merde",
"Pouffe",
"Pouffiasse",
"Pute au rabais",
"Pute borgne",
"Ramassis de chiure de moineau",
"Sac à Vin",
"Sac à Foutre",
"Vieux",
"Sauvage",
"Serpillière à foutre",
"Tas de saindoux",
"Thon",
"Tire couilles",
"Tête d’ampoule",
"Tête de bite",
"Tête de chibre",
"Tête de con",
"Tête de noeud",
"Tête à claques",
"Vioque",
"Wisigoth",
"T’es con comme du plastique",
"T’es comme une pizza, sauf qu’elle on peut l’avoir sans champignons",
"Ton père le chauve",
"Ta mère elle boit l’eau des pâtes",
"Va pisser sur un fil électrique",
"Va jouer sur l’autoroute",
"Va jouer sur la voie ferrée",
"Beurre doux",
"Rentre dans ton pays",
"Avortement raté",
"Va jouer dans le mixer",
"Tes parents ils ont jeté le bébé et élevé le placenta",
"Ta mère en sarouel",
"T’es moche même de dos",
"Puterelle",
];
let mut rng = thread_rng();
let mut indexes = (0..insults.len()).collect::<Vec<usize>>();
indexes.shuffle(&mut rng);
(insults, indexes)
}
let mut data = client.data.lock();
data.insert::<commands::blague::Score>(commands::blague::init(&filename));
data.insert::<commands::blague::FileScore>(filename);
let mut data = client.data.write();
data.insert::<commands::tg::Tg>(commands::tg::init());
.configure(|c| {
c.allow_whitespace(true)
.on_mention(true)
.prefix("!")
.delimiters(vec![", ", ",", " "])
})
.customised_help(help_commands::with_embeds, |c| {
c.individual_command_tip("🦀 Bonjour 🦀")
.max_levenshtein_distance(5)
.command_not_found_text("Could not find: `{}`.")
.striked_commands_tip(None)
})
.group("Tribunal", |g| {
g.desc("Commande du tribunal des blagues")
.command("nul", |c| c.cmd(commands::blague::nul).desc("Blague nulle"))
.command("mdr", |c| c.cmd(commands::blague::mdr).desc("Bonne blague"))
.command("blague", |c| {
c.cmd(commands::blague::blague)
.desc("Affiche le score des blagues")
})
}),
.configure(|c| c.prefix("!").delimiters(vec![", ", ",", " "]))
.group(&GENERAL_GROUP),