diff --git a/Cargo.lock b/Cargo.lock index af43c76f4..2db6e0d3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3595,6 +3595,7 @@ dependencies = [ "colored", "criterion", "crypto-bigint 0.7.5", + "dashmap", "ecdsa 0.17.0", "md5", "num-derive", @@ -3610,7 +3611,6 @@ dependencies = [ "sha2 0.11.0", "syn 3.0.3", "thiserror 2.0.20", - "tokio", "ureq", "uuid", ] diff --git a/crates/pumpkin-util/Cargo.toml b/crates/pumpkin-util/Cargo.toml index a44a794ee..ed055ca3f 100644 --- a/crates/pumpkin-util/Cargo.toml +++ b/crates/pumpkin-util/Cargo.toml @@ -22,7 +22,7 @@ syn = { workspace = true, optional = true } proc-macro2 = { workspace = true, optional = true } uuid.workspace = true -tokio = { workspace = true, features = ["sync"] } +dashmap.workspace = true base64.workspace = true p384 = { workspace = true, features = ["ecdsa"] } thiserror.workspace = true diff --git a/crates/pumpkin-util/src/permission.rs b/crates/pumpkin-util/src/permission.rs index a4fea2afd..2ba1e074c 100644 --- a/crates/pumpkin-util/src/permission.rs +++ b/crates/pumpkin-util/src/permission.rs @@ -1,7 +1,6 @@ +use dashmap::DashMap; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::HashMap; -use std::sync::Arc; -use tokio::sync::RwLock; /// Describes the default behaviour for permissions. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -65,7 +64,7 @@ impl Permission { #[derive(Default)] pub struct PermissionRegistry { /// All registered permissions. - permissions: HashMap, + permissions: DashMap, } impl PermissionRegistry { @@ -76,7 +75,7 @@ impl PermissionRegistry { #[must_use] pub fn new() -> Self { Self { - permissions: HashMap::new(), + permissions: DashMap::new(), } } @@ -88,7 +87,7 @@ impl PermissionRegistry { /// # Returns /// - `Ok(())` if the permission was successfully registered. /// - `Err(String)` if a permission with the same node already exists. - pub fn register_permission(&mut self, permission: Permission) -> Result<(), String> { + pub fn register_permission(&self, permission: Permission) -> Result<(), String> { if self.permissions.contains_key(&permission.node) { return Err(format!( "Permission {} is already registered", @@ -108,7 +107,7 @@ impl PermissionRegistry { /// # Parameters /// - `permission`: The `Permission` instance to add. #[allow(clippy::expect_used)] - pub fn register_permission_or_panic(&mut self, permission: Permission) { + pub fn register_permission_or_panic(&self, permission: Permission) { self.register_permission(permission) .expect("Permission should have been registered successfully"); } @@ -119,9 +118,12 @@ impl PermissionRegistry { /// - `node`: The full permission node string to look up. /// /// # Returns - /// `Some(&Permission)` if the node exists, or `None` otherwise. + /// `Some(Ref<'_, String, Permission>)` if the node exists, or `None` otherwise. #[must_use] - pub fn get_permission(&self, node: &str) -> Option<&Permission> { + pub fn get_permission( + &self, + node: &str, + ) -> Option> { self.permissions.get(node) } @@ -137,8 +139,9 @@ impl PermissionRegistry { /// # Returns /// - `true` if the node existed and its default was updated. /// - `false` if no permission with that node is registered. - pub fn set_default(&mut self, node: &str, default: PermissionDefault) -> bool { - if let Some(permission) = self.permissions.get_mut(node) { + #[must_use] + pub fn set_default(&self, node: &str, default: PermissionDefault) -> bool { + if let Some(mut permission) = self.permissions.get_mut(node) { permission.default = default; true } else { @@ -163,7 +166,7 @@ impl PermissionRegistry { #[derive(Default, Clone, Debug, Serialize, Deserialize)] pub struct PermissionAttachment { /// Directly assigned permissions. - permissions: HashMap, + pub permissions: HashMap, } impl PermissionAttachment { @@ -217,53 +220,103 @@ impl PermissionAttachment { } } -/// Manager for player permissions. +/// Manager for player and server permissions. #[derive(Default)] pub struct PermissionManager { /// Global registry of permissions. - pub registry: Arc>, - /// Player permission attachments. - pub attachments: HashMap>>, + pub registry: PermissionRegistry, + /// Player permission attachments keyed by player UUID. + pub attachments: DashMap>, } impl PermissionManager { - /// Creates a new `PermissionManager`. - /// - /// # Parameters - /// - `registry`: An `Arc>` containing the global permissions registry. - /// - /// # Returns - /// A `PermissionManager` with an empty attachments map. - pub fn new(registry: Arc>) -> Self { + /// Creates a new empty `PermissionManager`. + #[must_use] + pub fn new() -> Self { Self { - registry, - attachments: HashMap::new(), + registry: PermissionRegistry::new(), + attachments: DashMap::new(), } } - /// Retrieves the `PermissionAttachment` for a given player, creating one if it doesn't exist. - /// - /// # Parameters - /// - `player_id`: The UUID of the player. - /// - /// # Returns - /// An `Arc>` representing the player's attachment. - pub fn get_attachment(&mut self, player_id: uuid::Uuid) -> Arc> { - Arc::clone( - self.attachments - .entry(player_id) - .or_insert_with(|| Arc::new(RwLock::new(PermissionAttachment::new()))), - ) + /// Creates a new `PermissionManager` with an existing `PermissionRegistry`. + #[must_use] + pub fn with_registry(registry: PermissionRegistry) -> Self { + Self { + registry, + attachments: DashMap::new(), + } } - /// Removes the `PermissionAttachment` for a given player. - /// - /// # Parameters - /// - `player_id`: The UUID of the player. - pub fn remove_attachment(&mut self, player_id: &uuid::Uuid) { + /// Registers a new permission node in the global registry. + pub fn register_permission(&self, permission: Permission) -> Result<(), String> { + self.registry.register_permission(permission) + } + + /// Registers a new permission node in the global registry or panics if already registered. + pub fn register_permission_or_panic(&self, permission: Permission) { + self.registry.register_permission_or_panic(permission); + } + + /// Retrieves a permission node by its name from the registry. + #[must_use] + pub fn get_permission( + &self, + node: &str, + ) -> Option> { + self.registry.get_permission(node) + } + + /// Overrides the default behaviour of an already-registered permission in the registry. + #[must_use] + pub fn set_default(&self, node: &str, default: PermissionDefault) -> bool { + self.registry.set_default(node, default) + } + + /// Checks whether a permission node exists in the registry. + #[must_use] + pub fn has_registered_permission(&self, node: &str) -> bool { + self.registry.has_permission(node) + } + + /// Sets a player's explicit permission. + pub fn set_permission(&self, player_id: uuid::Uuid, node: impl Into, value: bool) { + self.attachments + .entry(player_id) + .or_default() + .insert(node.into(), value); + } + + /// Unsets a player's explicit permission. + pub fn unset_permission(&self, player_id: &uuid::Uuid, node: &str) { + if let Some(player_perms) = self.attachments.get(player_id) { + player_perms.remove(node); + } + } + + /// Checks if a permission is explicitly set for a player. + #[must_use] + pub fn has_permission_set(&self, player_id: &uuid::Uuid, node: &str) -> Option { + self.attachments + .get(player_id) + .and_then(|p| p.get(node).as_deref().copied()) + } + + /// Removes all permission attachments for a player. + pub fn remove_attachment(&self, player_id: &uuid::Uuid) { self.attachments.remove(player_id); } + /// Retrieves all explicitly assigned permissions for a player. + #[must_use] + pub fn get_player_permissions(&self, player_id: &uuid::Uuid) -> Option> { + self.attachments.get(player_id).map(|p| { + p.iter() + .map(|item| (item.key().clone(), *item.value())) + .collect() + }) + } + /// Checks if a player has a specific permission. /// /// # Parameters @@ -273,21 +326,18 @@ impl PermissionManager { /// /// # Returns /// `true` if the player has the permission, `false` otherwise. - pub async fn has_permission( + #[must_use] + pub fn has_permission( &self, player_id: &uuid::Uuid, permission_node: &str, player_op_level: PermissionLvl, ) -> bool { - let reg = self.registry.read().await; - // Check explicitly set permissions if let Some(attachment) = self.attachments.get(player_id) { - let attachment = attachment.read().await; - // Check for the exact permission match - if let Some(value) = attachment.has_permission_set(permission_node) { - return value; + if let Some(value) = attachment.get(permission_node) { + return *value; } // Check parent nodes (for wildcard permissions) @@ -298,23 +348,21 @@ impl PermissionManager { // Check wildcard permissions at each level let mut current_node = namespace.to_string(); - if let Some(value) = attachment.has_permission_set(&format!("{current_node}:*")) { - return value; + if let Some(value) = attachment.get(&format!("{current_node}:*")) { + return *value; } current_node.push(':'); for (i, part) in key_parts.iter().enumerate() { current_node.push_str(part); - if let Some(value) = attachment.has_permission_set(¤t_node) { - return value; + if let Some(value) = attachment.get(¤t_node) { + return *value; } if i < key_parts.len() - 1 { - if let Some(value) = - attachment.has_permission_set(&format!("{current_node}.*")) - { - return value; + if let Some(value) = attachment.get(&format!("{current_node}.*")) { + return *value; } current_node.push('.'); } @@ -322,17 +370,20 @@ impl PermissionManager { } // Check for inherited permissions from parent nodes - for (node, value) in attachment.get_permissions() { - if let Some(permission) = reg.get_permission(node) + for item in attachment.iter() { + let node = item.key(); + let value = *item.value(); + if let Some(permission) = self.registry.get_permission(node) && let Some(child_val) = permission.children.get(permission_node) { - return *value && *child_val; + return value && *child_val; } } } // Fall back to the default permission value - reg.get_permission(permission_node) + self.registry + .get_permission(permission_node) .is_some_and(|permission| match permission.default { PermissionDefault::Allow => true, PermissionDefault::Deny => false, diff --git a/crates/pumpkin/src/command/commands/advancement.rs b/crates/pumpkin/src/command/commands/advancement.rs index 55ce91eb5..52cb1f813 100644 --- a/crates/pumpkin/src/command/commands/advancement.rs +++ b/crates/pumpkin/src/command/commands/advancement.rs @@ -562,7 +562,7 @@ impl CommandExecutor for EveryAdvancementExecutor { } /// register the advancement command -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/attribute.rs b/crates/pumpkin/src/command/commands/attribute.rs index 908ab7eff..3a481ac41 100644 --- a/crates/pumpkin/src/command/commands/attribute.rs +++ b/crates/pumpkin/src/command/commands/attribute.rs @@ -450,7 +450,7 @@ impl CommandExecutor for ModifierGetExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/banlist.rs b/crates/pumpkin/src/command/commands/banlist.rs index f724a7053..124b30c6e 100644 --- a/crates/pumpkin/src/command/commands/banlist.rs +++ b/crates/pumpkin/src/command/commands/banlist.rs @@ -106,7 +106,7 @@ impl CommandExecutor for BanListCommandExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/clone.rs b/crates/pumpkin/src/command/commands/clone.rs index 9e3581e81..e8ab80b46 100644 --- a/crates/pumpkin/src/command/commands/clone.rs +++ b/crates/pumpkin/src/command/commands/clone.rs @@ -264,7 +264,7 @@ impl CommandExecutor for CloneExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/dialog.rs b/crates/pumpkin/src/command/commands/dialog.rs index ea85643c5..712f4f299 100644 --- a/crates/pumpkin/src/command/commands/dialog.rs +++ b/crates/pumpkin/src/command/commands/dialog.rs @@ -86,7 +86,7 @@ impl CommandExecutor for DialogShowExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/difficulty.rs b/crates/pumpkin/src/command/commands/difficulty.rs index f9b8ee3e6..5c8d3eda9 100644 --- a/crates/pumpkin/src/command/commands/difficulty.rs +++ b/crates/pumpkin/src/command/commands/difficulty.rs @@ -82,7 +82,7 @@ impl CommandExecutor for DifficultySetExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/execute.rs b/crates/pumpkin/src/command/commands/execute.rs index 15dbf4e1e..93b31e21d 100644 --- a/crates/pumpkin/src/command/commands/execute.rs +++ b/crates/pumpkin/src/command/commands/execute.rs @@ -393,7 +393,7 @@ fn execute_summon_modifier<'a>( } #[allow(clippy::too_many_lines)] -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/fetchprofile.rs b/crates/pumpkin/src/command/commands/fetchprofile.rs index fcbd70713..adad40626 100644 --- a/crates/pumpkin/src/command/commands/fetchprofile.rs +++ b/crates/pumpkin/src/command/commands/fetchprofile.rs @@ -364,7 +364,7 @@ impl CommandExecutor for PrintForEntityExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/fillbiome.rs b/crates/pumpkin/src/command/commands/fillbiome.rs index 64f2e9a44..85e8a40db 100644 --- a/crates/pumpkin/src/command/commands/fillbiome.rs +++ b/crates/pumpkin/src/command/commands/fillbiome.rs @@ -158,7 +158,7 @@ impl CommandExecutor for FillBiomeExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/forceload.rs b/crates/pumpkin/src/command/commands/forceload.rs index fb8cf37a9..f5b03673d 100644 --- a/crates/pumpkin/src/command/commands/forceload.rs +++ b/crates/pumpkin/src/command/commands/forceload.rs @@ -347,7 +347,7 @@ impl CommandExecutor for ForceloadQueryExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/help.rs b/crates/pumpkin/src/command/commands/help.rs index deb543d1b..a670bf90c 100644 --- a/crates/pumpkin/src/command/commands/help.rs +++ b/crates/pumpkin/src/command/commands/help.rs @@ -373,7 +373,7 @@ impl CommandExecutor for HelpCommandExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/kill.rs b/crates/pumpkin/src/command/commands/kill.rs index 5d367d1e5..adaa532f6 100644 --- a/crates/pumpkin/src/command/commands/kill.rs +++ b/crates/pumpkin/src/command/commands/kill.rs @@ -72,7 +72,7 @@ impl CommandExecutor for SelfExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/list.rs b/crates/pumpkin/src/command/commands/list.rs index 580ae3ae5..e0927b676 100644 --- a/crates/pumpkin/src/command/commands/list.rs +++ b/crates/pumpkin/src/command/commands/list.rs @@ -99,7 +99,7 @@ fn get_player_names_and_ids(players: &[Arc]) -> TextComponent { TextComponent::join_with_comma(names_and_ids) } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/loot.rs b/crates/pumpkin/src/command/commands/loot.rs index 5649cfcdf..f2a9ee92a 100644 --- a/crates/pumpkin/src/command/commands/loot.rs +++ b/crates/pumpkin/src/command/commands/loot.rs @@ -220,7 +220,7 @@ impl CommandExecutor for LootExecutor { } #[expect(clippy::too_many_lines)] -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/mod.rs b/crates/pumpkin/src/command/commands/mod.rs index edfeaaaf4..22594aa4d 100644 --- a/crates/pumpkin/src/command/commands/mod.rs +++ b/crates/pumpkin/src/command/commands/mod.rs @@ -3,9 +3,8 @@ use crate::command::tree::Command; use pumpkin_config::{BasicConfiguration, CommandsConfig}; use pumpkin_util::{ PermissionLvl, - permission::{Permission, PermissionDefault, PermissionRegistry}, + permission::{Permission, PermissionDefault, PermissionManager, PermissionRegistry}, }; -use tokio::sync::RwLock; use tracing::{info, warn}; mod advancement; @@ -87,15 +86,13 @@ mod worldborder; #[allow(clippy::too_many_lines)] #[must_use] -pub async fn default_dispatcher( - registry: &RwLock, +pub fn default_dispatcher( + permission_manager: &PermissionManager, _basic_config: &BasicConfiguration, commands_config: &CommandsConfig, ) -> CommandDispatcher { let mut dispatcher = crate::command::dispatcher::CommandDispatcher::default(); - - let mut registry_lock = registry.write().await; - let registry = &mut *registry_lock; + let registry = &permission_manager.registry; register_permissions(registry); @@ -227,7 +224,7 @@ pub async fn default_dispatcher( /// this affects both the legacy and the node-based dispatchers uniformly. fn apply_command_overrides( dispatcher: &mut CommandDispatcher, - registry: &mut PermissionRegistry, + registry: &PermissionRegistry, commands_config: &CommandsConfig, ) { for (raw_name, settings) in &commands_config.overrides { @@ -278,11 +275,16 @@ fn apply_command_overrides( }; if let Some(node) = resolve_permission_node(dispatcher, registry, &name) { - registry.set_default(&node, default); - info!( - "The /{name} command now needs permission level {} to use", - level as u8 - ); + if registry.set_default(&node, default) { + info!( + "The /{name} command now needs permission level {} to use", + level as u8 + ); + } else { + warn!( + "Command override for /{name} sets a permission level, but matching permission node could not be updated; leaving it unchanged" + ); + } } else { warn!( "Command override for /{name} sets a permission level, but no matching permission node could be found; leaving it unchanged" @@ -316,7 +318,7 @@ fn resolve_permission_node( None } -fn register_permissions(registry: &mut PermissionRegistry) { +fn register_permissions(registry: &PermissionRegistry) { // Register level 0 permissions (allowed by default) register_level_0_permissions(registry); @@ -336,7 +338,7 @@ fn register_permissions(registry: &mut PermissionRegistry) { .unwrap_or_else(|e| tracing::warn!("{e}")); } -fn register_level_0_permissions(registry: &mut PermissionRegistry) { +fn register_level_0_permissions(registry: &PermissionRegistry) { // Register permissions for builtin commands that are allowed for everyone registry .register_permission(Permission::new( @@ -362,7 +364,7 @@ fn register_level_0_permissions(registry: &mut PermissionRegistry) { } #[expect(clippy::too_many_lines)] -fn register_level_2_permissions(registry: &mut PermissionRegistry) { +fn register_level_2_permissions(registry: &PermissionRegistry) { // Register permissions for commands with PermissionLvl::Two registry .register_permission(Permission::new( @@ -576,7 +578,7 @@ fn register_level_2_permissions(registry: &mut PermissionRegistry) { .unwrap_or_else(|e| tracing::warn!("{e}")); } -fn register_level_3_permissions(registry: &mut PermissionRegistry) { +fn register_level_3_permissions(registry: &PermissionRegistry) { // Register permissions for commands with PermissionLvl::Three registry .register_permission(Permission::new( @@ -661,8 +663,7 @@ fn register_level_3_permissions(registry: &mut PermissionRegistry) { mod override_tests { use pumpkin_config::{BasicConfiguration, CommandOverride, CommandsConfig}; use pumpkin_util::PermissionLvl; - use pumpkin_util::permission::{PermissionDefault, PermissionRegistry}; - use tokio::sync::RwLock; + use pumpkin_util::permission::{PermissionDefault, PermissionManager}; use super::default_dispatcher; @@ -686,16 +687,16 @@ mod override_tests { ); } - #[tokio::test] - async fn disabling_a_command_removes_and_hides_it() { + #[test] + fn disabling_a_command_removes_and_hides_it() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); // `gamemode` lives on the legacy dispatcher; disabling it should remove // it there and flag it on the wrapper. disabled(&mut commands, "gamemode"); - let registry = RwLock::new(PermissionRegistry::new()); - let dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let dispatcher = default_dispatcher(&manager, &basic, &commands); assert!(dispatcher.is_disabled("gamemode")); assert!( @@ -708,16 +709,16 @@ mod override_tests { ); } - #[tokio::test] - async fn disabling_an_alias_turns_off_the_whole_command() { + #[test] + fn disabling_an_alias_turns_off_the_whole_command() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); // `tp` is an alias of `teleport`; disabling it should take the whole // command down, including the primary name. disabled(&mut commands, "tp"); - let registry = RwLock::new(PermissionRegistry::new()); - let dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let dispatcher = default_dispatcher(&manager, &basic, &commands); assert!(dispatcher.is_disabled("tp")); assert!(dispatcher.is_disabled("teleport")); @@ -725,60 +726,59 @@ mod override_tests { assert!(dispatcher.fallback_dispatcher.get_tree("teleport").is_err()); } - #[tokio::test] - async fn disabling_a_node_command_also_disables_its_aliases() { + #[test] + fn disabling_a_node_command_also_disables_its_aliases() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); // `help` is a node-based command with the aliases `h` and `?`. disabled(&mut commands, "help"); - let registry = RwLock::new(PermissionRegistry::new()); - let dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let dispatcher = default_dispatcher(&manager, &basic, &commands); assert!(dispatcher.is_disabled("help")); assert!(dispatcher.is_disabled("h")); assert!(dispatcher.is_disabled("?")); } - #[tokio::test] - async fn override_for_unknown_command_is_ignored() { + #[test] + fn override_for_unknown_command_is_ignored() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); // A command name that does not exist (usually a typo in the config) // should be ignored, not silently swallow a real command or panic. disabled(&mut commands, "notacommand"); - let registry = RwLock::new(PermissionRegistry::new()); - let dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let dispatcher = default_dispatcher(&manager, &basic, &commands); assert!(!dispatcher.is_disabled("notacommand")); assert!(dispatcher.fallback_dispatcher.get_tree("gamemode").is_ok()); } - #[tokio::test] - async fn override_is_case_insensitive() { + #[test] + fn override_is_case_insensitive() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); disabled(&mut commands, "GameMode"); - let registry = RwLock::new(PermissionRegistry::new()); - let dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let dispatcher = default_dispatcher(&manager, &basic, &commands); assert!(dispatcher.is_disabled("gamemode")); } - #[tokio::test] - async fn permission_level_override_rewrites_the_registry_default() { + #[test] + fn permission_level_override_rewrites_the_registry_default() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); // `gamemode` is normally level 2; bump it to owner-only. permission(&mut commands, "gamemode", PermissionLvl::Four); - let registry = RwLock::new(PermissionRegistry::new()); - let _dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let _dispatcher = default_dispatcher(&manager, &basic, &commands); - let registry = registry.read().await; - let permission = registry + let permission = manager .get_permission("minecraft:command.gamemode") .expect("gamemode permission should be registered"); assert_eq!( @@ -787,8 +787,8 @@ mod override_tests { ); } - #[tokio::test] - async fn permission_override_resolves_node_command_by_convention() { + #[test] + fn permission_override_resolves_node_command_by_convention() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); // `kill` is a node-based command whose permission node is not recorded in @@ -796,11 +796,10 @@ mod override_tests { // `minecraft:command.kill` naming convention. permission(&mut commands, "kill", PermissionLvl::Four); - let registry = RwLock::new(PermissionRegistry::new()); - let _dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let _dispatcher = default_dispatcher(&manager, &basic, &commands); - let registry = registry.read().await; - let permission = registry + let permission = manager .get_permission("minecraft:command.kill") .expect("kill permission should be registered"); assert_eq!( @@ -809,17 +808,16 @@ mod override_tests { ); } - #[tokio::test] - async fn permission_level_zero_allows_everyone() { + #[test] + fn permission_level_zero_allows_everyone() { let basic = BasicConfiguration::default(); let mut commands = CommandsConfig::default(); permission(&mut commands, "gamemode", PermissionLvl::Zero); - let registry = RwLock::new(PermissionRegistry::new()); - let _dispatcher = default_dispatcher(®istry, &basic, &commands).await; + let manager = PermissionManager::new(); + let _dispatcher = default_dispatcher(&manager, &basic, &commands); - let registry = registry.read().await; - let permission = registry + let permission = manager .get_permission("minecraft:command.gamemode") .expect("gamemode permission should be registered"); assert_eq!(permission.default, PermissionDefault::Allow); diff --git a/crates/pumpkin/src/command/commands/op.rs b/crates/pumpkin/src/command/commands/op.rs index 4e9c863c4..8cbe65b54 100644 --- a/crates/pumpkin/src/command/commands/op.rs +++ b/crates/pumpkin/src/command/commands/op.rs @@ -105,7 +105,7 @@ impl SuggestionProvider for OpSuggestionProvider { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/place.rs b/crates/pumpkin/src/command/commands/place.rs index 72f95476c..166141164 100644 --- a/crates/pumpkin/src/command/commands/place.rs +++ b/crates/pumpkin/src/command/commands/place.rs @@ -701,7 +701,7 @@ fn apply_delta( } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/random.rs b/crates/pumpkin/src/command/commands/random.rs index 49e64e4b5..fd3380d0b 100644 --- a/crates/pumpkin/src/command/commands/random.rs +++ b/crates/pumpkin/src/command/commands/random.rs @@ -88,7 +88,7 @@ impl CommandExecutor for RandomExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/recipe.rs b/crates/pumpkin/src/command/commands/recipe.rs index a8c37c33b..2de2a19f7 100644 --- a/crates/pumpkin/src/command/commands/recipe.rs +++ b/crates/pumpkin/src/command/commands/recipe.rs @@ -223,7 +223,7 @@ impl CommandExecutor for RecipeTakeExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/ride.rs b/crates/pumpkin/src/command/commands/ride.rs index e1c046c6b..1f13cb6d7 100644 --- a/crates/pumpkin/src/command/commands/ride.rs +++ b/crates/pumpkin/src/command/commands/ride.rs @@ -178,7 +178,7 @@ impl CommandExecutor for RideDismountExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/saveall.rs b/crates/pumpkin/src/command/commands/saveall.rs index 8dbe68ce4..ed61ad6ba 100644 --- a/crates/pumpkin/src/command/commands/saveall.rs +++ b/crates/pumpkin/src/command/commands/saveall.rs @@ -60,7 +60,7 @@ impl CommandExecutor for SaveAllExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/saveoff.rs b/crates/pumpkin/src/command/commands/saveoff.rs index 964f2ad3a..ad45f6651 100644 --- a/crates/pumpkin/src/command/commands/saveoff.rs +++ b/crates/pumpkin/src/command/commands/saveoff.rs @@ -53,7 +53,7 @@ impl CommandExecutor for SaveOffExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/saveon.rs b/crates/pumpkin/src/command/commands/saveon.rs index 32b79da9b..e490029a0 100644 --- a/crates/pumpkin/src/command/commands/saveon.rs +++ b/crates/pumpkin/src/command/commands/saveon.rs @@ -53,7 +53,7 @@ impl CommandExecutor for SaveOnExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/scoreboard.rs b/crates/pumpkin/src/command/commands/scoreboard.rs index d51a678eb..aaf29a29a 100644 --- a/crates/pumpkin/src/command/commands/scoreboard.rs +++ b/crates/pumpkin/src/command/commands/scoreboard.rs @@ -205,7 +205,7 @@ impl CommandExecutor for ObjectivesRemoveExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/seed.rs b/crates/pumpkin/src/command/commands/seed.rs index b1fde7177..5b8095ab4 100644 --- a/crates/pumpkin/src/command/commands/seed.rs +++ b/crates/pumpkin/src/command/commands/seed.rs @@ -50,7 +50,7 @@ impl CommandExecutor for SeedCommandExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/setidletimeout.rs b/crates/pumpkin/src/command/commands/setidletimeout.rs index c44430d15..40aa11874 100644 --- a/crates/pumpkin/src/command/commands/setidletimeout.rs +++ b/crates/pumpkin/src/command/commands/setidletimeout.rs @@ -58,7 +58,7 @@ impl CommandExecutor for SetIdleTimeoutExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/spreadplayers.rs b/crates/pumpkin/src/command/commands/spreadplayers.rs index e70e8b887..66bfcd372 100644 --- a/crates/pumpkin/src/command/commands/spreadplayers.rs +++ b/crates/pumpkin/src/command/commands/spreadplayers.rs @@ -320,7 +320,7 @@ impl CommandExecutor for SpreadPlayersExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/stop.rs b/crates/pumpkin/src/command/commands/stop.rs index a08af7693..4584b4012 100644 --- a/crates/pumpkin/src/command/commands/stop.rs +++ b/crates/pumpkin/src/command/commands/stop.rs @@ -37,7 +37,7 @@ impl CommandExecutor for StopCommandExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/tag.rs b/crates/pumpkin/src/command/commands/tag.rs index 9d649cf6a..6d313bec0 100644 --- a/crates/pumpkin/src/command/commands/tag.rs +++ b/crates/pumpkin/src/command/commands/tag.rs @@ -177,7 +177,7 @@ impl CommandExecutor for ListExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/team.rs b/crates/pumpkin/src/command/commands/team.rs index 51499f4d5..385d8823c 100644 --- a/crates/pumpkin/src/command/commands/team.rs +++ b/crates/pumpkin/src/command/commands/team.rs @@ -1114,7 +1114,7 @@ fn modify_branch() -> LiteralArgumentBuilder { ) } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/teammsg.rs b/crates/pumpkin/src/command/commands/teammsg.rs index 2faf98ad8..055ae043a 100644 --- a/crates/pumpkin/src/command/commands/teammsg.rs +++ b/crates/pumpkin/src/command/commands/teammsg.rs @@ -81,7 +81,7 @@ impl CommandExecutor for TeamMsgCommandExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/tick.rs b/crates/pumpkin/src/command/commands/tick.rs index 807bbba88..b4e9064f5 100644 --- a/crates/pumpkin/src/command/commands/tick.rs +++ b/crates/pumpkin/src/command/commands/tick.rs @@ -366,7 +366,7 @@ const fn time_argument() -> TimeArgumentType { TimeArgumentType::new(1) } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/commands/trigger.rs b/crates/pumpkin/src/command/commands/trigger.rs index e2e008918..95eff2856 100644 --- a/crates/pumpkin/src/command/commands/trigger.rs +++ b/crates/pumpkin/src/command/commands/trigger.rs @@ -234,7 +234,7 @@ impl CommandExecutor for SetTriggerExecutor { } } -pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { +pub fn register(dispatcher: &mut CommandDispatcher, registry: &PermissionRegistry) { registry.register_permission_or_panic(Permission::new( PERMISSION, DESCRIPTION, diff --git a/crates/pumpkin/src/command/dispatcher.rs b/crates/pumpkin/src/command/dispatcher.rs index 10103bb55..95ca20280 100644 --- a/crates/pumpkin/src/command/dispatcher.rs +++ b/crates/pumpkin/src/command/dispatcher.rs @@ -768,11 +768,10 @@ impl CommandDispatcher { mod test { use pumpkin_config::BasicConfiguration; use pumpkin_data::translation; - use pumpkin_util::permission::PermissionRegistry; + use pumpkin_util::permission::PermissionManager; use pumpkin_util::text::TextContent; use pumpkin_util::text::click::ClickEvent; use pumpkin_util::text::color::{Color, NamedColor}; - use tokio::sync::RwLock; use super::{ PathParsingFailure, render_syntax_error_messages, select_parse_error, @@ -789,26 +788,24 @@ mod test { } } - #[tokio::test] - async fn dynamic_command() { + #[test] + fn dynamic_command() { let config = BasicConfiguration::default(); let commands_config = pumpkin_config::CommandsConfig::default(); - let registry = RwLock::new(PermissionRegistry::new()); - let mut dispatcher = default_dispatcher(®istry, &config, &commands_config) - .await - .fallback_dispatcher; + let manager = PermissionManager::new(); + let mut dispatcher = + default_dispatcher(&manager, &config, &commands_config).fallback_dispatcher; let tree = CommandTree::new(["test"], "test_desc"); dispatcher.register(tree, "minecraft:test"); } - #[tokio::test] - async fn pumpkin_command_aliases() { + #[test] + fn pumpkin_command_aliases() { let config = BasicConfiguration::default(); let commands_config = pumpkin_config::CommandsConfig::default(); - let registry = RwLock::new(PermissionRegistry::new()); - let dispatcher = default_dispatcher(®istry, &config, &commands_config) - .await - .fallback_dispatcher; + let manager = PermissionManager::new(); + let dispatcher = + default_dispatcher(&manager, &config, &commands_config).fallback_dispatcher; let pumpkin_tree = dispatcher.get_tree("pumpkin").unwrap(); let version_tree = dispatcher.get_tree("version").unwrap(); diff --git a/crates/pumpkin/src/command/mod.rs b/crates/pumpkin/src/command/mod.rs index a276d5264..ff704c44f 100644 --- a/crates/pumpkin/src/command/mod.rs +++ b/crates/pumpkin/src/command/mod.rs @@ -174,8 +174,7 @@ impl CommandSender { Self::Console | Self::Rcon(_) => true, // Console and RCON always have all permissions Self::Player(p) => p.has_permission(server, node).await, Self::CommandBlock(..) | Self::Dummy => { - let perm_reg = server.permission_registry.read().await; - let Some(p) = perm_reg.get_permission(node) else { + let Some(p) = server.permission_manager.get_permission(node) else { return false; }; match p.default { diff --git a/crates/pumpkin/src/entity/player.rs b/crates/pumpkin/src/entity/player.rs index 100c62373..3f2442752 100644 --- a/crates/pumpkin/src/entity/player.rs +++ b/crates/pumpkin/src/entity/player.rs @@ -5294,11 +5294,11 @@ impl Player { } pub async fn has_permission(self: &Arc, server: &Server, node: &str) -> bool { - let perm_manager = server.permission_manager.read().await; - let result = perm_manager - .has_permission(&self.gameprofile.id, node, self.permission_lvl.load()) - .await; - drop(perm_manager); + let result = server.permission_manager.has_permission( + &self.gameprofile.id, + node, + self.permission_lvl.load(), + ); let mut event = PlayerPermissionCheckEvent::new(self.clone(), node.to_string(), result); let server_arc = self.world().server.upgrade(); diff --git a/crates/pumpkin/src/plugin/api/context.rs b/crates/pumpkin/src/plugin/api/context.rs index 00c85f1ef..d0e6c8660 100644 --- a/crates/pumpkin/src/plugin/api/context.rs +++ b/crates/pumpkin/src/plugin/api/context.rs @@ -37,7 +37,7 @@ pub struct Context { pub server: Arc, pub handlers: Arc>, pub plugin_manager: Arc, - pub permission_manager: Arc>, + pub permission_manager: Arc, pub logger: Arc>, } impl Context { @@ -229,7 +229,7 @@ impl Context { } /// Register a permission for this plugin - pub async fn register_permission(&self, permission: Permission) -> Result<(), String> { + pub fn register_permission(&self, permission: Permission) -> Result<(), String> { // Ensure the permission has the correct namespace if !permission .node @@ -241,23 +241,20 @@ impl Context { )); } - let registry = &self.permission_manager.read().await.registry; - registry.write().await.register_permission(permission) + self.permission_manager.register_permission(permission) } /// Check if a player has a permission - pub async fn player_has_permission(&self, player_uuid: &uuid::Uuid, permission: &str) -> bool { - let permission_manager = self.permission_manager.read().await; - + #[must_use] + pub fn player_has_permission(&self, player_uuid: &uuid::Uuid, permission: &str) -> bool { // If the player isn't online, we need to find their op level let player_op_level = self .server .get_player_by_uuid(*player_uuid) .map_or(PermissionLvl::Zero, |player| player.permission_lvl.load()); - permission_manager + self.permission_manager .has_permission(player_uuid, permission, player_op_level) - .await } /// Asynchronously registers an event handler for a specific event type. diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/context.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/context.rs index 5b99f71b7..9ca6f341c 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/context.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/context.rs @@ -1963,10 +1963,7 @@ impl pumpkin::plugin::context::HostContext for PluginHostState { let context_res = self .resource_table .get_mut::(&Resource::new_own(context.rep()))?; - Ok(context_res - .provider - .register_permission(util_permission) - .await) + Ok(context_res.provider.register_permission(util_permission)) } async fn get_data_folder(&mut self, _context: Resource) -> wasmtime::Result { diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs index d3fa10563..8c79eaaa9 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs @@ -1365,11 +1365,9 @@ impl pumpkin::plugin::player::HostPlayer for PluginHostState { let player = player_from_resource(self, &player)?; let server = self.server.as_ref().expect("server not available"); - let mut perm_manager = server.permission_manager.write().await; - let attachment = perm_manager.get_attachment(player.gameprofile.id); - drop(perm_manager); - - attachment.write().await.set_permission(&node, value); + server + .permission_manager + .set_permission(player.gameprofile.id, node, value); Ok(()) } @@ -1382,11 +1380,9 @@ impl pumpkin::plugin::player::HostPlayer for PluginHostState { let player = player_from_resource(self, &player)?; let server = self.server.as_ref().expect("server not available"); - let mut perm_manager = server.permission_manager.write().await; - let attachment = perm_manager.get_attachment(player.gameprofile.id); - drop(perm_manager); - - attachment.write().await.unset_permission(&node); + server + .permission_manager + .unset_permission(&player.gameprofile.id, &node); Ok(()) } @@ -1399,11 +1395,9 @@ impl pumpkin::plugin::player::HostPlayer for PluginHostState { let player = player_from_resource(self, &player)?; let server = self.server.as_ref().expect("server not available"); - let mut perm_manager = server.permission_manager.write().await; - let attachment = perm_manager.get_attachment(player.gameprofile.id); - drop(perm_manager); - - Ok(attachment.read().await.has_permission_set(&node)) + Ok(server + .permission_manager + .has_permission_set(&player.gameprofile.id, &node)) } async fn has_permission( diff --git a/crates/pumpkin/src/server/mod.rs b/crates/pumpkin/src/server/mod.rs index 77459a3b8..f03a682e9 100644 --- a/crates/pumpkin/src/server/mod.rs +++ b/crates/pumpkin/src/server/mod.rs @@ -23,7 +23,7 @@ use key_store::KeyStore; use pumpkin_config::{AdvancedConfiguration, BasicConfiguration}; use pumpkin_data::dimension::Dimension; use pumpkin_data::entity::EntityType; -use pumpkin_util::permission::{PermissionManager, PermissionRegistry}; +use pumpkin_util::permission::PermissionManager; use pumpkin_util::text::color::NamedColor; use pumpkin_world::dimension::into_level; use pumpkin_world::world::WorldPortalExt; @@ -47,7 +47,7 @@ use std::net::IpAddr; use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicI32, AtomicI64, AtomicU32}; use std::{future::Future, sync::atomic::Ordering, time::Duration}; -use tokio::sync::{Mutex, OnceCell, RwLock}; +use tokio::sync::{Mutex, OnceCell}; use tokio::task::{JoinHandle, JoinSet}; use tokio_util::task::TaskTracker; @@ -79,9 +79,7 @@ pub struct Server { pub plugin_manager: Arc, /// Permission manager for the server. - pub permission_manager: Arc>, - /// Permission registry for the server. - pub permission_registry: Arc>, + pub permission_manager: Arc, /// Handles cryptographic keys for secure communication. key_store: OnceCell>, @@ -154,16 +152,13 @@ impl Server { advanced_config: AdvancedConfiguration, vanilla_data: VanillaData, ) -> Arc { - let permission_registry = Arc::new(RwLock::new(PermissionRegistry::new())); + let permission_manager = Arc::new(PermissionManager::new()); // First register the default commands. After that, plugins can put in their own. - let command_dispatcher = ArcSwap::from_pointee( - default_dispatcher( - &permission_registry, - &basic_config, - &advanced_config.commands, - ) - .await, - ); + let command_dispatcher = ArcSwap::from_pointee(default_dispatcher( + &permission_manager, + &basic_config, + &advanced_config.commands, + )); crate::command::set_broadcast_console_to_ops( advanced_config.commands.broadcast_console_to_ops, @@ -264,10 +259,7 @@ impl Server { advanced_config, data: vanilla_data, plugin_manager: Arc::new(PluginManager::new()), - permission_manager: Arc::new(RwLock::new(PermissionManager::new( - permission_registry.clone(), - ))), - permission_registry, + permission_manager, container_id: 0.into(), recipe_manager: Arc::new(recipe::RecipeManager::new()), enchantment_manager: Arc::new(enchantment::EnchantmentManager::new()),