-
-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added native operator permission management (#348)
* Starting work on Operator permission system This commit adds the ops.json configuration found in vanilla servers, and updates the basic configuration to handle the default permission level. Server now uses ops file and defaults players to op level 0 The /op command has been added but needs players to rejoin for now. * Clippy Fix + need to Rejoin after /op removed I found the source of the DeadLock. Updated set permission function. Fix cargo formatting issues and clippy issues. * Remove temp warn message * Move OperatorConfig to server As Snowiii pointed out, OperatorConfig is runtime data. Revert most changes in pumpkin-config. op_permission_level must say in the basic configuration for parity with Minecraft. * cargo fmt + cargo clippy * Sync permission change with client * Fixs issues @Commandcracker found in review - Move PermissionLvl to core and removed OpLevel - Move ops.json to /data/ops.json - Fix permissions issue with /op command - Shorten /op command description * refactor into `data` folder * create data dir when needed * add to readme * fix: conflicts --------- Co-authored-by: Alexander Medvedev <[email protected]>
- Loading branch information
1 parent
c521ef8
commit 6a5add8
Showing
25 changed files
with
346 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use pumpkin_core::permission::PermissionLvl; | ||
use serde::{Deserialize, Serialize}; | ||
use uuid::Uuid; | ||
|
||
#[derive(Serialize, Deserialize, Clone, Default)] | ||
pub struct Op { | ||
pub uuid: Uuid, | ||
pub name: String, | ||
pub level: PermissionLvl, | ||
pub bypasses_player_limit: bool, | ||
} | ||
|
||
impl Op { | ||
pub fn new( | ||
uuid: Uuid, | ||
name: String, | ||
level: PermissionLvl, | ||
bypasses_player_limit: bool, | ||
) -> Self { | ||
Self { | ||
uuid, | ||
name, | ||
level, | ||
bypasses_player_limit, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use num_derive::{FromPrimitive, ToPrimitive}; | ||
use serde::{Deserialize, Deserializer, Serialize, Serializer}; | ||
|
||
/// Represents the player's permission level | ||
/// | ||
/// Permission levels determine the player's access to commands and server operations. | ||
/// Each numeric level corresponds to a specific role: | ||
/// - `Zero`: `normal`: Player can use basic commands. | ||
/// - `One`: `moderator`: Player can bypass spawn protection. | ||
/// - `Two`: `gamemaster`: Player or executor can use more commands and player can use command blocks. | ||
/// - `Three`: `admin`: Player or executor can use commands related to multiplayer management. | ||
/// - `Four`: `owner`: Player or executor can use all of the commands, including commands related to server management. | ||
#[derive(FromPrimitive, ToPrimitive, Clone, Copy, Default, PartialEq, Eq)] | ||
#[repr(i8)] | ||
pub enum PermissionLvl { | ||
#[default] | ||
Zero = 0, | ||
One = 1, | ||
Two = 2, | ||
Three = 3, | ||
Four = 4, | ||
} | ||
|
||
impl PartialOrd for PermissionLvl { | ||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||
(*self as u8).partial_cmp(&(*other as u8)) | ||
} | ||
} | ||
|
||
impl Serialize for PermissionLvl { | ||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
serializer.serialize_u8(*self as u8) | ||
} | ||
} | ||
|
||
impl<'de> Deserialize<'de> for PermissionLvl { | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
let value = u8::deserialize(deserializer)?; | ||
match value { | ||
0 => Ok(PermissionLvl::Zero), | ||
2 => Ok(PermissionLvl::Two), | ||
3 => Ok(PermissionLvl::Three), | ||
4 => Ok(PermissionLvl::Four), | ||
_ => Err(serde::de::Error::custom(format!( | ||
"Invalid value for OpLevel: {}", | ||
value | ||
))), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use crate::{ | ||
command::{ | ||
args::{arg_players::PlayersArgumentConsumer, Arg, ConsumedArgs}, | ||
tree::CommandTree, | ||
tree_builder::{argument, require}, | ||
CommandError, CommandExecutor, CommandSender, | ||
}, | ||
data::{op_data::OPERATOR_CONFIG, SaveJSONConfiguration}, | ||
}; | ||
use async_trait::async_trait; | ||
use pumpkin_config::{op::Op, BASIC_CONFIG}; | ||
use pumpkin_core::permission::PermissionLvl; | ||
use pumpkin_core::text::TextComponent; | ||
use CommandError::InvalidConsumption; | ||
|
||
const NAMES: [&str; 1] = ["op"]; | ||
const DESCRIPTION: &str = "Grants operator status to a player."; | ||
const ARG_TARGET: &str = "player"; | ||
|
||
struct OpExecutor; | ||
|
||
#[async_trait] | ||
impl CommandExecutor for OpExecutor { | ||
async fn execute<'a>( | ||
&self, | ||
sender: &mut CommandSender<'a>, | ||
server: &crate::server::Server, | ||
args: &ConsumedArgs<'a>, | ||
) -> Result<(), CommandError> { | ||
let mut config = OPERATOR_CONFIG.write().await; | ||
|
||
let Some(Arg::Players(targets)) = args.get(&ARG_TARGET) else { | ||
return Err(InvalidConsumption(Some(ARG_TARGET.into()))); | ||
}; | ||
|
||
// log each player to the console. | ||
for player in targets { | ||
let new_level = if BASIC_CONFIG.op_permission_level > sender.permission_lvl() { | ||
sender.permission_lvl() | ||
} else { | ||
BASIC_CONFIG.op_permission_level | ||
}; | ||
|
||
let op_entry = Op::new( | ||
player.gameprofile.id, | ||
player.gameprofile.name.clone(), | ||
new_level, | ||
false, | ||
); | ||
if let Some(op) = config | ||
.ops | ||
.iter_mut() | ||
.find(|o| o.uuid == player.gameprofile.id) | ||
{ | ||
op.level = new_level; | ||
} else { | ||
config.ops.push(op_entry); | ||
} | ||
config.save(); | ||
|
||
player | ||
.set_permission_lvl(new_level, &server.command_dispatcher) | ||
.await; | ||
|
||
let player_name = player.gameprofile.name.clone(); | ||
let message = format!("Made {player_name} a server operator."); | ||
let msg = TextComponent::text(&message); | ||
sender.send_message(msg).await; | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
pub fn init_command_tree() -> CommandTree { | ||
CommandTree::new(NAMES, DESCRIPTION).with_child( | ||
require(|sender| sender.has_permission_lvl(PermissionLvl::Three)) | ||
.with_child(argument(ARG_TARGET, PlayersArgumentConsumer).execute(OpExecutor)), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.