Compare commits

..

3 commits

Author SHA1 Message Date
0478f634fa
feat; modified the command that interacts with teh server to accomodate bedrock players
Some checks failed
On_Push / lint_clippy (push) Failing after 3m22s
On_Push / lint_fmt (push) Failing after 5s
On_Push / build (push) Has been skipped
On_Push / deploy (push) Has been skipped
For #26
2024-11-30 00:55:23 +00:00
ee0c8f0987
feat; can now handle bedrock in the command
For #26
2024-11-30 00:44:36 +00:00
b55650b221
db: add another col to store the bedrock id
For #26
2024-11-29 23:13:28 +00:00
5 changed files with 144 additions and 43 deletions

48
Cargo.lock generated
View file

@ -107,9 +107,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.89" version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
[[package]] [[package]]
name = "async-channel" name = "async-channel"
@ -143,7 +143,7 @@ dependencies = [
"async-task", "async-task",
"concurrent-queue", "concurrent-queue",
"fastrand 2.1.1", "fastrand 2.1.1",
"futures-lite 2.3.0", "futures-lite 2.5.0",
"slab", "slab",
] ]
@ -158,21 +158,21 @@ dependencies = [
"async-io", "async-io",
"async-lock", "async-lock",
"blocking", "blocking",
"futures-lite 2.3.0", "futures-lite 2.5.0",
"once_cell", "once_cell",
] ]
[[package]] [[package]]
name = "async-io" name = "async-io"
version = "2.3.4" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
dependencies = [ dependencies = [
"async-lock", "async-lock",
"cfg-if", "cfg-if",
"concurrent-queue", "concurrent-queue",
"futures-io", "futures-io",
"futures-lite 2.3.0", "futures-lite 2.5.0",
"parking", "parking",
"polling", "polling",
"rustix", "rustix",
@ -206,7 +206,7 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-lite 2.3.0", "futures-lite 2.5.0",
"gloo-timers", "gloo-timers",
"kv-log-macro", "kv-log-macro",
"log", "log",
@ -381,7 +381,7 @@ dependencies = [
"async-channel 2.3.1", "async-channel 2.3.1",
"async-task", "async-task",
"futures-io", "futures-io",
"futures-lite 2.3.0", "futures-lite 2.5.0",
"piper", "piper",
] ]
@ -586,9 +586,9 @@ dependencies = [
[[package]] [[package]]
name = "curl" name = "curl"
version = "0.4.46" version = "0.4.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" checksum = "d9fb4d13a1be2b58f14d60adba57c9834b78c62fd86c3e76a148f732686e9265"
dependencies = [ dependencies = [
"curl-sys", "curl-sys",
"libc", "libc",
@ -601,9 +601,9 @@ dependencies = [
[[package]] [[package]]
name = "curl-sys" name = "curl-sys"
version = "0.4.75+curl-8.10.0" version = "0.4.78+curl-8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a4fd752d337342e4314717c0d9b6586b059a120c80029ebe4d49b11fec7875e" checksum = "8eec768341c5c7789611ae51cf6c459099f22e64a5d5d0ce4892434e33821eaf"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
@ -923,9 +923,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-lite" name = "futures-lite"
version = "2.3.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1"
dependencies = [ dependencies = [
"fastrand 2.1.1", "fastrand 2.1.1",
"futures-core", "futures-core",
@ -1298,7 +1298,7 @@ dependencies = [
"httpdate", "httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"socket2 0.4.10", "socket2 0.5.7",
"tokio", "tokio",
"tower-service", "tower-service",
"tracing", "tracing",
@ -1907,18 +1907,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.1.5" version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95"
dependencies = [ dependencies = [
"pin-project-internal", "pin-project-internal",
] ]
[[package]] [[package]]
name = "pin-project-internal" name = "pin-project-internal"
version = "1.1.5" version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1977,9 +1977,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]] [[package]]
name = "polling" name = "polling"
version = "3.7.3" version = "3.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"concurrent-queue", "concurrent-queue",
@ -3521,9 +3521,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]] [[package]]
name = "value-bag" name = "value-bag"
version = "1.9.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"

View file

@ -14,6 +14,9 @@ name = "update_users"
[[bin]] [[bin]]
name = "update_minecraft" name = "update_minecraft"
[[bin]]
name = "test"
[dependencies] [dependencies]
# discord library # discord library
serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache"] } serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache"] }

View file

@ -0,0 +1,3 @@
-- Using this col we will be able to see if someone has a bedrock account (as well as a java one)
ALTER TABLE wolves ADD COLUMN minecraft_uid TEXT;

View file

@ -15,18 +15,29 @@ pub(crate) mod user {
pub(crate) mod add { pub(crate) mod add {
use super::*; use super::*;
use crate::commands::link_email::link::get_server_member_discord; use crate::commands::link_email::link::get_server_member_discord;
use serde::{Deserialize, Serialize};
use serenity::model::id::UserId; use serenity::model::id::UserId;
use skynet_discord_bot::{whitelist_update, Config, Minecraft, Wolves}; use skynet_discord_bot::{whitelist_update, Config, Minecraft, Wolves};
use sqlx::Error; use sqlx::Error;
pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {
command.name("link_minecraft").description("Link your minecraft account").create_option(|option| { command
option .name("link_minecraft")
.name("minecraft-username") .description("Link your minecraft account")
.description("Your Minecraft username") .create_option(|option| {
.kind(CommandOptionType::String) option
.required(true) .name("minecraft-username")
}) .description("Your Minecraft username")
.kind(CommandOptionType::String)
.required(true)
})
.create_option(|option| {
option
.name("java-account")
.description("Is this a Java account?")
.kind(CommandOptionType::Boolean)
.required(false)
})
} }
pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String { pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> String {
@ -61,19 +72,42 @@ pub(crate) mod user {
return "Please provide a valid username".to_string(); return "Please provide a valid username".to_string();
}; };
// insert the username into the database // this is always true unless they state its not
match add_minecraft(&db, &command.user.id, username).await { let mut java = true;
Ok(_) => {} if let Some(x) = command.data.options.get(1) {
Err(e) => { if let Some(CommandDataOptionValue::Boolean(z)) = x.to_owned().resolved {
dbg!("{:?}", e); java = z;
return format!("Failure to minecraft username {:?}", username); }
}
if java {
// insert the username into the database
match add_minecraft(&db, &command.user.id, username).await {
Ok(_) => {}
Err(e) => {
dbg!("{:?}", e);
return format!("Failure to minecraft username {:?}", username);
}
}
} else {
match get_minecraft_bedrock(username, &config.minecraft_mcprofile).await {
None => {
return format!("No UID found for {:?}", username);
}
Some(x) => match add_minecraft_bedrock(&db, &command.user.id, &x.floodgateuid).await {
Ok(_) => {}
Err(e) => {
dbg!("{:?}", e);
return format!("Failure to minecraft UID {:?}", &x.floodgateuid);
}
},
} }
} }
// get a list of servers that the user is a member of // get a list of servers that the user is a member of
if let Ok(servers) = get_servers(&db, &command.user.id).await { if let Ok(servers) = get_servers(&db, &command.user.id).await {
for server in servers { for server in servers {
whitelist_update(&vec![username.to_string()], &server.minecraft, &config.discord_token_minecraft).await; whitelist_update(&vec![(username.to_string(), java)], &server.minecraft, &config.discord_token_minecraft).await;
} }
} }
@ -94,6 +128,51 @@ pub(crate) mod user {
.await .await
} }
#[derive(Serialize, Deserialize, Debug)]
struct BedrockDetails {
pub gamertag: String,
pub xuid: String,
pub floodgateuid: String,
pub icon: String,
pub gamescore: String,
pub accounttier: String,
pub textureid: String,
pub skin: String,
pub linked: bool,
pub java_uuid: String,
pub java_name: String,
}
async fn get_minecraft_bedrock(username: &str, api_key: &str) -> Option<BedrockDetails> {
let url = format!("https://mcprofile.io/api/v1/bedrock/gamertag/{username}/");
match surf::get(url)
.header("x-api-key", api_key)
.header("User-Agent", "UL Computer Society")
.recv_json()
.await
{
Ok(res) => Some(res),
Err(e) => {
dbg!(e);
None
}
}
}
async fn add_minecraft_bedrock(db: &Pool<Sqlite>, user: &UserId, minecraft: &str) -> Result<Option<Wolves>, Error> {
sqlx::query_as::<_, Wolves>(
"
UPDATE wolves
SET minecraft_uid = ?2
WHERE discord = ?1;
",
)
.bind(*user.as_u64() as i64)
.bind(minecraft)
.fetch_optional(db)
.await
}
async fn get_servers(db: &Pool<Sqlite>, discord: &UserId) -> Result<Vec<Minecraft>, Error> { async fn get_servers(db: &Pool<Sqlite>, discord: &UserId) -> Result<Vec<Minecraft>, Error> {
sqlx::query_as::<_, Minecraft>( sqlx::query_as::<_, Minecraft>(
" "

View file

@ -31,6 +31,7 @@ pub struct Config {
// tokens for discord and other API's // tokens for discord and other API's
pub discord_token: String, pub discord_token: String,
pub discord_token_minecraft: String, pub discord_token_minecraft: String,
pub minecraft_mcprofile: String,
// email settings // email settings
pub mail_smtp: String, pub mail_smtp: String,
@ -58,6 +59,7 @@ pub fn get_config() -> Config {
let mut config = Config { let mut config = Config {
discord_token: "".to_string(), discord_token: "".to_string(),
discord_token_minecraft: "".to_string(), discord_token_minecraft: "".to_string(),
minecraft_mcprofile: "".to_string(),
home: ".".to_string(), home: ".".to_string(),
database: "database.db".to_string(), database: "database.db".to_string(),
@ -82,6 +84,9 @@ pub fn get_config() -> Config {
if let Ok(x) = env::var("DISCORD_TOKEN_MINECRAFT") { if let Ok(x) = env::var("DISCORD_TOKEN_MINECRAFT") {
config.discord_token_minecraft = x.trim().to_string(); config.discord_token_minecraft = x.trim().to_string();
} }
if let Ok(x) = env::var("MINECRAFT_MCPROFILE_KEY") {
config.minecraft_mcprofile = x.trim().to_string();
}
if let Ok(x) = env::var("EMAIL_SMTP") { if let Ok(x) = env::var("EMAIL_SMTP") {
config.mail_smtp = x.trim().to_string(); config.mail_smtp = x.trim().to_string();
@ -130,6 +135,7 @@ pub struct ServerMembersWolves {
pub email: String, pub email: String,
pub discord: Option<UserId>, pub discord: Option<UserId>,
pub minecraft: Option<String>, pub minecraft: Option<String>,
pub minecraft_uid: Option<String>,
} }
impl<'r> FromRow<'r, SqliteRow> for ServerMembersWolves { impl<'r> FromRow<'r, SqliteRow> for ServerMembersWolves {
fn from_row(row: &'r SqliteRow) -> Result<Self, Error> { fn from_row(row: &'r SqliteRow) -> Result<Self, Error> {
@ -154,6 +160,7 @@ impl<'r> FromRow<'r, SqliteRow> for ServerMembersWolves {
email: row.try_get("email")?, email: row.try_get("email")?,
discord, discord,
minecraft: row.try_get("minecraft")?, minecraft: row.try_get("minecraft")?,
minecraft_uid: row.try_get("minecraft_uid")?,
}) })
} }
} }
@ -699,7 +706,10 @@ pub async fn update_server(server_id: &str, db: &Pool<Sqlite>, g_id: &GuildId, c
let mut usernames = vec![]; let mut usernames = vec![];
for member in get_server_member_bulk(db, g_id).await { for member in get_server_member_bulk(db, g_id).await {
if let Some(x) = member.minecraft { if let Some(x) = member.minecraft {
usernames.push(x); usernames.push((x, true));
}
if let Some(x) = member.minecraft_uid {
usernames.push((x, true));
} }
} }
if !usernames.is_empty() { if !usernames.is_empty() {
@ -763,13 +773,19 @@ struct BodyDelete {
files: Vec<String>, files: Vec<String>,
} }
pub async fn whitelist_update(add: &Vec<String>, server: &str, token: &str) { pub async fn whitelist_update(add: &Vec<(String, bool)>, server: &str, token: &str) {
let url_base = format!("http://panel.games.skynet.ie/api/client/servers/{server}"); let url_base = format!("http://panel.games.skynet.ie/api/client/servers/{server}");
let bearer = format!("Bearer {token}"); let bearer = format!("Bearer {token}");
for name in add { for (name, java) in add {
let data = BodyCommand { let data = if *java {
command: format!("whitelist add {name}"), BodyCommand {
command: format!("whitelist add {name}"),
}
} else {
BodyCommand {
command: format!("fwhitelist add {name}"),
}
}; };
post(&format!("{url_base}/command"), &bearer, &data).await; post(&format!("{url_base}/command"), &bearer, &data).await;
} }