mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Change admins from Vec<String> into Hashset<Uuid>, add commands to server-cli-bin for adding and removing admins
This commit is contained in:
parent
ca2bf937e6
commit
71251ca6a6
@ -1,5 +1,4 @@
|
|||||||
use specs::{Component, NullStorage};
|
use specs::{Component, NullStorage};
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct Admin;
|
pub struct Admin;
|
||||||
@ -7,12 +6,3 @@ pub struct Admin;
|
|||||||
impl Component for Admin {
|
impl Component for Admin {
|
||||||
type Storage = NullStorage<Self>;
|
type Storage = NullStorage<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of admin usernames. This is stored as a specs resource so that the list
|
|
||||||
/// can be read by specs systems.
|
|
||||||
pub struct AdminList(pub Vec<String>);
|
|
||||||
impl Deref for AdminList {
|
|
||||||
type Target = Vec<String>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Vec<String> { &self.0 }
|
|
||||||
}
|
|
||||||
|
@ -24,7 +24,7 @@ pub mod visual;
|
|||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use ability::{CharacterAbility, CharacterAbilityType, ItemConfig, Loadout};
|
pub use ability::{CharacterAbility, CharacterAbilityType, ItemConfig, Loadout};
|
||||||
pub use admin::{Admin, AdminList};
|
pub use admin::Admin;
|
||||||
pub use agent::{Agent, Alignment};
|
pub use agent::{Agent, Alignment};
|
||||||
pub use beam::{Beam, BeamSegment};
|
pub use beam::{Beam, BeamSegment};
|
||||||
pub use body::{
|
pub use body::{
|
||||||
|
28
server-cli/src/admin.rs
Normal file
28
server-cli/src/admin.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
pub fn admin_subcommand(
|
||||||
|
sub_m: &clap::ArgMatches,
|
||||||
|
server_settings: &server::Settings,
|
||||||
|
editable_settings: &mut server::EditableSettings,
|
||||||
|
data_dir: &std::path::Path,
|
||||||
|
) {
|
||||||
|
let login_provider =
|
||||||
|
server::login_provider::LoginProvider::new(server_settings.auth_server_address.clone());
|
||||||
|
|
||||||
|
match sub_m.subcommand() {
|
||||||
|
("add", Some(sub_m)) => {
|
||||||
|
if let Some(username) = sub_m.value_of("username") {
|
||||||
|
server::add_admin(username, &login_provider, editable_settings, data_dir)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
("remove", Some(sub_m)) => {
|
||||||
|
if let Some(username) = sub_m.value_of("username") {
|
||||||
|
server::remove_admin(username, &login_provider, editable_settings, data_dir)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// TODO: can clap enforce this?
|
||||||
|
// or make this list current admins or something
|
||||||
|
_ => tracing::error!(
|
||||||
|
"Invalid input, use one of the subcommands listed using: \nveloren-server-cli help \
|
||||||
|
admin"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
#![deny(clippy::clone_on_ref_ptr)]
|
#![deny(clippy::clone_on_ref_ptr)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
|
|
||||||
|
mod admin;
|
||||||
mod logging;
|
mod logging;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod shutdown_coordinator;
|
mod shutdown_coordinator;
|
||||||
@ -12,11 +13,9 @@ use crate::{
|
|||||||
shutdown_coordinator::ShutdownCoordinator,
|
shutdown_coordinator::ShutdownCoordinator,
|
||||||
tui_runner::{Message, Tui},
|
tui_runner::{Message, Tui},
|
||||||
};
|
};
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg, SubCommand};
|
||||||
use common::clock::Clock;
|
use common::clock::Clock;
|
||||||
use server::{Event, Input, Server};
|
use server::{Event, Input, Server};
|
||||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
|
||||||
use signal_hook::SIGUSR1;
|
|
||||||
use std::{
|
use std::{
|
||||||
io,
|
io,
|
||||||
sync::{atomic::AtomicBool, mpsc, Arc},
|
sync::{atomic::AtomicBool, mpsc, Arc},
|
||||||
@ -35,48 +34,54 @@ fn main() -> io::Result<()> {
|
|||||||
Arg::with_name("basic")
|
Arg::with_name("basic")
|
||||||
.short("b")
|
.short("b")
|
||||||
.long("basic")
|
.long("basic")
|
||||||
.help("Disables the tui")
|
.help("Disables the tui"),
|
||||||
.takes_value(false),
|
|
||||||
Arg::with_name("interactive")
|
Arg::with_name("interactive")
|
||||||
.short("i")
|
.short("i")
|
||||||
.long("interactive")
|
.long("interactive")
|
||||||
.help("Enables command input for basic mode")
|
.help("Enables command input for basic mode"),
|
||||||
.takes_value(false),
|
|
||||||
Arg::with_name("no-auth")
|
Arg::with_name("no-auth")
|
||||||
.long("no-auth")
|
.long("no-auth")
|
||||||
.help("Runs without auth enabled"),
|
.help("Runs without auth enabled"),
|
||||||
])
|
])
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("admin")
|
||||||
|
.about("Add or remove admins")
|
||||||
|
.subcommands(vec![
|
||||||
|
SubCommand::with_name("add").about("Adds an admin").arg(
|
||||||
|
Arg::with_name("username")
|
||||||
|
.help("Name of the admin to add")
|
||||||
|
.required(true),
|
||||||
|
),
|
||||||
|
SubCommand::with_name("remove")
|
||||||
|
.about("Removes an admin")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("username")
|
||||||
|
.help("Name of the admin to remove")
|
||||||
|
.required(true),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let basic = matches.is_present("basic");
|
let basic = matches.is_present("basic")
|
||||||
|
// Default to basic with these subcommands
|
||||||
|
|| matches
|
||||||
|
.subcommand_name()
|
||||||
|
.filter(|name| ["admin"].contains(name))
|
||||||
|
.is_some();
|
||||||
let interactive = matches.is_present("interactive");
|
let interactive = matches.is_present("interactive");
|
||||||
let no_auth = matches.is_present("no-auth");
|
let no_auth = matches.is_present("no-auth");
|
||||||
|
|
||||||
let sigusr1_signal = Arc::new(AtomicBool::new(false));
|
let sigusr1_signal = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||||
let _ = signal_hook::flag::register(SIGUSR1, Arc::clone(&sigusr1_signal));
|
let _ = signal_hook::flag::register(signal_hook::SIGUSR1, Arc::clone(&sigusr1_signal));
|
||||||
|
|
||||||
logging::init(basic);
|
logging::init(basic);
|
||||||
|
|
||||||
// Load settings
|
// Load settings
|
||||||
let settings = settings::Settings::load();
|
let settings = settings::Settings::load();
|
||||||
|
|
||||||
// Panic hook to ensure that console mode is set back correctly if in non-basic
|
|
||||||
// mode
|
|
||||||
let hook = std::panic::take_hook();
|
|
||||||
std::panic::set_hook(Box::new(move |info| {
|
|
||||||
Tui::shutdown(basic);
|
|
||||||
hook(info);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let tui = (!basic || interactive).then(|| Tui::run(basic));
|
|
||||||
|
|
||||||
info!("Starting server...");
|
|
||||||
|
|
||||||
// Set up an fps clock
|
|
||||||
let mut clock = Clock::start();
|
|
||||||
|
|
||||||
// Determine folder to save server data in
|
// Determine folder to save server data in
|
||||||
let server_data_dir = {
|
let server_data_dir = {
|
||||||
let mut path = common::userdata_dir_workspace!();
|
let mut path = common::userdata_dir_workspace!();
|
||||||
@ -86,7 +91,33 @@ fn main() -> io::Result<()> {
|
|||||||
|
|
||||||
// Load server settings
|
// Load server settings
|
||||||
let mut server_settings = server::Settings::load(&server_data_dir);
|
let mut server_settings = server::Settings::load(&server_data_dir);
|
||||||
let editable_settings = server::EditableSettings::load(&server_data_dir);
|
let mut editable_settings = server::EditableSettings::load(&server_data_dir);
|
||||||
|
match matches.subcommand() {
|
||||||
|
("admin", Some(sub_m)) => {
|
||||||
|
admin::admin_subcommand(
|
||||||
|
sub_m,
|
||||||
|
&server_settings,
|
||||||
|
&mut editable_settings,
|
||||||
|
&server_data_dir,
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panic hook to ensure that console mode is set back correctly if in non-basic
|
||||||
|
// mode
|
||||||
|
if !basic {
|
||||||
|
let hook = std::panic::take_hook();
|
||||||
|
std::panic::set_hook(Box::new(move |info| {
|
||||||
|
Tui::shutdown(basic);
|
||||||
|
hook(info);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let tui = (!basic || interactive).then(|| Tui::run(basic));
|
||||||
|
|
||||||
|
info!("Starting server...");
|
||||||
|
|
||||||
if no_auth {
|
if no_auth {
|
||||||
server_settings.auth_server_address = None;
|
server_settings.auth_server_address = None;
|
||||||
@ -106,6 +137,12 @@ fn main() -> io::Result<()> {
|
|||||||
|
|
||||||
let mut shutdown_coordinator = ShutdownCoordinator::new(Arc::clone(&sigusr1_signal));
|
let mut shutdown_coordinator = ShutdownCoordinator::new(Arc::clone(&sigusr1_signal));
|
||||||
|
|
||||||
|
// Set up an fps clock
|
||||||
|
let mut clock = Clock::start();
|
||||||
|
// Wait for a tick so we don't start with a zero dt
|
||||||
|
// TODO: consider integrating this into Clock::start?
|
||||||
|
clock.tick(Duration::from_millis(1000 / TPS));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Terminate the server if instructed to do so by the shutdown coordinator
|
// Terminate the server if instructed to do so by the shutdown coordinator
|
||||||
if shutdown_coordinator.check(&mut server, &settings) {
|
if shutdown_coordinator.check(&mut server, &settings) {
|
||||||
@ -144,6 +181,12 @@ fn main() -> io::Result<()> {
|
|||||||
info!("Closing the server");
|
info!("Closing the server");
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
|
Message::AddAdmin(username) => {
|
||||||
|
server.add_admin(&username);
|
||||||
|
},
|
||||||
|
Message::RemoveAdmin(username) => {
|
||||||
|
server.remove_admin(&username);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Err(mpsc::TryRecvError::Empty) | Err(mpsc::TryRecvError::Disconnected) => {},
|
Err(mpsc::TryRecvError::Empty) | Err(mpsc::TryRecvError::Disconnected) => {},
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ pub enum Message {
|
|||||||
AbortShutdown,
|
AbortShutdown,
|
||||||
Shutdown { grace_period: Duration },
|
Shutdown { grace_period: Duration },
|
||||||
Quit,
|
Quit,
|
||||||
|
AddAdmin(String),
|
||||||
|
RemoveAdmin(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Command<'a> {
|
pub struct Command<'a> {
|
||||||
@ -37,7 +39,8 @@ pub struct Command<'a> {
|
|||||||
pub cmd: fn(Vec<String>, &mut mpsc::Sender<Message>),
|
pub cmd: fn(Vec<String>, &mut mpsc::Sender<Message>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const COMMANDS: [Command; 4] = [
|
// TODO: mabye we could be using clap here?
|
||||||
|
pub const COMMANDS: [Command; 5] = [
|
||||||
Command {
|
Command {
|
||||||
name: "quit",
|
name: "quit",
|
||||||
description: "Closes the server",
|
description: "Closes the server",
|
||||||
@ -70,6 +73,22 @@ pub const COMMANDS: [Command; 4] = [
|
|||||||
args: 0,
|
args: 0,
|
||||||
cmd: |_, sender| sender.send(Message::AbortShutdown).unwrap(),
|
cmd: |_, sender| sender.send(Message::AbortShutdown).unwrap(),
|
||||||
},
|
},
|
||||||
|
Command {
|
||||||
|
name: "admin",
|
||||||
|
description: "Add or remove an admin via \'admin add/remove <username>\'",
|
||||||
|
split_spaces: true,
|
||||||
|
args: 2,
|
||||||
|
cmd: |args, sender| match args.get(..2) {
|
||||||
|
Some([op, username]) if op == "add" => {
|
||||||
|
sender.send(Message::AddAdmin(username.clone())).unwrap()
|
||||||
|
},
|
||||||
|
Some([op, username]) if op == "remove" => {
|
||||||
|
sender.send(Message::RemoveAdmin(username.clone())).unwrap()
|
||||||
|
},
|
||||||
|
Some(_) => error!("First arg must be add or remove"),
|
||||||
|
_ => error!("Not enough args, should be unreachable"),
|
||||||
|
},
|
||||||
|
},
|
||||||
Command {
|
Command {
|
||||||
name: "help",
|
name: "help",
|
||||||
description: "List all command available",
|
description: "List all command available",
|
||||||
|
@ -156,9 +156,6 @@ impl Server {
|
|||||||
state
|
state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.insert(CharacterLoader::new(&persistence_db_dir)?);
|
.insert(CharacterLoader::new(&persistence_db_dir)?);
|
||||||
state
|
|
||||||
.ecs_mut()
|
|
||||||
.insert(comp::AdminList(settings.admins.clone()));
|
|
||||||
state.ecs_mut().insert(Vec::<Outcome>::new());
|
state.ecs_mut().insert(Vec::<Outcome>::new());
|
||||||
|
|
||||||
// System timers for performance monitoring
|
// System timers for performance monitoring
|
||||||
@ -935,6 +932,20 @@ impl Server {
|
|||||||
pub fn number_of_players(&self) -> i64 {
|
pub fn number_of_players(&self) -> i64 {
|
||||||
self.state.ecs().read_storage::<Client>().join().count() as i64
|
self.state.ecs().read_storage::<Client>().join().count() as i64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_admin(&self, username: &str) {
|
||||||
|
let mut editable_settings = self.editable_settings_mut();
|
||||||
|
let login_provider = self.state.ecs().fetch::<LoginProvider>();
|
||||||
|
let data_dir = self.data_dir();
|
||||||
|
add_admin(username, &login_provider, &mut editable_settings, &data_dir.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_admin(&self, username: &str) {
|
||||||
|
let mut editable_settings = self.editable_settings_mut();
|
||||||
|
let login_provider = self.state.ecs().fetch::<LoginProvider>();
|
||||||
|
let data_dir = self.data_dir();
|
||||||
|
remove_admin(username, &login_provider, &mut editable_settings, &data_dir.path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Server {
|
impl Drop for Server {
|
||||||
@ -943,3 +954,52 @@ impl Drop for Server {
|
|||||||
.notify_registered_clients(ServerMsg::Disconnect(DisconnectReason::Shutdown));
|
.notify_registered_clients(ServerMsg::Disconnect(DisconnectReason::Shutdown));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_admin(
|
||||||
|
username: &str,
|
||||||
|
login_provider: &LoginProvider,
|
||||||
|
editable_settings: &mut EditableSettings,
|
||||||
|
data_dir: &std::path::Path,
|
||||||
|
) {
|
||||||
|
use crate::settings::EditableSetting;
|
||||||
|
match login_provider.username_to_uuid(username) {
|
||||||
|
Ok(uuid) => editable_settings.admins.edit(data_dir, |admins| {
|
||||||
|
if admins.insert(uuid.clone()) {
|
||||||
|
info!("Successfully added {} ({}) as an admin!", username, uuid);
|
||||||
|
} else {
|
||||||
|
info!("{} ({}) is already an admin!", username, uuid);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Err(err) => error!(
|
||||||
|
?err,
|
||||||
|
"Could not find uuid for this name either the user does not exist or \
|
||||||
|
there was an error communicating with the auth server."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_admin(
|
||||||
|
username: &str,
|
||||||
|
login_provider: &LoginProvider,
|
||||||
|
editable_settings: &mut EditableSettings,
|
||||||
|
data_dir: &std::path::Path,
|
||||||
|
) {
|
||||||
|
use crate::settings::EditableSetting;
|
||||||
|
match login_provider.username_to_uuid(username) {
|
||||||
|
Ok(uuid) => editable_settings.admins.edit(data_dir, |admins| {
|
||||||
|
if admins.remove(&uuid) {
|
||||||
|
info!(
|
||||||
|
"Successfully removed {} ({}) from the admins",
|
||||||
|
username, uuid
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info!("{} ({}) is not an admin!", username, uuid);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Err(err) => error!(
|
||||||
|
?err,
|
||||||
|
"Could not find uuid for this name either the user does not exist or \
|
||||||
|
there was an error communicating with the auth server."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -53,7 +53,7 @@ impl LoginProvider {
|
|||||||
pub fn try_login(
|
pub fn try_login(
|
||||||
&mut self,
|
&mut self,
|
||||||
username_or_token: &str,
|
username_or_token: &str,
|
||||||
admins: &[String],
|
admins: &HashSet<Uuid>,
|
||||||
whitelist: &HashSet<Uuid>,
|
whitelist: &HashSet<Uuid>,
|
||||||
banlist: &HashMap<Uuid, BanRecord>,
|
banlist: &HashMap<Uuid, BanRecord>,
|
||||||
) -> Result<(String, Uuid), RegisterError> {
|
) -> Result<(String, Uuid), RegisterError> {
|
||||||
@ -70,7 +70,7 @@ impl LoginProvider {
|
|||||||
|
|
||||||
// user can only join if he is admin, the whitelist is empty (everyone can join)
|
// user can only join if he is admin, the whitelist is empty (everyone can join)
|
||||||
// or his name is in the whitelist
|
// or his name is in the whitelist
|
||||||
if !whitelist.is_empty() && !whitelist.contains(&uuid) && !admins.contains(&username) {
|
if !whitelist.is_empty() && !whitelist.contains(&uuid) && !admins.contains(&uuid) {
|
||||||
return Err(RegisterError::NotOnWhitelist);
|
return Err(RegisterError::NotOnWhitelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ const SETTINGS_FILENAME: &str = "settings.ron";
|
|||||||
const WHITELIST_FILENAME: &str = "whitelist.ron";
|
const WHITELIST_FILENAME: &str = "whitelist.ron";
|
||||||
const BANLIST_FILENAME: &str = "banlist.ron";
|
const BANLIST_FILENAME: &str = "banlist.ron";
|
||||||
const SERVER_DESCRIPTION_FILENAME: &str = "description.ron";
|
const SERVER_DESCRIPTION_FILENAME: &str = "description.ron";
|
||||||
|
const ADMINS_FILENAME: &str = "admins.ron";
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@ -34,7 +35,6 @@ pub struct Settings {
|
|||||||
//pub pvp_enabled: bool,
|
//pub pvp_enabled: bool,
|
||||||
pub server_name: String,
|
pub server_name: String,
|
||||||
pub start_time: f64,
|
pub start_time: f64,
|
||||||
pub admins: Vec<String>,
|
|
||||||
/// When set to None, loads the default map file (if available); otherwise,
|
/// When set to None, loads the default map file (if available); otherwise,
|
||||||
/// uses the value of the file options to decide how to proceed.
|
/// uses the value of the file options to decide how to proceed.
|
||||||
pub map_file: Option<FileOpts>,
|
pub map_file: Option<FileOpts>,
|
||||||
@ -57,7 +57,6 @@ impl Default for Settings {
|
|||||||
max_players: 100,
|
max_players: 100,
|
||||||
start_time: 9.0 * 3600.0,
|
start_time: 9.0 * 3600.0,
|
||||||
map_file: None,
|
map_file: None,
|
||||||
admins: Vec::new(),
|
|
||||||
persistence_db_dir: "saves".into(),
|
persistence_db_dir: "saves".into(),
|
||||||
max_view_distance: Some(30),
|
max_view_distance: Some(30),
|
||||||
banned_words_files: Vec::new(),
|
banned_words_files: Vec::new(),
|
||||||
@ -137,8 +136,6 @@ impl Settings {
|
|||||||
server_name: "Singleplayer".to_owned(),
|
server_name: "Singleplayer".to_owned(),
|
||||||
max_players: 100,
|
max_players: 100,
|
||||||
start_time: 9.0 * 3600.0,
|
start_time: 9.0 * 3600.0,
|
||||||
admins: vec!["singleplayer".to_string()], /* TODO: Let the player choose if they want
|
|
||||||
* to use admin commands or not */
|
|
||||||
max_view_distance: None,
|
max_view_distance: None,
|
||||||
client_timeout: Duration::from_secs(180),
|
client_timeout: Duration::from_secs(180),
|
||||||
..load // Fill in remaining fields from server_settings.ron.
|
..load // Fill in remaining fields from server_settings.ron.
|
||||||
@ -179,18 +176,28 @@ pub struct BanRecord {
|
|||||||
#[derive(Deserialize, Serialize, Default)]
|
#[derive(Deserialize, Serialize, Default)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Whitelist(HashSet<Uuid>);
|
pub struct Whitelist(HashSet<Uuid>);
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default)]
|
#[derive(Deserialize, Serialize, Default)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct Banlist(HashMap<Uuid, BanRecord>);
|
pub struct Banlist(HashMap<Uuid, BanRecord>);
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct ServerDescription(String);
|
pub struct ServerDescription(String);
|
||||||
|
impl Default for ServerDescription {
|
||||||
|
fn default() -> Self { Self("This is the best Veloren server".into()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Default)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct Admins(HashSet<Uuid>);
|
||||||
|
|
||||||
/// Combines all the editable settings into one struct that is stored in the ecs
|
/// Combines all the editable settings into one struct that is stored in the ecs
|
||||||
pub struct EditableSettings {
|
pub struct EditableSettings {
|
||||||
pub whitelist: Whitelist,
|
pub whitelist: Whitelist,
|
||||||
pub banlist: Banlist,
|
pub banlist: Banlist,
|
||||||
pub server_description: ServerDescription,
|
pub server_description: ServerDescription,
|
||||||
|
pub admins: Admins,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EditableSettings {
|
impl EditableSettings {
|
||||||
@ -199,6 +206,7 @@ impl EditableSettings {
|
|||||||
whitelist: Whitelist::load(data_dir),
|
whitelist: Whitelist::load(data_dir),
|
||||||
banlist: Banlist::load(data_dir),
|
banlist: Banlist::load(data_dir),
|
||||||
server_description: ServerDescription::load(data_dir),
|
server_description: ServerDescription::load(data_dir),
|
||||||
|
admins: Admins::load(data_dir),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,15 +214,21 @@ impl EditableSettings {
|
|||||||
let load = Self::load(data_dir);
|
let load = Self::load(data_dir);
|
||||||
Self {
|
Self {
|
||||||
server_description: ServerDescription("Who needs friends anyway?".into()),
|
server_description: ServerDescription("Who needs friends anyway?".into()),
|
||||||
|
// TODO: Let the player choose if they want to use admin commands or not
|
||||||
|
admins: Admins(
|
||||||
|
std::iter::once(
|
||||||
|
// TODO: hacky
|
||||||
|
crate::login_provider::LoginProvider::new(None)
|
||||||
|
.username_to_uuid("singleplayer")
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
..load
|
..load
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerDescription {
|
|
||||||
fn default() -> Self { Self("This is the best Veloren server".into()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EditableSetting for Whitelist {
|
impl EditableSetting for Whitelist {
|
||||||
const FILENAME: &'static str = WHITELIST_FILENAME;
|
const FILENAME: &'static str = WHITELIST_FILENAME;
|
||||||
}
|
}
|
||||||
@ -227,6 +241,10 @@ impl EditableSetting for ServerDescription {
|
|||||||
const FILENAME: &'static str = SERVER_DESCRIPTION_FILENAME;
|
const FILENAME: &'static str = SERVER_DESCRIPTION_FILENAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EditableSetting for Admins {
|
||||||
|
const FILENAME: &'static str = ADMINS_FILENAME;
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for Whitelist {
|
impl Deref for Whitelist {
|
||||||
type Target = HashSet<Uuid>;
|
type Target = HashSet<Uuid>;
|
||||||
|
|
||||||
@ -256,3 +274,13 @@ impl Deref for ServerDescription {
|
|||||||
impl DerefMut for ServerDescription {
|
impl DerefMut for ServerDescription {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for Admins {
|
||||||
|
type Target = HashSet<Uuid>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Admins {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
Admin, AdminList, CanBuild, ChatMode, ChatType, ControlEvent, Controller, ForceUpdate, Ori,
|
Admin, CanBuild, ChatMode, ChatType, ControlEvent, Controller, ForceUpdate, Ori,
|
||||||
Player, Pos, Stats, UnresolvedChatMsg, Vel,
|
Player, Pos, Stats, UnresolvedChatMsg, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
@ -57,7 +57,6 @@ impl Sys {
|
|||||||
chat_modes: &ReadStorage<'_, ChatMode>,
|
chat_modes: &ReadStorage<'_, ChatMode>,
|
||||||
login_provider: &mut WriteExpect<'_, LoginProvider>,
|
login_provider: &mut WriteExpect<'_, LoginProvider>,
|
||||||
block_changes: &mut Write<'_, BlockChange>,
|
block_changes: &mut Write<'_, BlockChange>,
|
||||||
admin_list: &ReadExpect<'_, AdminList>,
|
|
||||||
admins: &mut WriteStorage<'_, Admin>,
|
admins: &mut WriteStorage<'_, Admin>,
|
||||||
positions: &mut WriteStorage<'_, Pos>,
|
positions: &mut WriteStorage<'_, Pos>,
|
||||||
velocities: &mut WriteStorage<'_, Vel>,
|
velocities: &mut WriteStorage<'_, Vel>,
|
||||||
@ -99,7 +98,7 @@ impl Sys {
|
|||||||
} => {
|
} => {
|
||||||
let (username, uuid) = match login_provider.try_login(
|
let (username, uuid) = match login_provider.try_login(
|
||||||
&token_or_username,
|
&token_or_username,
|
||||||
&settings.admins,
|
&*editable_settings.admins,
|
||||||
&*editable_settings.whitelist,
|
&*editable_settings.whitelist,
|
||||||
&*editable_settings.banlist,
|
&*editable_settings.banlist,
|
||||||
) {
|
) {
|
||||||
@ -112,8 +111,8 @@ impl Sys {
|
|||||||
|
|
||||||
let vd =
|
let vd =
|
||||||
view_distance.map(|vd| vd.min(settings.max_view_distance.unwrap_or(vd)));
|
view_distance.map(|vd| vd.min(settings.max_view_distance.unwrap_or(vd)));
|
||||||
|
let is_admin = editable_settings.admins.contains(&uuid);
|
||||||
let player = Player::new(username.clone(), None, vd, uuid);
|
let player = Player::new(username.clone(), None, vd, uuid);
|
||||||
let is_admin = admin_list.contains(&username);
|
|
||||||
|
|
||||||
if !player.is_valid() {
|
if !player.is_valid() {
|
||||||
// Invalid player
|
// Invalid player
|
||||||
@ -441,7 +440,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, ChatMode>,
|
ReadStorage<'a, ChatMode>,
|
||||||
WriteExpect<'a, LoginProvider>,
|
WriteExpect<'a, LoginProvider>,
|
||||||
Write<'a, BlockChange>,
|
Write<'a, BlockChange>,
|
||||||
ReadExpect<'a, AdminList>,
|
|
||||||
WriteStorage<'a, Admin>,
|
WriteStorage<'a, Admin>,
|
||||||
WriteStorage<'a, Pos>,
|
WriteStorage<'a, Pos>,
|
||||||
WriteStorage<'a, Vel>,
|
WriteStorage<'a, Vel>,
|
||||||
@ -475,7 +473,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
chat_modes,
|
chat_modes,
|
||||||
mut accounts,
|
mut accounts,
|
||||||
mut block_changes,
|
mut block_changes,
|
||||||
admin_list,
|
|
||||||
mut admins,
|
mut admins,
|
||||||
mut positions,
|
mut positions,
|
||||||
mut velocities,
|
mut velocities,
|
||||||
@ -537,7 +534,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
&chat_modes,
|
&chat_modes,
|
||||||
&mut accounts,
|
&mut accounts,
|
||||||
&mut block_changes,
|
&mut block_changes,
|
||||||
&admin_list,
|
|
||||||
&mut admins,
|
&mut admins,
|
||||||
&mut positions,
|
&mut positions,
|
||||||
&mut velocities,
|
&mut velocities,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user