Initial Commit
This commit is contained in:
commit
ef13383f5a
|
@ -0,0 +1,2 @@
|
||||||
|
DISCORD_BOT_TOKEN=
|
||||||
|
RUST_LOG=
|
|
@ -0,0 +1,3 @@
|
||||||
|
/target
|
||||||
|
/.env
|
||||||
|
/.vscode
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "arona"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Rekai Musuka <rekai@musuka.dev>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bluearch-recruitment = { git = "https://github.com/Paoda/bluearch-recruitment.git", branch = "main", version = "^0.1" }
|
||||||
|
dotenv = "^0.15"
|
||||||
|
env_logger = "^0.8"
|
||||||
|
lazy_static = "^1.4"
|
||||||
|
log = "^0.4"
|
||||||
|
serde = "^1.0"
|
||||||
|
serde_json = "^1.0"
|
||||||
|
serenity = "^0.10"
|
||||||
|
tokio = { version = "^1.0", features = ["macros", "rt-multi-thread"] }
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Rekai Nyangadzayi Musuka
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,407 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ヒナ",
|
||||||
|
"eng": "Hina"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "イオリ",
|
||||||
|
"eng": "Iori"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ハルナ",
|
||||||
|
"eng": "Haruna"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "イズミ",
|
||||||
|
"eng": "Izumi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Aru",
|
||||||
|
"jpn": "アル"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "スミレ",
|
||||||
|
"eng": "Sumire"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "エイミ",
|
||||||
|
"eng": "Iemi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Karin",
|
||||||
|
"jpn": "カリン"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ネル",
|
||||||
|
"eng": "Neru"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Maki",
|
||||||
|
"jpn": "マキ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Hibiki",
|
||||||
|
"jpn": "ヒビキ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Saya",
|
||||||
|
"jpn": "サヤ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Shun",
|
||||||
|
"jpn": "シュン"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Shiroko",
|
||||||
|
"jpn": "シロコ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Hoshino",
|
||||||
|
"jpn": "ホシノ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ヒフミ",
|
||||||
|
"eng": "Hifumi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Tsurugi",
|
||||||
|
"jpn": "ツルギ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "アカリ",
|
||||||
|
"eng": "Akari"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ジュンコ",
|
||||||
|
"eng": "Junko"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ムツキ",
|
||||||
|
"eng": "Mutsuki"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Kayoko",
|
||||||
|
"jpn": "カヨコ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "フウカ",
|
||||||
|
"eng": "Fuuka"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ユウカ",
|
||||||
|
"eng": "Yuuka"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Akane",
|
||||||
|
"jpn": "アカネ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ハル",
|
||||||
|
"eng": "Haru"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Utaha",
|
||||||
|
"jpn": "ウタハ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "チセ",
|
||||||
|
"eng": "Chise"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Tsubaki",
|
||||||
|
"jpn": "ツバキ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "セリカ",
|
||||||
|
"eng": "Serika"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "アヤネ",
|
||||||
|
"eng": "Ayane"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Hasumi",
|
||||||
|
"jpn": "ハスミ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Hanae",
|
||||||
|
"jpn": "ハナエ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Airi",
|
||||||
|
"jpn": "アイリ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ノゾミ",
|
||||||
|
"eng": "Nozomi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Chinatsu",
|
||||||
|
"jpn": "チナツ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Haruka",
|
||||||
|
"jpn": "ハルカ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "ジュリ",
|
||||||
|
"eng": "Juri"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "コタマ",
|
||||||
|
"eng": "Kotama"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "アスナ",
|
||||||
|
"eng": "Asuna"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "コトリ",
|
||||||
|
"eng": "Kotori"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "フィーナ",
|
||||||
|
"eng": "Pina"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"jpn": "スズミ",
|
||||||
|
"eng": "Suzumi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Shimiko",
|
||||||
|
"jpn": "シミコ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Serina",
|
||||||
|
"jpn": "セリナ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {
|
||||||
|
"translations": {
|
||||||
|
"eng": "Yoshimi",
|
||||||
|
"jpn": "ヨシミ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": 1
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,159 @@
|
||||||
|
use bluearch_recruitment::banner::{Banner, BannerBuilder};
|
||||||
|
use bluearch_recruitment::gacha::{GachaBuilder, Recruitment};
|
||||||
|
use bluearch_recruitment::i18n::Language;
|
||||||
|
use bluearch_recruitment::student::Student;
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use log::{error, info};
|
||||||
|
use serenity::async_trait;
|
||||||
|
use serenity::client::{Client, Context, EventHandler};
|
||||||
|
use serenity::framework::standard::{
|
||||||
|
macros::{command, group},
|
||||||
|
CommandResult, StandardFramework,
|
||||||
|
};
|
||||||
|
use serenity::model::channel::Message;
|
||||||
|
use std::env;
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
#[group]
|
||||||
|
#[commands(ping)]
|
||||||
|
struct General;
|
||||||
|
|
||||||
|
#[group]
|
||||||
|
#[commands(roll, roll10, banner)]
|
||||||
|
struct RecruitmentCommands;
|
||||||
|
|
||||||
|
struct Handler;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl EventHandler for Handler {}
|
||||||
|
|
||||||
|
const STUDENTS_JSON: &str = include_str!("../data/students.json");
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref STUDENTS: Vec<Student> = serde_json::from_str(STUDENTS_JSON).unwrap();
|
||||||
|
static ref BANNER: Banner = create_banner();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
dotenv().ok();
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let framework = StandardFramework::new()
|
||||||
|
.configure(|c| c.prefix("!")) // set the bot's prefix to "!"
|
||||||
|
.group(&GENERAL_GROUP)
|
||||||
|
.group(&RECRUITMENTCOMMANDS_GROUP);
|
||||||
|
|
||||||
|
// Login with a bot token from the environment
|
||||||
|
let token = env::var("DISCORD_BOT_TOKEN").expect("DISCORD_BOT_TOKEN was not set.");
|
||||||
|
info!("アロナ has started with Bot Token: {}", &token);
|
||||||
|
|
||||||
|
let mut client = Client::builder(token)
|
||||||
|
.event_handler(Handler)
|
||||||
|
.framework(framework)
|
||||||
|
.await
|
||||||
|
.expect("Failed to create Serenity Client");
|
||||||
|
|
||||||
|
info!("Successfully created the Serenity Client");
|
||||||
|
|
||||||
|
// start listening for events by starting a single shard
|
||||||
|
if let Err(why) = client.start().await {
|
||||||
|
error!("An error occurred while running the client: {:?}", why);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let author_name = format!("{}#{}", msg.author.name, msg.author.discriminator);
|
||||||
|
info!("Ping received from: {}", author_name);
|
||||||
|
|
||||||
|
let now = SystemTime::now();
|
||||||
|
|
||||||
|
match now.duration_since(UNIX_EPOCH) {
|
||||||
|
Ok(now_timestamp) => {
|
||||||
|
let diff = now_timestamp.as_millis() - msg.timestamp.timestamp_millis() as u128;
|
||||||
|
msg.reply(ctx, format!("Pong! (Response: {}ms)", diff))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
msg.reply(ctx, "Pong! (Response: ??ms)").await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
async fn roll(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let author_name = format!("{}#{}", msg.author.name, msg.author.discriminator);
|
||||||
|
info!("{} Requested a single roll", author_name);
|
||||||
|
|
||||||
|
let student = BANNER.roll();
|
||||||
|
|
||||||
|
msg.reply(
|
||||||
|
ctx,
|
||||||
|
format!(
|
||||||
|
"You Pulled: {} {}",
|
||||||
|
student.name.get(Language::English).unwrap(),
|
||||||
|
student.rarity
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
async fn roll10(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let author_name = format!("{}#{}", msg.author.name, msg.author.discriminator);
|
||||||
|
info!("{} Requested a 10-roll", author_name);
|
||||||
|
|
||||||
|
let students = BANNER.roll10();
|
||||||
|
let mut response = "You Pulled:\n".to_string();
|
||||||
|
|
||||||
|
for student in students.iter() {
|
||||||
|
response += &format!(
|
||||||
|
"{} {}\n",
|
||||||
|
student.name.get(Language::English).unwrap(),
|
||||||
|
student.rarity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.reply(ctx, response).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
async fn banner(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
msg.reply(ctx, format!("Current Banner: {}", BANNER.name))
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_banner() -> Banner {
|
||||||
|
let pool: Vec<Student> = STUDENTS
|
||||||
|
.iter()
|
||||||
|
.filter(|student| student.name != "ノゾミ")
|
||||||
|
.map(|student| student.clone())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let sparkable: Vec<Student> = pool
|
||||||
|
.iter()
|
||||||
|
.filter(|student| student.name == "ホシノ" || student.name == "シロコ")
|
||||||
|
.map(|student| student.clone())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let gacha = GachaBuilder::new(79.0, 18.5, 2.5)
|
||||||
|
.with_pool(pool)
|
||||||
|
.with_priority(&sparkable, 0.7)
|
||||||
|
.finish()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
BannerBuilder::new("ピックアップ募集")
|
||||||
|
.with_gacha(&gacha)
|
||||||
|
.with_name_translation(Language::English, "Rate-Up Recruitment")
|
||||||
|
.with_sparkable_students(&sparkable)
|
||||||
|
.finish()
|
||||||
|
.unwrap()
|
||||||
|
}
|
Loading…
Reference in New Issue