Compare commits
3 Commits
feature/FixURLS
...
0.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ae38b0e01 | |||
| b2059a76c6 | |||
| fcbe163d18 |
Generated
+1
-1
@@ -4,7 +4,7 @@ version = 4
|
||||
|
||||
[[package]]
|
||||
name = "RhythmWorks"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"reqwest",
|
||||
"semver",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "RhythmWorks"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
+65
-46
@@ -8,18 +8,12 @@ use songbird::SerenityInit;
|
||||
use songbird::get;
|
||||
use songbird::input::HlsRequest;
|
||||
use songbird::input::Input;
|
||||
use songbird::tracks::TrackHandle;
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
use std::sync::Arc;
|
||||
pub mod modules;
|
||||
|
||||
type TrackMap = Arc<Mutex<HashMap<u64, TrackHandle>>>;
|
||||
struct Handler {
|
||||
track_map: TrackMap,
|
||||
}
|
||||
struct Handler;
|
||||
fn get_user_voice_channel(ctx: &Context, msg: &Message) -> Option<ChannelId> {
|
||||
let guild_id = msg.guild_id?;
|
||||
let guild = ctx.cache.guild(guild_id)?;
|
||||
@@ -77,61 +71,78 @@ impl EventHandler for Handler {
|
||||
}
|
||||
}
|
||||
if msg.content.starts_with("!play") {
|
||||
let mut url = msg
|
||||
let mut yt_url = msg
|
||||
.content
|
||||
.strip_prefix("!play ")
|
||||
.unwrap_or("")
|
||||
.trim()
|
||||
.to_string();
|
||||
let separator = "&";
|
||||
if let Some(offset) = url.find(separator) {
|
||||
url.truncate(offset);
|
||||
if let Some(offset) = yt_url.find('&') {
|
||||
yt_url.truncate(offset);
|
||||
}
|
||||
if url.is_empty() {
|
||||
if yt_url.is_empty() {
|
||||
let _ = msg.reply(&ctx, "Please provide a YouTube URL.").await;
|
||||
return;
|
||||
}
|
||||
let guild_id = msg.guild_id.unwrap();
|
||||
let manager = songbird::get(&ctx)
|
||||
.await
|
||||
.expect("Songbird Voice client placed in at initialisation.")
|
||||
.clone();
|
||||
let handler_lock = if let Some(handler) = manager.get(guild_id) {
|
||||
handler
|
||||
let manager = songbird::get(&ctx).await.unwrap().clone();
|
||||
let handler_lock = if let Some(call) = manager.get(guild_id) {
|
||||
call
|
||||
} else {
|
||||
let channel_id = get_user_voice_channel(&ctx, &msg);
|
||||
match channel_id {
|
||||
Some(c) => manager.join(guild_id, c).await.unwrap(),
|
||||
let channel_id = match get_user_voice_channel(&ctx, &msg) {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
let _ = msg.reply(&ctx, "Join a voice channel first!").await;
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
manager.join(guild_id, channel_id).await.unwrap()
|
||||
};
|
||||
let output = Command::new("./yt-dlp")
|
||||
.args(["-f", "bestaudio", "-g", &url])
|
||||
.args(["-f", "bestaudio", "-g", &yt_url])
|
||||
.stdout(Stdio::piped())
|
||||
.output()
|
||||
.expect("Failed");
|
||||
let url_bytes = output.stdout;
|
||||
let url = String::from_utf8(url_bytes).expect("Failed");
|
||||
let mut handler = handler_lock.lock().await;
|
||||
let input = Input::from(HlsRequest::new(reqwest::Client::new(), url.to_string()));
|
||||
let track_handle = handler.play_input(input);
|
||||
let _ = track_handle.play();
|
||||
self.track_map
|
||||
.lock()
|
||||
.await
|
||||
.insert(guild_id.into(), track_handle);
|
||||
let _ = msg.channel_id.say(&ctx.http, "🎶 Playing...").await;
|
||||
.expect("yt-dlp failed");
|
||||
if !output.status.success() {
|
||||
let _ = msg.reply(&ctx, "Failed to fetch audio stream.").await;
|
||||
return;
|
||||
}
|
||||
let stream_url = String::from_utf8(output.stdout)
|
||||
.expect("Invalid UTF-8")
|
||||
.trim()
|
||||
.to_string();
|
||||
let mut call = handler_lock.lock().await;
|
||||
let input = Input::from(HlsRequest::new(reqwest::Client::new(), stream_url));
|
||||
let _ = call.enqueue_input(input).await;
|
||||
let position = call.queue().len();
|
||||
let response = if position == 1 {
|
||||
"🎶 Now playing!".to_string()
|
||||
} else {
|
||||
format!("🎶 Added Song to Queue: #{}", position)
|
||||
};
|
||||
let _ = msg.channel_id.say(&ctx.http, response).await;
|
||||
}
|
||||
if msg.content == "!skip" {
|
||||
let guild_id = match msg.guild_id {
|
||||
Some(g) => g,
|
||||
None => return,
|
||||
};
|
||||
let manager = songbird::get(&ctx).await.unwrap();
|
||||
if let Some(call) = manager.get(guild_id) {
|
||||
let call = call.lock().await;
|
||||
let _ = call.queue().skip();
|
||||
let _ = msg.channel_id.say(&ctx.http, "Skipped").await;
|
||||
}
|
||||
}
|
||||
if msg.content == "!pause" {
|
||||
let guild_id = match msg.guild_id {
|
||||
Some(g) => g,
|
||||
None => return,
|
||||
};
|
||||
if let Some(handle) = self.track_map.lock().await.get(&guild_id.into()) {
|
||||
let _ = handle.pause();
|
||||
let manager = songbird::get(&ctx).await.unwrap();
|
||||
if let Some(call) = manager.get(guild_id) {
|
||||
let call = call.lock().await;
|
||||
let _ = call.queue().pause();
|
||||
}
|
||||
}
|
||||
if msg.content == "!resume" {
|
||||
@@ -139,8 +150,10 @@ impl EventHandler for Handler {
|
||||
Some(g) => g,
|
||||
None => return,
|
||||
};
|
||||
if let Some(handle) = self.track_map.lock().await.get(&guild_id.into()) {
|
||||
let _ = handle.play();
|
||||
let manager = songbird::get(&ctx).await.unwrap();
|
||||
if let Some(call) = manager.get(guild_id) {
|
||||
let call = call.lock().await;
|
||||
let _ = call.queue().resume();
|
||||
}
|
||||
}
|
||||
if msg.content == "!stop" {
|
||||
@@ -148,8 +161,10 @@ impl EventHandler for Handler {
|
||||
Some(g) => g,
|
||||
None => return,
|
||||
};
|
||||
if let Some(handle) = self.track_map.lock().await.get(&guild_id.into()) {
|
||||
let _ = handle.stop();
|
||||
let manager = songbird::get(&ctx).await.unwrap();
|
||||
if let Some(call) = manager.get(guild_id) {
|
||||
let call = call.lock().await;
|
||||
let _ = call.queue().stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,24 +172,28 @@ impl EventHandler for Handler {
|
||||
println!("{} is connected!", ready.user.name);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
println!("RhythmWorks Copyright (C) 2025 James Brotosky\n
|
||||
println!(
|
||||
"RhythmWorks Copyright (C) 2025 James Brotosky\n
|
||||
This program comes with ABSOLUTELY NO WARRANTY\n
|
||||
This is free software, and you are welcome to redistribute it under certain conditions.");
|
||||
This is free software, and you are welcome to redistribute it under certain conditions."
|
||||
);
|
||||
updator::update().await;
|
||||
println!("Please paste in your bot token");
|
||||
let mut input = String::new();
|
||||
io::stdin().read_line(&mut input).expect("Failed to read line");
|
||||
io::stdin()
|
||||
.read_line(&mut input)
|
||||
.expect("Failed to read line");
|
||||
let token = input.trim();
|
||||
let intents = GatewayIntents::GUILD_MESSAGES
|
||||
| GatewayIntents::GUILDS
|
||||
| GatewayIntents::DIRECT_MESSAGES
|
||||
| GatewayIntents::MESSAGE_CONTENT
|
||||
| GatewayIntents::GUILD_VOICE_STATES;
|
||||
let track_map: TrackMap = Arc::new(Mutex::new(HashMap::new()));
|
||||
let mut client = Client::builder(&token, intents)
|
||||
.event_handler(Handler { track_map })
|
||||
.event_handler(Handler)
|
||||
.register_songbird()
|
||||
.await
|
||||
.expect("Err creating client");
|
||||
|
||||
+12
-8
@@ -1,15 +1,22 @@
|
||||
use std::thread;
|
||||
|
||||
use serde::Deserialize;
|
||||
use semver::Version;
|
||||
use reqwest;
|
||||
use semver::Version;
|
||||
use serde::Deserialize;
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Release {
|
||||
tag_name: String,
|
||||
}
|
||||
|
||||
pub async fn update() {
|
||||
let body = reqwest::get("https://git.racooncity.org/api/v1/repos/brotoskyj/RhythmWorks/releases/latest").await.unwrap().text().await.unwrap();
|
||||
let body = reqwest::get(
|
||||
"https://git.racooncity.org/api/v1/repos/brotoskyj/RhythmWorks/releases/latest",
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.text()
|
||||
.await
|
||||
.unwrap();
|
||||
let release_info: Release = serde_json::from_str(&body).unwrap();
|
||||
let latest_version = Version::parse(&release_info.tag_name).unwrap();
|
||||
let current_version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
|
||||
@@ -18,9 +25,6 @@ pub async fn update() {
|
||||
println!("URL: https://git.racooncity.org/brotoskyj/RhythmWorks/releases");
|
||||
thread::sleep(std::time::Duration::from_secs(10));
|
||||
std::process::exit(1);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user