Added whitelist
This commit is contained in:
parent
639018b4fa
commit
fbebccc68c
|
@ -3,3 +3,4 @@ Cargo.lock
|
||||||
test_server/*
|
test_server/*
|
||||||
main_icon.png
|
main_icon.png
|
||||||
motd.json
|
motd.json
|
||||||
|
whitelist.json
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
// Yeahbut December 2023
|
// Yeahbut December 2023
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use std::fs;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||||
|
use serde_json::Value;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use purple_cello_mc_protocol::{
|
use purple_cello_mc_protocol::{
|
||||||
mc_types::{self, Result, Packet},
|
mc_types::{self, Result, Packet},
|
||||||
|
@ -9,6 +14,14 @@ use purple_cello_mc_protocol::{
|
||||||
login,
|
login,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const EXPIRATION_DURATION: Duration = Duration::from_secs(3600);
|
||||||
|
|
||||||
|
struct CachedWhitelist {
|
||||||
|
whitelist_data: Value,
|
||||||
|
timestamp: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
struct Player {
|
struct Player {
|
||||||
name: String,
|
name: String,
|
||||||
player_uuid: Option<u128>,
|
player_uuid: Option<u128>,
|
||||||
|
@ -19,17 +32,134 @@ enum PlayerAllowed {
|
||||||
False(String),
|
False(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_player(player: Player) -> Result<PlayerAllowed> {
|
fn load_whitelist() -> Value {
|
||||||
static PARITY: AtomicBool = AtomicBool::new(true);
|
let file_path = "./whitelist.json";
|
||||||
let parity: bool;
|
|
||||||
parity = PARITY.load(Ordering::Relaxed);
|
let data = match fs::read_to_string(file_path) {
|
||||||
PARITY.store(!parity, Ordering::Relaxed);
|
Ok(data) => data,
|
||||||
if parity {
|
Err(_) => return Value::Null,
|
||||||
// if player.name.to_lowercase() == "yeahbut" {
|
};
|
||||||
Ok(PlayerAllowed::True(player))
|
|
||||||
} else {
|
let whitelist_data: Value = match serde_json::from_str(&data) {
|
||||||
Ok(PlayerAllowed::False("Testing blocking, try again.".to_string()))
|
Ok(value) => value,
|
||||||
|
Err(_) => return Value::Null,
|
||||||
|
};
|
||||||
|
|
||||||
|
whitelist_data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_whitelist() -> Vec<Player> {
|
||||||
|
lazy_static! {
|
||||||
|
static ref WHITELIST_CACHE: Arc<Mutex<Option<CachedWhitelist>>> =
|
||||||
|
Arc::new(Mutex::new(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut cache = WHITELIST_CACHE.lock().unwrap();
|
||||||
|
|
||||||
|
if let Some(cached_whitelist) = cache.as_ref() {
|
||||||
|
if cached_whitelist.timestamp.elapsed() >= EXPIRATION_DURATION {
|
||||||
|
println!("Refreshing whitelist cache");
|
||||||
|
*cache = Some(CachedWhitelist {
|
||||||
|
whitelist_data: load_whitelist(),
|
||||||
|
timestamp: Instant::now(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*cache = Some(CachedWhitelist {
|
||||||
|
whitelist_data: load_whitelist(),
|
||||||
|
timestamp: Instant::now(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let whitelist_data = cache.as_ref().unwrap().whitelist_data.clone();
|
||||||
|
|
||||||
|
std::mem::drop(cache);
|
||||||
|
|
||||||
|
if whitelist_data == Value::Null {
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
let whitelist_array = match whitelist_data.as_array() {
|
||||||
|
Some(whitelist) => whitelist,
|
||||||
|
None => { return Vec::new(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut whitelist: Vec<Player> = Vec::new();
|
||||||
|
|
||||||
|
for whitelisted_player in whitelist_array {
|
||||||
|
let player_map = match whitelisted_player.as_object() {
|
||||||
|
Some(whitelist) => whitelist,
|
||||||
|
None => { continue; }
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = match player_map.get("name") {
|
||||||
|
Some(name) => {
|
||||||
|
match name.as_str() {
|
||||||
|
Some(name) => name,
|
||||||
|
None => { continue; }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => { continue; }
|
||||||
|
};
|
||||||
|
|
||||||
|
let player_uuid = match player_map.get("uuid") {
|
||||||
|
Some(uuid) => {
|
||||||
|
match uuid.as_str() {
|
||||||
|
Some(uuid) => {
|
||||||
|
match u128::from_str_radix(uuid, 16) {
|
||||||
|
Ok(uuid) => uuid,
|
||||||
|
Err(_) => { continue; }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => { continue; }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => { continue; }
|
||||||
|
};
|
||||||
|
|
||||||
|
whitelist.push(Player {
|
||||||
|
name: name.to_string(),
|
||||||
|
player_uuid: Some(player_uuid),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
whitelist
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_player_whitelist(player: Player) -> PlayerAllowed {
|
||||||
|
let whitelist = get_whitelist();
|
||||||
|
|
||||||
|
if player.player_uuid.is_none() {
|
||||||
|
return PlayerAllowed::False("Invalid UUID".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut invalid_uuid = false;
|
||||||
|
let mut invalid_username = false;
|
||||||
|
|
||||||
|
for wl_player in whitelist {
|
||||||
|
if wl_player == player {
|
||||||
|
return PlayerAllowed::True(player);
|
||||||
|
} else if wl_player.name == player.name {
|
||||||
|
invalid_uuid = true;
|
||||||
|
} else if wl_player.player_uuid == player.player_uuid {
|
||||||
|
invalid_username = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if invalid_uuid {
|
||||||
|
PlayerAllowed::False("Invalid UUID".to_string())
|
||||||
|
} else if invalid_username {
|
||||||
|
PlayerAllowed::False(
|
||||||
|
"Invalid Username, please contact the server admin to update your \
|
||||||
|
username: purplecelloserver@gmail.com".to_string()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PlayerAllowed::False("Not whitelisted on this server".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_player(player: Player) -> Result<PlayerAllowed> {
|
||||||
|
Ok(check_player_whitelist(player))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn respond_login(
|
pub async fn respond_login(
|
||||||
|
|
Loading…
Reference in New Issue