Add Effects
This commit is contained in:
parent
0fb1b76ea7
commit
995edfb3c2
@ -51,7 +51,7 @@ rayon = "1.10"
|
|||||||
parking_lot = { version = "0.12", features = ["send_guard"] }
|
parking_lot = { version = "0.12", features = ["send_guard"] }
|
||||||
crossbeam = "0.8"
|
crossbeam = "0.8"
|
||||||
|
|
||||||
uuid = { version = "1.13", features = ["serde", "v3", "v4"] }
|
uuid = { version = "1.14", features = ["serde", "v3", "v4"] }
|
||||||
derive_more = { version = "2.0", features = ["full"] }
|
derive_more = { version = "2.0", features = ["full"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|||||||
@ -72,6 +72,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi
|
|||||||
- [ ] Advancements
|
- [ ] Advancements
|
||||||
- Entities
|
- Entities
|
||||||
- [x] Non-Living (Minecart, Eggs...)
|
- [x] Non-Living (Minecart, Eggs...)
|
||||||
|
- [x] Entity Effects
|
||||||
- [x] Players
|
- [x] Players
|
||||||
- [x] Mobs
|
- [x] Mobs
|
||||||
- [x] Animals
|
- [x] Animals
|
||||||
|
|||||||
41
assets/status_effects.json
Normal file
41
assets/status_effects.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
[
|
||||||
|
"speed",
|
||||||
|
"slowness",
|
||||||
|
"haste",
|
||||||
|
"mining_fatigue",
|
||||||
|
"strength",
|
||||||
|
"instant_health",
|
||||||
|
"instant_damage",
|
||||||
|
"jump_boost",
|
||||||
|
"nausea",
|
||||||
|
"regeneration",
|
||||||
|
"resistance",
|
||||||
|
"fire_resistance",
|
||||||
|
"water_breathing",
|
||||||
|
"invisibility",
|
||||||
|
"blindness",
|
||||||
|
"night_vision",
|
||||||
|
"hunger",
|
||||||
|
"weakness",
|
||||||
|
"poison",
|
||||||
|
"wither",
|
||||||
|
"health_boost",
|
||||||
|
"absorption",
|
||||||
|
"saturation",
|
||||||
|
"glowing",
|
||||||
|
"levitation",
|
||||||
|
"luck",
|
||||||
|
"unluck",
|
||||||
|
"slow_falling",
|
||||||
|
"conduit_power",
|
||||||
|
"dolphins_grace",
|
||||||
|
"bad_omen",
|
||||||
|
"hero_of_the_village",
|
||||||
|
"darkness",
|
||||||
|
"trial_omen",
|
||||||
|
"raid_omen",
|
||||||
|
"wind_charged",
|
||||||
|
"weaving",
|
||||||
|
"oozing",
|
||||||
|
"infested"
|
||||||
|
]
|
||||||
@ -21,6 +21,7 @@ mod screen;
|
|||||||
mod sound;
|
mod sound;
|
||||||
mod sound_category;
|
mod sound_category;
|
||||||
mod spawn_egg;
|
mod spawn_egg;
|
||||||
|
mod status_effect;
|
||||||
mod world_event;
|
mod world_event;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
@ -42,6 +43,7 @@ pub fn main() {
|
|||||||
write_generated_file(spawn_egg::build(), "spawn_egg.rs");
|
write_generated_file(spawn_egg::build(), "spawn_egg.rs");
|
||||||
write_generated_file(item::build(), "item.rs");
|
write_generated_file(item::build(), "item.rs");
|
||||||
write_generated_file(fluid::build(), "fluid.rs");
|
write_generated_file(fluid::build(), "fluid.rs");
|
||||||
|
write_generated_file(status_effect::build(), "status_effect.rs");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn array_to_tokenstream(array: &[String]) -> TokenStream {
|
pub fn array_to_tokenstream(array: &[String]) -> TokenStream {
|
||||||
|
|||||||
51
pumpkin-data/build/status_effect.rs
Normal file
51
pumpkin-data/build/status_effect.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use heck::ToPascalCase;
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{format_ident, quote};
|
||||||
|
|
||||||
|
pub(crate) fn build() -> TokenStream {
|
||||||
|
println!("cargo:rerun-if-changed=../assets/status_effects.json");
|
||||||
|
|
||||||
|
let chunk_status: Vec<String> =
|
||||||
|
serde_json::from_str(include_str!("../../assets/status_effects.json"))
|
||||||
|
.expect("Failed to parse status_effects.json");
|
||||||
|
let mut variants = TokenStream::new();
|
||||||
|
let mut type_from_name = TokenStream::new();
|
||||||
|
let mut type_to_name = TokenStream::new();
|
||||||
|
|
||||||
|
for status in chunk_status.iter() {
|
||||||
|
let const_ident = format_ident!("{}", status.to_pascal_case());
|
||||||
|
let resource_name = status.to_lowercase();
|
||||||
|
|
||||||
|
variants.extend([quote! {
|
||||||
|
#const_ident,
|
||||||
|
}]);
|
||||||
|
type_from_name.extend(quote! {
|
||||||
|
#resource_name => Some(Self::#const_ident),
|
||||||
|
});
|
||||||
|
type_to_name.extend(quote! {
|
||||||
|
Self::#const_ident => #resource_name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
quote! {
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub enum EffectType {
|
||||||
|
#variants
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EffectType {
|
||||||
|
#[doc = r" Try to parse a Effect Type from a resource location string"]
|
||||||
|
pub fn from_name(name: &str) -> Option<Self> {
|
||||||
|
match name {
|
||||||
|
#type_from_name
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn to_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
#type_to_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,6 +32,7 @@ pub mod game_event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod entity {
|
pub mod entity {
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/status_effect.rs"));
|
||||||
include!(concat!(env!("OUT_DIR"), "/spawn_egg.rs"));
|
include!(concat!(env!("OUT_DIR"), "/spawn_egg.rs"));
|
||||||
include!(concat!(env!("OUT_DIR"), "/entity_type.rs"));
|
include!(concat!(env!("OUT_DIR"), "/entity_type.rs"));
|
||||||
include!(concat!(env!("OUT_DIR"), "/entity_pose.rs"));
|
include!(concat!(env!("OUT_DIR"), "/entity_pose.rs"));
|
||||||
|
|||||||
@ -71,6 +71,7 @@ mod unload_chunk;
|
|||||||
mod update_entity_pos;
|
mod update_entity_pos;
|
||||||
mod update_entity_pos_rot;
|
mod update_entity_pos_rot;
|
||||||
mod update_entity_rot;
|
mod update_entity_rot;
|
||||||
|
mod update_mob_effect;
|
||||||
mod update_objectives;
|
mod update_objectives;
|
||||||
mod update_score;
|
mod update_score;
|
||||||
mod worldevent;
|
mod worldevent;
|
||||||
@ -148,6 +149,7 @@ pub use unload_chunk::*;
|
|||||||
pub use update_entity_pos::*;
|
pub use update_entity_pos::*;
|
||||||
pub use update_entity_pos_rot::*;
|
pub use update_entity_pos_rot::*;
|
||||||
pub use update_entity_rot::*;
|
pub use update_entity_rot::*;
|
||||||
|
pub use update_mob_effect::*;
|
||||||
pub use update_objectives::*;
|
pub use update_objectives::*;
|
||||||
pub use update_score::*;
|
pub use update_score::*;
|
||||||
pub use worldevent::*;
|
pub use worldevent::*;
|
||||||
|
|||||||
33
pumpkin-protocol/src/client/play/update_mob_effect.rs
Normal file
33
pumpkin-protocol/src/client/play/update_mob_effect.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use pumpkin_data::packet::clientbound::PLAY_UPDATE_MOB_EFFECT;
|
||||||
|
use pumpkin_macros::client_packet;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::codec::var_int::VarInt;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[client_packet(PLAY_UPDATE_MOB_EFFECT)]
|
||||||
|
pub struct CUpdateMobEffect {
|
||||||
|
entity_id: VarInt,
|
||||||
|
effect_id: VarInt,
|
||||||
|
amplifier: VarInt,
|
||||||
|
duration: VarInt,
|
||||||
|
flags: i8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CUpdateMobEffect {
|
||||||
|
pub fn new(
|
||||||
|
entity_id: VarInt,
|
||||||
|
effect_id: VarInt,
|
||||||
|
amplifier: VarInt,
|
||||||
|
duration: VarInt,
|
||||||
|
flags: i8,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
effect_id,
|
||||||
|
amplifier,
|
||||||
|
duration,
|
||||||
|
flags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,7 +30,7 @@ num-traits = "0.2"
|
|||||||
# Compression
|
# Compression
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
lz4 = "1.28"
|
lz4 = "1.28"
|
||||||
zstd = "0.13.2"
|
zstd = "0.13.3"
|
||||||
|
|
||||||
|
|
||||||
file-guard = "0.2"
|
file-guard = "0.2"
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use std::{collections::HashMap, hash::Hash, sync::Arc};
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bounded_num::{NotInBounds, Number};
|
use bounded_num::{NotInBounds, Number};
|
||||||
use pumpkin_data::damage::DamageType;
|
use pumpkin_data::damage::DamageType;
|
||||||
|
use pumpkin_data::entity::EffectType;
|
||||||
use pumpkin_data::particle::Particle;
|
use pumpkin_data::particle::Particle;
|
||||||
use pumpkin_data::sound::SoundCategory;
|
use pumpkin_data::sound::SoundCategory;
|
||||||
use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders};
|
use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders};
|
||||||
@ -27,17 +28,15 @@ pub mod bossbar_style;
|
|||||||
pub mod bounded_num;
|
pub mod bounded_num;
|
||||||
pub mod command;
|
pub mod command;
|
||||||
mod coordinate;
|
mod coordinate;
|
||||||
pub mod damage_type;
|
|
||||||
pub mod entities;
|
pub mod entities;
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
pub mod gamemode;
|
pub mod gamemode;
|
||||||
pub mod item;
|
|
||||||
pub mod message;
|
pub mod message;
|
||||||
pub mod particle;
|
|
||||||
pub mod players;
|
pub mod players;
|
||||||
pub mod position_2d;
|
pub mod position_2d;
|
||||||
pub mod position_3d;
|
pub mod position_3d;
|
||||||
pub mod position_block;
|
pub mod position_block;
|
||||||
|
pub mod resource;
|
||||||
pub mod resource_location;
|
pub mod resource_location;
|
||||||
pub mod rotation;
|
pub mod rotation;
|
||||||
pub mod simple;
|
pub mod simple;
|
||||||
@ -105,6 +104,7 @@ pub enum Arg<'a> {
|
|||||||
Simple(&'a str),
|
Simple(&'a str),
|
||||||
SoundCategory(SoundCategory),
|
SoundCategory(SoundCategory),
|
||||||
DamageType(DamageType),
|
DamageType(DamageType),
|
||||||
|
Effect(EffectType),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// see [`crate::commands::tree::builder::argument`] and [`CommandTree::execute`]/[`crate::commands::tree::builder::NonLeafNodeBuilder::execute`]
|
/// see [`crate::commands::tree::builder::argument`] and [`CommandTree::execute`]/[`crate::commands::tree::builder::NonLeafNodeBuilder::execute`]
|
||||||
|
|||||||
@ -4,7 +4,10 @@ use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, Suggestion
|
|||||||
|
|
||||||
use crate::command::{
|
use crate::command::{
|
||||||
CommandSender,
|
CommandSender,
|
||||||
args::{Arg, ArgumentConsumer, DefaultNameArgConsumer, FindArg, GetClientSideArgParser},
|
args::{
|
||||||
|
Arg, ArgumentConsumer, ConsumedArgs, DefaultNameArgConsumer, FindArg,
|
||||||
|
GetClientSideArgParser,
|
||||||
|
},
|
||||||
dispatcher::CommandError,
|
dispatcher::CommandError,
|
||||||
tree::RawArgs,
|
tree::RawArgs,
|
||||||
};
|
};
|
||||||
@ -59,7 +62,7 @@ impl DefaultNameArgConsumer for DamageTypeArgumentConsumer {
|
|||||||
impl<'a> FindArg<'a> for DamageTypeArgumentConsumer {
|
impl<'a> FindArg<'a> for DamageTypeArgumentConsumer {
|
||||||
type Data = &'a DamageType;
|
type Data = &'a DamageType;
|
||||||
|
|
||||||
fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
fn find_arg(args: &'a ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
||||||
match args.get(name) {
|
match args.get(name) {
|
||||||
Some(Arg::DamageType(data)) => Ok(data),
|
Some(Arg::DamageType(data)) => Ok(data),
|
||||||
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
|
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
|
||||||
71
pumpkin/src/command/args/resource/effect.rs
Normal file
71
pumpkin/src/command/args/resource/effect.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
use pumpkin_data::entity::EffectType;
|
||||||
|
use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders};
|
||||||
|
|
||||||
|
use crate::command::{
|
||||||
|
CommandSender,
|
||||||
|
args::{
|
||||||
|
Arg, ArgumentConsumer, ConsumedArgs, DefaultNameArgConsumer, FindArg,
|
||||||
|
GetClientSideArgParser,
|
||||||
|
},
|
||||||
|
dispatcher::CommandError,
|
||||||
|
tree::RawArgs,
|
||||||
|
};
|
||||||
|
use crate::server::Server;
|
||||||
|
|
||||||
|
pub struct EffectTypeArgumentConsumer;
|
||||||
|
|
||||||
|
impl GetClientSideArgParser for EffectTypeArgumentConsumer {
|
||||||
|
fn get_client_side_parser(&self) -> ArgumentType {
|
||||||
|
ArgumentType::Resource {
|
||||||
|
identifier: "mob_effect",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_client_side_suggestion_type_override(&self) -> Option<SuggestionProviders> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl ArgumentConsumer for EffectTypeArgumentConsumer {
|
||||||
|
async fn consume<'a>(
|
||||||
|
&'a self,
|
||||||
|
_sender: &CommandSender<'a>,
|
||||||
|
_server: &'a Server,
|
||||||
|
args: &mut RawArgs<'a>,
|
||||||
|
) -> Option<Arg<'a>> {
|
||||||
|
let name = args.pop()?;
|
||||||
|
|
||||||
|
// Create a static damage type first
|
||||||
|
let damage_type = EffectType::from_name(&name.replace("minecraft:", ""))?;
|
||||||
|
// Find matching static damage type from values array
|
||||||
|
Some(Arg::Effect(damage_type))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn suggest<'a>(
|
||||||
|
&'a self,
|
||||||
|
_sender: &CommandSender<'a>,
|
||||||
|
_server: &'a Server,
|
||||||
|
_input: &'a str,
|
||||||
|
) -> Result<Option<Vec<CommandSuggestion>>, CommandError> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DefaultNameArgConsumer for EffectTypeArgumentConsumer {
|
||||||
|
fn default_name(&self) -> &'static str {
|
||||||
|
"mob_effect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FindArg<'a> for EffectTypeArgumentConsumer {
|
||||||
|
type Data = &'a EffectType;
|
||||||
|
|
||||||
|
fn find_arg(args: &'a ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
||||||
|
match args.get(name) {
|
||||||
|
Some(Arg::Effect(data)) => Ok(data),
|
||||||
|
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,15 +2,16 @@ use async_trait::async_trait;
|
|||||||
use pumpkin_data::item::Item;
|
use pumpkin_data::item::Item;
|
||||||
use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders};
|
use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, SuggestionProviders};
|
||||||
|
|
||||||
use crate::{command::dispatcher::CommandError, server::Server};
|
use crate::command::{
|
||||||
|
CommandSender,
|
||||||
use super::{
|
args::{
|
||||||
super::{
|
Arg, ArgumentConsumer, ConsumedArgs, DefaultNameArgConsumer, FindArg,
|
||||||
CommandSender,
|
GetClientSideArgParser,
|
||||||
args::{ArgumentConsumer, RawArgs},
|
|
||||||
},
|
},
|
||||||
Arg, DefaultNameArgConsumer, FindArg, GetClientSideArgParser,
|
dispatcher::CommandError,
|
||||||
|
tree::RawArgs,
|
||||||
};
|
};
|
||||||
|
use crate::server::Server;
|
||||||
|
|
||||||
pub struct ItemArgumentConsumer;
|
pub struct ItemArgumentConsumer;
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ impl DefaultNameArgConsumer for ItemArgumentConsumer {
|
|||||||
impl<'a> FindArg<'a> for ItemArgumentConsumer {
|
impl<'a> FindArg<'a> for ItemArgumentConsumer {
|
||||||
type Data = (&'a str, Item);
|
type Data = (&'a str, Item);
|
||||||
|
|
||||||
fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
fn find_arg(args: &'a ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
||||||
match args.get(name) {
|
match args.get(name) {
|
||||||
Some(Arg::Item(name)) => Item::from_name(&name.replace("minecraft:", "")).map_or_else(
|
Some(Arg::Item(name)) => Item::from_name(&name.replace("minecraft:", "")).map_or_else(
|
||||||
|| {
|
|| {
|
||||||
4
pumpkin/src/command/args/resource/mod.rs
Normal file
4
pumpkin/src/command/args/resource/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod damage_type;
|
||||||
|
pub mod effect;
|
||||||
|
pub mod item;
|
||||||
|
pub mod particle;
|
||||||
@ -4,7 +4,10 @@ use pumpkin_protocol::client::play::{ArgumentType, CommandSuggestion, Suggestion
|
|||||||
|
|
||||||
use crate::command::{
|
use crate::command::{
|
||||||
CommandSender,
|
CommandSender,
|
||||||
args::{Arg, ArgumentConsumer, DefaultNameArgConsumer, FindArg, GetClientSideArgParser},
|
args::{
|
||||||
|
Arg, ArgumentConsumer, ConsumedArgs, DefaultNameArgConsumer, FindArg,
|
||||||
|
GetClientSideArgParser,
|
||||||
|
},
|
||||||
dispatcher::CommandError,
|
dispatcher::CommandError,
|
||||||
tree::RawArgs,
|
tree::RawArgs,
|
||||||
};
|
};
|
||||||
@ -59,7 +62,7 @@ impl DefaultNameArgConsumer for ParticleArgumentConsumer {
|
|||||||
impl<'a> FindArg<'a> for ParticleArgumentConsumer {
|
impl<'a> FindArg<'a> for ParticleArgumentConsumer {
|
||||||
type Data = &'a Particle;
|
type Data = &'a Particle;
|
||||||
|
|
||||||
fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
fn find_arg(args: &'a ConsumedArgs, name: &str) -> Result<Self::Data, CommandError> {
|
||||||
match args.get(name) {
|
match args.get(name) {
|
||||||
Some(Arg::Particle(data)) => Ok(data),
|
Some(Arg::Particle(data)) => Ok(data),
|
||||||
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
|
_ => Err(CommandError::InvalidConsumption(Some(name.to_string()))),
|
||||||
@ -20,10 +20,10 @@ const DESCRIPTION: &str = "bans a player";
|
|||||||
const ARG_TARGET: &str = "player";
|
const ARG_TARGET: &str = "player";
|
||||||
const ARG_REASON: &str = "reason";
|
const ARG_REASON: &str = "reason";
|
||||||
|
|
||||||
struct BanNoReasonExecutor;
|
struct NoReasonExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BanNoReasonExecutor {
|
impl CommandExecutor for NoReasonExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -39,10 +39,10 @@ impl CommandExecutor for BanNoReasonExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BanReasonExecutor;
|
struct ReasonExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BanReasonExecutor {
|
impl CommandExecutor for ReasonExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -107,7 +107,7 @@ async fn ban_player(sender: &CommandSender<'_>, player: &Player, reason: Option<
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_TARGET, PlayersArgumentConsumer)
|
argument(ARG_TARGET, PlayersArgumentConsumer)
|
||||||
.execute(BanNoReasonExecutor)
|
.execute(NoReasonExecutor)
|
||||||
.then(argument(ARG_REASON, MsgArgConsumer).execute(BanReasonExecutor)),
|
.then(argument(ARG_REASON, MsgArgConsumer).execute(ReasonExecutor)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,10 +36,10 @@ async fn parse_ip(target: &str, server: &Server) -> Option<IpAddr> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BanIpNoReasonExecutor;
|
struct NoReasonExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BanIpNoReasonExecutor {
|
impl CommandExecutor for NoReasonExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -55,10 +55,10 @@ impl CommandExecutor for BanIpNoReasonExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BanIpReasonExecutor;
|
struct ReasonExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BanIpReasonExecutor {
|
impl CommandExecutor for ReasonExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -148,7 +148,7 @@ async fn ban_ip(sender: &CommandSender<'_>, server: &Server, target: &str, reaso
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_TARGET, SimpleArgConsumer)
|
argument(ARG_TARGET, SimpleArgConsumer)
|
||||||
.execute(BanIpNoReasonExecutor)
|
.execute(NoReasonExecutor)
|
||||||
.then(argument(ARG_REASON, MsgArgConsumer).execute(BanIpReasonExecutor)),
|
.then(argument(ARG_REASON, MsgArgConsumer).execute(ReasonExecutor)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ const DESCRIPTION: &str = "shows the banlist";
|
|||||||
|
|
||||||
const ARG_LIST_TYPE: &str = "ips|players";
|
const ARG_LIST_TYPE: &str = "ips|players";
|
||||||
|
|
||||||
struct BanListExecutor;
|
struct ListExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BanListExecutor {
|
impl CommandExecutor for ListExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -74,10 +74,10 @@ impl CommandExecutor for BanListExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BanListAllExecutor;
|
struct ListAllExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BanListAllExecutor {
|
impl CommandExecutor for ListAllExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -138,6 +138,6 @@ async fn handle_banlist(list: Vec<(String, String, String)>, sender: &CommandSen
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.execute(BanListAllExecutor)
|
.execute(ListAllExecutor)
|
||||||
.then(argument(ARG_LIST_TYPE, SimpleArgConsumer).execute(BanListExecutor))
|
.then(argument(ARG_LIST_TYPE, SimpleArgConsumer).execute(ListExecutor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,10 +52,10 @@ enum CommandValueSet {
|
|||||||
Visible,
|
Visible,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BossbarAddExecuter;
|
struct AddExecuter;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BossbarAddExecuter {
|
impl CommandExecutor for AddExecuter {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -101,10 +101,10 @@ impl CommandExecutor for BossbarAddExecuter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BossbarGetExecuter(CommandValueGet);
|
struct GetExecuter(CommandValueGet);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BossbarGetExecuter {
|
impl CommandExecutor for GetExecuter {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -179,10 +179,10 @@ impl CommandExecutor for BossbarGetExecuter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BossbarListExecuter;
|
struct ListExecuter;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BossbarListExecuter {
|
impl CommandExecutor for ListExecuter {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -238,10 +238,10 @@ impl CommandExecutor for BossbarListExecuter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BossbarRemoveExecuter;
|
struct RemoveExecuter;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BossbarRemoveExecuter {
|
impl CommandExecutor for RemoveExecuter {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -289,10 +289,10 @@ impl CommandExecutor for BossbarRemoveExecuter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BossbarSetExecuter(CommandValueSet);
|
struct SetExecuter(CommandValueSet);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for BossbarSetExecuter {
|
impl CommandExecutor for SetExecuter {
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
@ -591,25 +591,24 @@ fn value_consumer() -> BoundedNumArgumentConsumer<i32> {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(
|
.then(
|
||||||
literal("add")
|
literal("add").then(
|
||||||
.then(argument_default_name(non_autocomplete_consumer()).then(
|
argument_default_name(non_autocomplete_consumer())
|
||||||
argument(ARG_NAME, TextComponentArgConsumer).execute(BossbarAddExecuter),
|
.then(argument(ARG_NAME, TextComponentArgConsumer).execute(AddExecuter)),
|
||||||
)),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("get").then(
|
literal("get").then(
|
||||||
argument_default_name(autocomplete_consumer())
|
argument_default_name(autocomplete_consumer())
|
||||||
.then(literal("max").execute(BossbarGetExecuter(CommandValueGet::Max)))
|
.then(literal("max").execute(GetExecuter(CommandValueGet::Max)))
|
||||||
.then(literal("players").execute(BossbarGetExecuter(CommandValueGet::Players)))
|
.then(literal("players").execute(GetExecuter(CommandValueGet::Players)))
|
||||||
.then(literal("value").execute(BossbarGetExecuter(CommandValueGet::Value)))
|
.then(literal("value").execute(GetExecuter(CommandValueGet::Value)))
|
||||||
.then(literal("visible").execute(BossbarGetExecuter(CommandValueGet::Visible))),
|
.then(literal("visible").execute(GetExecuter(CommandValueGet::Visible))),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(literal("list").execute(BossbarListExecuter))
|
.then(literal("list").execute(ListExecuter))
|
||||||
.then(
|
.then(
|
||||||
literal("remove").then(
|
literal("remove")
|
||||||
argument_default_name(autocomplete_consumer()).execute(BossbarRemoveExecuter),
|
.then(argument_default_name(autocomplete_consumer()).execute(RemoveExecuter)),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("set").then(
|
literal("set").then(
|
||||||
@ -617,45 +616,45 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
.then(
|
.then(
|
||||||
literal("color").then(
|
literal("color").then(
|
||||||
argument_default_name(BossbarColorArgumentConsumer)
|
argument_default_name(BossbarColorArgumentConsumer)
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Color)),
|
.execute(SetExecuter(CommandValueSet::Color)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("max").then(
|
literal("max").then(
|
||||||
argument_default_name(max_value_consumer())
|
argument_default_name(max_value_consumer())
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Max)),
|
.execute(SetExecuter(CommandValueSet::Max)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("name").then(
|
literal("name").then(
|
||||||
argument(ARG_NAME, TextComponentArgConsumer)
|
argument(ARG_NAME, TextComponentArgConsumer)
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Name)),
|
.execute(SetExecuter(CommandValueSet::Name)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("players")
|
literal("players")
|
||||||
.then(
|
.then(
|
||||||
argument_default_name(PlayersArgumentConsumer)
|
argument_default_name(PlayersArgumentConsumer)
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Players(true))),
|
.execute(SetExecuter(CommandValueSet::Players(true))),
|
||||||
)
|
)
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Players(false))),
|
.execute(SetExecuter(CommandValueSet::Players(false))),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("style").then(
|
literal("style").then(
|
||||||
argument_default_name(BossbarStyleArgumentConsumer)
|
argument_default_name(BossbarStyleArgumentConsumer)
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Style)),
|
.execute(SetExecuter(CommandValueSet::Style)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("value").then(
|
literal("value").then(
|
||||||
argument_default_name(value_consumer())
|
argument_default_name(value_consumer())
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Value)),
|
.execute(SetExecuter(CommandValueSet::Value)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("visible").then(
|
literal("visible").then(
|
||||||
argument(ARG_VISIBLE, BoolArgConsumer)
|
argument(ARG_VISIBLE, BoolArgConsumer)
|
||||||
.execute(BossbarSetExecuter(CommandValueSet::Visible)),
|
.execute(SetExecuter(CommandValueSet::Visible)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -73,10 +73,10 @@ fn clear_command_text_output(item_count: usize, targets: &[Arc<Player>]) -> Text
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClearExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for ClearExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -100,10 +100,10 @@ impl CommandExecutor for ClearExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClearSelfExecutor;
|
struct SelfExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for ClearSelfExecutor {
|
impl CommandExecutor for SelfExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -126,6 +126,6 @@ impl CommandExecutor for ClearSelfExecutor {
|
|||||||
#[allow(clippy::redundant_closure_for_method_calls)] // causes lifetime issues
|
#[allow(clippy::redundant_closure_for_method_calls)] // causes lifetime issues
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_TARGET, EntitiesArgumentConsumer).execute(ClearExecutor))
|
.then(argument(ARG_TARGET, EntitiesArgumentConsumer).execute(Executor))
|
||||||
.then(require(|sender| sender.is_player()).execute(ClearSelfExecutor))
|
.then(require(|sender| sender.is_player()).execute(SelfExecutor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,11 +9,13 @@ use crate::command::{
|
|||||||
CommandError, CommandExecutor, CommandSender,
|
CommandError, CommandExecutor, CommandSender,
|
||||||
args::{
|
args::{
|
||||||
Arg, ConsumedArgs, FindArg, bounded_num::BoundedNumArgumentConsumer,
|
Arg, ConsumedArgs, FindArg, bounded_num::BoundedNumArgumentConsumer,
|
||||||
damage_type::DamageTypeArgumentConsumer, entity::EntityArgumentConsumer,
|
entity::EntityArgumentConsumer, position_3d::Position3DArgumentConsumer,
|
||||||
position_3d::Position3DArgumentConsumer,
|
resource::damage_type::DamageTypeArgumentConsumer,
|
||||||
|
},
|
||||||
|
tree::{
|
||||||
|
CommandTree,
|
||||||
|
builder::{argument, literal},
|
||||||
},
|
},
|
||||||
tree::CommandTree,
|
|
||||||
tree::builder::{argument, literal},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const NAMES: [&str; 1] = ["damage"];
|
const NAMES: [&str; 1] = ["damage"];
|
||||||
@ -29,8 +31,8 @@ fn amount_consumer() -> BoundedNumArgumentConsumer<f32> {
|
|||||||
BoundedNumArgumentConsumer::new().name(ARG_AMOUNT).min(0.0)
|
BoundedNumArgumentConsumer::new().name(ARG_AMOUNT).min(0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DamageLocationExecutor;
|
struct LocationExecutor;
|
||||||
struct DamageEntityExecutor(bool);
|
struct EntityExecutor(bool);
|
||||||
|
|
||||||
async fn send_damage_result(
|
async fn send_damage_result(
|
||||||
sender: &mut CommandSender<'_>,
|
sender: &mut CommandSender<'_>,
|
||||||
@ -60,7 +62,7 @@ async fn send_damage_result(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for DamageLocationExecutor {
|
impl CommandExecutor for LocationExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -100,7 +102,7 @@ impl CommandExecutor for DamageLocationExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for DamageEntityExecutor {
|
impl CommandExecutor for EntityExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -155,28 +157,28 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
argument(ARG_TARGET, EntityArgumentConsumer).then(
|
argument(ARG_TARGET, EntityArgumentConsumer).then(
|
||||||
argument(ARG_AMOUNT, amount_consumer())
|
argument(ARG_AMOUNT, amount_consumer())
|
||||||
// Basic damage
|
// Basic damage
|
||||||
.execute(DamageEntityExecutor(false))
|
.execute(EntityExecutor(false))
|
||||||
// With damage type
|
// With damage type
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_DAMAGE_TYPE, DamageTypeArgumentConsumer)
|
argument(ARG_DAMAGE_TYPE, DamageTypeArgumentConsumer)
|
||||||
.execute(DamageEntityExecutor(false))
|
.execute(EntityExecutor(false))
|
||||||
// At location
|
// At location
|
||||||
.then(
|
.then(
|
||||||
literal("at").then(
|
literal("at").then(
|
||||||
argument(ARG_LOCATION, Position3DArgumentConsumer)
|
argument(ARG_LOCATION, Position3DArgumentConsumer)
|
||||||
.execute(DamageLocationExecutor),
|
.execute(LocationExecutor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
// By entity
|
// By entity
|
||||||
.then(
|
.then(
|
||||||
literal("by").then(
|
literal("by").then(
|
||||||
argument(ARG_ENTITY, EntityArgumentConsumer)
|
argument(ARG_ENTITY, EntityArgumentConsumer)
|
||||||
.execute(DamageEntityExecutor(false))
|
.execute(EntityExecutor(false))
|
||||||
// From cause
|
// From cause
|
||||||
.then(
|
.then(
|
||||||
literal("from").then(
|
literal("from").then(
|
||||||
argument(ARG_CAUSE, EntityArgumentConsumer)
|
argument(ARG_CAUSE, EntityArgumentConsumer)
|
||||||
.execute(DamageEntityExecutor(true)),
|
.execute(EntityExecutor(true)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -15,10 +15,10 @@ const NAMES: [&str; 1] = ["deop"];
|
|||||||
const DESCRIPTION: &str = "Revokes operator status from a player.";
|
const DESCRIPTION: &str = "Revokes operator status from a player.";
|
||||||
const ARG_TARGETS: &str = "targets";
|
const ARG_TARGETS: &str = "targets";
|
||||||
|
|
||||||
struct DeopExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for DeopExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -61,5 +61,5 @@ impl CommandExecutor for DeopExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_TARGETS, PlayersArgumentConsumer).execute(DeopExecutor))
|
.then(argument(ARG_TARGETS, PlayersArgumentConsumer).execute(Executor))
|
||||||
}
|
}
|
||||||
|
|||||||
100
pumpkin/src/command/commands/effect.rs
Normal file
100
pumpkin/src/command/commands/effect.rs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
use crate::command::args::resource::effect::EffectTypeArgumentConsumer;
|
||||||
|
|
||||||
|
use crate::TextComponent;
|
||||||
|
|
||||||
|
use crate::command::args::players::PlayersArgumentConsumer;
|
||||||
|
|
||||||
|
use crate::command::args::{Arg, ConsumedArgs};
|
||||||
|
use crate::command::dispatcher::CommandError;
|
||||||
|
use crate::command::dispatcher::CommandError::InvalidConsumption;
|
||||||
|
use crate::command::tree::CommandTree;
|
||||||
|
use crate::command::tree::builder::{argument, literal};
|
||||||
|
use crate::command::{CommandExecutor, CommandSender};
|
||||||
|
use crate::server::Server;
|
||||||
|
|
||||||
|
const NAMES: [&str; 1] = ["effect"];
|
||||||
|
|
||||||
|
const DESCRIPTION: &str = "Adds or removes the status effects of players and other entities.";
|
||||||
|
|
||||||
|
// const ARG_CLEAR: &str = "clear";
|
||||||
|
const ARG_GIVE: &str = "give";
|
||||||
|
|
||||||
|
const ARG_TARGET: &str = "target";
|
||||||
|
const ARG_EFFECT: &str = "effect";
|
||||||
|
|
||||||
|
struct GiveExecutor;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl CommandExecutor for GiveExecutor {
|
||||||
|
async fn execute<'a>(
|
||||||
|
&self,
|
||||||
|
sender: &mut CommandSender<'a>,
|
||||||
|
_server: &Server,
|
||||||
|
args: &ConsumedArgs<'a>,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
let Some(Arg::Players(targets)) = args.get(ARG_TARGET) else {
|
||||||
|
return Err(InvalidConsumption(Some(ARG_TARGET.into())));
|
||||||
|
};
|
||||||
|
let Some(Arg::Effect(effect)) = args.get(ARG_EFFECT) else {
|
||||||
|
return Err(InvalidConsumption(Some(ARG_EFFECT.into())));
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_count = targets.len();
|
||||||
|
|
||||||
|
for target in targets {
|
||||||
|
target
|
||||||
|
.add_effect(
|
||||||
|
crate::entity::effect::Effect {
|
||||||
|
r#type: *effect,
|
||||||
|
duration: 30,
|
||||||
|
amplifier: 1,
|
||||||
|
ambient: true,
|
||||||
|
show_particles: true,
|
||||||
|
show_icon: true,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
let translation_name =
|
||||||
|
TextComponent::translate(format!("effect.minecraft.{}", effect.to_name()), []);
|
||||||
|
if target_count == 1 {
|
||||||
|
// TODO: use entity name
|
||||||
|
sender
|
||||||
|
.send_message(TextComponent::translate(
|
||||||
|
"commands.effect.give.success.single",
|
||||||
|
[
|
||||||
|
translation_name,
|
||||||
|
TextComponent::text(targets[0].gameprofile.name.clone()),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
} else {
|
||||||
|
sender
|
||||||
|
.send_message(TextComponent::translate(
|
||||||
|
"commands.effect.give.success.multiple",
|
||||||
|
[
|
||||||
|
translation_name,
|
||||||
|
TextComponent::text(target_count.to_string()),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::redundant_closure_for_method_calls)]
|
||||||
|
pub fn init_command_tree() -> CommandTree {
|
||||||
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
|
literal(ARG_GIVE).then(
|
||||||
|
argument(ARG_TARGET, PlayersArgumentConsumer)
|
||||||
|
.then(argument(ARG_EFFECT, EffectTypeArgumentConsumer).execute(GiveExecutor)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// TODO: Add more things
|
||||||
|
}
|
||||||
@ -38,12 +38,12 @@ enum ExpType {
|
|||||||
Levels,
|
Levels,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExperienceExecutor {
|
struct Executor {
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
exp_type: Option<ExpType>,
|
exp_type: Option<ExpType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExperienceExecutor {
|
impl Executor {
|
||||||
async fn handle_query(
|
async fn handle_query(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'_>,
|
sender: &mut CommandSender<'_>,
|
||||||
@ -202,7 +202,7 @@ impl ExperienceExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for ExperienceExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -281,15 +281,15 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
literal("add").then(
|
literal("add").then(
|
||||||
argument(ARG_TARGETS, PlayersArgumentConsumer).then(
|
argument(ARG_TARGETS, PlayersArgumentConsumer).then(
|
||||||
argument(ARG_AMOUNT, xp_amount())
|
argument(ARG_AMOUNT, xp_amount())
|
||||||
.then(literal("levels").execute(ExperienceExecutor {
|
.then(literal("levels").execute(Executor {
|
||||||
mode: Mode::Add,
|
mode: Mode::Add,
|
||||||
exp_type: Some(ExpType::Levels),
|
exp_type: Some(ExpType::Levels),
|
||||||
}))
|
}))
|
||||||
.then(literal("points").execute(ExperienceExecutor {
|
.then(literal("points").execute(Executor {
|
||||||
mode: Mode::Add,
|
mode: Mode::Add,
|
||||||
exp_type: Some(ExpType::Points),
|
exp_type: Some(ExpType::Points),
|
||||||
}))
|
}))
|
||||||
.execute(ExperienceExecutor {
|
.execute(Executor {
|
||||||
mode: Mode::Add,
|
mode: Mode::Add,
|
||||||
exp_type: Some(ExpType::Points),
|
exp_type: Some(ExpType::Points),
|
||||||
}),
|
}),
|
||||||
@ -300,15 +300,15 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
literal("set").then(
|
literal("set").then(
|
||||||
argument(ARG_TARGETS, PlayersArgumentConsumer).then(
|
argument(ARG_TARGETS, PlayersArgumentConsumer).then(
|
||||||
argument(ARG_AMOUNT, xp_amount())
|
argument(ARG_AMOUNT, xp_amount())
|
||||||
.then(literal("levels").execute(ExperienceExecutor {
|
.then(literal("levels").execute(Executor {
|
||||||
mode: Mode::Set,
|
mode: Mode::Set,
|
||||||
exp_type: Some(ExpType::Levels),
|
exp_type: Some(ExpType::Levels),
|
||||||
}))
|
}))
|
||||||
.then(literal("points").execute(ExperienceExecutor {
|
.then(literal("points").execute(Executor {
|
||||||
mode: Mode::Set,
|
mode: Mode::Set,
|
||||||
exp_type: Some(ExpType::Points),
|
exp_type: Some(ExpType::Points),
|
||||||
}))
|
}))
|
||||||
.execute(ExperienceExecutor {
|
.execute(Executor {
|
||||||
mode: Mode::Set,
|
mode: Mode::Set,
|
||||||
exp_type: Some(ExpType::Points),
|
exp_type: Some(ExpType::Points),
|
||||||
}),
|
}),
|
||||||
@ -318,11 +318,11 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
.then(
|
.then(
|
||||||
literal("query").then(
|
literal("query").then(
|
||||||
argument(ARG_TARGETS, PlayersArgumentConsumer)
|
argument(ARG_TARGETS, PlayersArgumentConsumer)
|
||||||
.then(literal("levels").execute(ExperienceExecutor {
|
.then(literal("levels").execute(Executor {
|
||||||
mode: Mode::Query,
|
mode: Mode::Query,
|
||||||
exp_type: Some(ExpType::Levels),
|
exp_type: Some(ExpType::Levels),
|
||||||
}))
|
}))
|
||||||
.then(literal("points").execute(ExperienceExecutor {
|
.then(literal("points").execute(Executor {
|
||||||
mode: Mode::Query,
|
mode: Mode::Query,
|
||||||
exp_type: Some(ExpType::Points),
|
exp_type: Some(ExpType::Points),
|
||||||
})),
|
})),
|
||||||
|
|||||||
@ -33,11 +33,11 @@ enum Mode {
|
|||||||
Replace,
|
Replace,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetblockExecutor(Mode);
|
struct Executor(Mode);
|
||||||
|
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for SetblockExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -164,12 +164,12 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
argument(ARG_FROM, BlockPosArgumentConsumer).then(
|
argument(ARG_FROM, BlockPosArgumentConsumer).then(
|
||||||
argument(ARG_TO, BlockPosArgumentConsumer).then(
|
argument(ARG_TO, BlockPosArgumentConsumer).then(
|
||||||
argument(ARG_BLOCK, BlockArgumentConsumer)
|
argument(ARG_BLOCK, BlockArgumentConsumer)
|
||||||
.then(literal("destroy").execute(SetblockExecutor(Mode::Destroy)))
|
.then(literal("destroy").execute(Executor(Mode::Destroy)))
|
||||||
.then(literal("hollow").execute(SetblockExecutor(Mode::Hollow)))
|
.then(literal("hollow").execute(Executor(Mode::Hollow)))
|
||||||
.then(literal("keep").execute(SetblockExecutor(Mode::Keep)))
|
.then(literal("keep").execute(Executor(Mode::Keep)))
|
||||||
.then(literal("outline").execute(SetblockExecutor(Mode::Outline)))
|
.then(literal("outline").execute(Executor(Mode::Outline)))
|
||||||
.then(literal("replace").execute(SetblockExecutor(Mode::Replace)))
|
.then(literal("replace").execute(Executor(Mode::Replace)))
|
||||||
.execute(SetblockExecutor(Mode::Replace)),
|
.execute(Executor(Mode::Replace)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -23,10 +23,10 @@ const DESCRIPTION: &str = "Change a player's gamemode.";
|
|||||||
const ARG_GAMEMODE: &str = "gamemode";
|
const ARG_GAMEMODE: &str = "gamemode";
|
||||||
const ARG_TARGET: &str = "target";
|
const ARG_TARGET: &str = "target";
|
||||||
|
|
||||||
struct GamemodeTargetSelf;
|
struct TargetSelfExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for GamemodeTargetSelf {
|
impl CommandExecutor for TargetSelfExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -56,10 +56,10 @@ impl CommandExecutor for GamemodeTargetSelf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GamemodeTargetPlayer;
|
struct TargetPlayerExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for GamemodeTargetPlayer {
|
impl CommandExecutor for TargetPlayerExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -108,7 +108,7 @@ impl CommandExecutor for GamemodeTargetPlayer {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_GAMEMODE, GamemodeArgumentConsumer)
|
argument(ARG_GAMEMODE, GamemodeArgumentConsumer)
|
||||||
.then(require(|sender| sender.is_player()).execute(GamemodeTargetSelf))
|
.then(require(|sender| sender.is_player()).execute(TargetSelfExecutor))
|
||||||
.then(argument(ARG_TARGET, PlayersArgumentConsumer).execute(GamemodeTargetPlayer)),
|
.then(argument(ARG_TARGET, PlayersArgumentConsumer).execute(TargetPlayerExecutor)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,8 @@ use pumpkin_util::text::color::{Color, NamedColor};
|
|||||||
use pumpkin_util::text::hover::HoverEvent;
|
use pumpkin_util::text::hover::HoverEvent;
|
||||||
|
|
||||||
use crate::command::args::bounded_num::BoundedNumArgumentConsumer;
|
use crate::command::args::bounded_num::BoundedNumArgumentConsumer;
|
||||||
use crate::command::args::item::ItemArgumentConsumer;
|
|
||||||
use crate::command::args::players::PlayersArgumentConsumer;
|
use crate::command::args::players::PlayersArgumentConsumer;
|
||||||
|
use crate::command::args::resource::item::ItemArgumentConsumer;
|
||||||
use crate::command::args::{ConsumedArgs, FindArg, FindArgDefaultName};
|
use crate::command::args::{ConsumedArgs, FindArg, FindArgDefaultName};
|
||||||
use crate::command::tree::CommandTree;
|
use crate::command::tree::CommandTree;
|
||||||
use crate::command::tree::builder::{argument, argument_default_name};
|
use crate::command::tree::builder::{argument, argument_default_name};
|
||||||
@ -25,10 +25,10 @@ fn item_count_consumer() -> BoundedNumArgumentConsumer<i32> {
|
|||||||
.max(i32::MAX)
|
.max(i32::MAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GiveExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for GiveExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -112,8 +112,8 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument_default_name(PlayersArgumentConsumer).then(
|
argument_default_name(PlayersArgumentConsumer).then(
|
||||||
argument(ARG_ITEM, ItemArgumentConsumer)
|
argument(ARG_ITEM, ItemArgumentConsumer)
|
||||||
.execute(GiveExecutor)
|
.execute(Executor)
|
||||||
.then(argument_default_name(item_count_consumer()).execute(GiveExecutor)),
|
.then(argument_default_name(item_count_consumer()).execute(Executor)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,10 @@ fn page_number_consumer() -> BoundedNumArgumentConsumer<i32> {
|
|||||||
BoundedNumArgumentConsumer::new().name("page").min(1)
|
BoundedNumArgumentConsumer::new().name("page").min(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CommandHelpExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for CommandHelpExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -222,7 +222,7 @@ impl CommandExecutor for BaseHelpExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_COMMAND, CommandTreeArgumentConsumer).execute(CommandHelpExecutor))
|
.then(argument(ARG_COMMAND, CommandTreeArgumentConsumer).execute(Executor))
|
||||||
.then(argument_default_name(page_number_consumer()).execute(BaseHelpExecutor))
|
.then(argument_default_name(page_number_consumer()).execute(BaseHelpExecutor))
|
||||||
.execute(BaseHelpExecutor)
|
.execute(BaseHelpExecutor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,10 +18,10 @@ const ARG_TARGETS: &str = "targets";
|
|||||||
|
|
||||||
const ARG_REASON: &str = "reason";
|
const ARG_REASON: &str = "reason";
|
||||||
|
|
||||||
struct KickExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for KickExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -52,7 +52,7 @@ impl CommandExecutor for KickExecutor {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_TARGETS, PlayersArgumentConsumer)
|
argument(ARG_TARGETS, PlayersArgumentConsumer)
|
||||||
.execute(KickExecutor)
|
.execute(Executor)
|
||||||
.then(argument(ARG_REASON, MsgArgConsumer).execute(KickExecutor)),
|
.then(argument(ARG_REASON, MsgArgConsumer).execute(Executor)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ const DESCRIPTION: &str = "Kills all target entities.";
|
|||||||
|
|
||||||
const ARG_TARGET: &str = "target";
|
const ARG_TARGET: &str = "target";
|
||||||
|
|
||||||
struct KillExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for KillExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -66,10 +66,10 @@ impl CommandExecutor for KillExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KillSelfExecutor;
|
struct SelfExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for KillSelfExecutor {
|
impl CommandExecutor for SelfExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -104,6 +104,6 @@ impl CommandExecutor for KillSelfExecutor {
|
|||||||
#[allow(clippy::redundant_closure_for_method_calls)] // causes lifetime issues
|
#[allow(clippy::redundant_closure_for_method_calls)] // causes lifetime issues
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_TARGET, EntitiesArgumentConsumer).execute(KillExecutor))
|
.then(argument(ARG_TARGET, EntitiesArgumentConsumer).execute(Executor))
|
||||||
.then(require(|sender| sender.is_player()).execute(KillSelfExecutor))
|
.then(require(|sender| sender.is_player()).execute(SelfExecutor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,10 +15,10 @@ const NAMES: [&str; 1] = ["list"];
|
|||||||
|
|
||||||
const DESCRIPTION: &str = "Print the list of online players.";
|
const DESCRIPTION: &str = "Print the list of online players.";
|
||||||
|
|
||||||
struct ListExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for ListExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -54,5 +54,5 @@ fn get_player_names(players: Vec<Arc<Player>>) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).execute(ListExecutor)
|
CommandTree::new(NAMES, DESCRIPTION).execute(Executor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ const DESCRIPTION: &str = "Broadcasts a narrative message about yourself.";
|
|||||||
|
|
||||||
const ARG_MESSAGE: &str = "action";
|
const ARG_MESSAGE: &str = "action";
|
||||||
|
|
||||||
struct MeExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for MeExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -44,5 +44,5 @@ impl CommandExecutor for MeExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_MESSAGE, MsgArgConsumer).execute(MeExecutor))
|
.then(argument(ARG_MESSAGE, MsgArgConsumer).execute(Executor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,90 @@
|
|||||||
pub mod ban;
|
use pumpkin_util::PermissionLvl;
|
||||||
pub mod banip;
|
|
||||||
pub mod banlist;
|
use super::dispatcher::CommandDispatcher;
|
||||||
pub mod bossbar;
|
|
||||||
pub mod clear;
|
mod ban;
|
||||||
pub mod damage;
|
mod banip;
|
||||||
pub mod deop;
|
mod banlist;
|
||||||
pub mod experience;
|
mod bossbar;
|
||||||
pub mod fill;
|
mod clear;
|
||||||
pub mod gamemode;
|
mod damage;
|
||||||
pub mod give;
|
mod deop;
|
||||||
pub mod help;
|
mod effect;
|
||||||
pub mod kick;
|
mod experience;
|
||||||
pub mod kill;
|
mod fill;
|
||||||
pub mod list;
|
mod gamemode;
|
||||||
pub mod me;
|
mod give;
|
||||||
pub mod msg;
|
mod help;
|
||||||
pub mod op;
|
mod kick;
|
||||||
pub mod pardon;
|
mod kill;
|
||||||
pub mod pardonip;
|
mod list;
|
||||||
pub mod particle;
|
mod me;
|
||||||
pub mod playsound;
|
mod msg;
|
||||||
pub mod plugin;
|
mod op;
|
||||||
pub mod plugins;
|
mod pardon;
|
||||||
pub mod pumpkin;
|
mod pardonip;
|
||||||
pub mod say;
|
mod particle;
|
||||||
pub mod seed;
|
mod playsound;
|
||||||
pub mod setblock;
|
mod plugin;
|
||||||
pub mod stop;
|
mod plugins;
|
||||||
pub mod summon;
|
mod pumpkin;
|
||||||
pub mod teleport;
|
mod say;
|
||||||
pub mod time;
|
mod seed;
|
||||||
pub mod title;
|
mod setblock;
|
||||||
pub mod transfer;
|
mod stop;
|
||||||
pub mod weather;
|
mod summon;
|
||||||
pub mod worldborder;
|
mod teleport;
|
||||||
|
mod time;
|
||||||
|
mod title;
|
||||||
|
mod transfer;
|
||||||
|
mod weather;
|
||||||
|
mod worldborder;
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn default_dispatcher() -> CommandDispatcher {
|
||||||
|
let mut dispatcher = CommandDispatcher::default();
|
||||||
|
|
||||||
|
// Zero
|
||||||
|
dispatcher.register(pumpkin::init_command_tree(), PermissionLvl::Zero);
|
||||||
|
dispatcher.register(help::init_command_tree(), PermissionLvl::Zero);
|
||||||
|
dispatcher.register(list::init_command_tree(), PermissionLvl::Zero);
|
||||||
|
dispatcher.register(transfer::init_command_tree(), PermissionLvl::Zero);
|
||||||
|
dispatcher.register(me::init_command_tree(), PermissionLvl::Zero);
|
||||||
|
dispatcher.register(msg::init_command_tree(), PermissionLvl::Zero);
|
||||||
|
// Two
|
||||||
|
dispatcher.register(kill::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(worldborder::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(effect::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(teleport::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(time::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(give::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(clear::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(setblock::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(seed::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(fill::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(playsound::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(title::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(summon::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(experience::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(weather::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(particle::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(damage::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(bossbar::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(say::init_command_tree(), PermissionLvl::Two);
|
||||||
|
dispatcher.register(gamemode::init_command_tree(), PermissionLvl::Two);
|
||||||
|
// Three
|
||||||
|
dispatcher.register(op::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(deop::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(kick::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(plugin::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(plugins::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(ban::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(banip::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(banlist::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(pardon::init_command_tree(), PermissionLvl::Three);
|
||||||
|
dispatcher.register(pardonip::init_command_tree(), PermissionLvl::Three);
|
||||||
|
// Four
|
||||||
|
dispatcher.register(stop::init_command_tree(), PermissionLvl::Four);
|
||||||
|
|
||||||
|
dispatcher
|
||||||
|
}
|
||||||
|
|||||||
@ -19,10 +19,10 @@ const DESCRIPTION: &str = "Sends a private message to one or more players.";
|
|||||||
|
|
||||||
const ARG_MESSAGE: &str = "message";
|
const ARG_MESSAGE: &str = "message";
|
||||||
|
|
||||||
struct MsgExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for MsgExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -81,6 +81,6 @@ impl CommandExecutor for MsgExecutor {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument_default_name(PlayersArgumentConsumer)
|
argument_default_name(PlayersArgumentConsumer)
|
||||||
.then(argument(ARG_MESSAGE, MsgArgConsumer).execute(MsgExecutor)),
|
.then(argument(ARG_MESSAGE, MsgArgConsumer).execute(Executor)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ const NAMES: [&str; 1] = ["op"];
|
|||||||
const DESCRIPTION: &str = "Grants operator status to a player.";
|
const DESCRIPTION: &str = "Grants operator status to a player.";
|
||||||
const ARG_TARGETS: &str = "targets";
|
const ARG_TARGETS: &str = "targets";
|
||||||
|
|
||||||
struct OpExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for OpExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -81,5 +81,5 @@ impl CommandExecutor for OpExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_TARGETS, PlayersArgumentConsumer).execute(OpExecutor))
|
.then(argument(ARG_TARGETS, PlayersArgumentConsumer).execute(Executor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ const DESCRIPTION: &str = "unbans a player";
|
|||||||
|
|
||||||
const ARG_TARGET: &str = "player";
|
const ARG_TARGET: &str = "player";
|
||||||
|
|
||||||
struct PardonExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for PardonExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -60,5 +60,5 @@ impl CommandExecutor for PardonExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_TARGET, SimpleArgConsumer).execute(PardonExecutor))
|
.then(argument(ARG_TARGET, SimpleArgConsumer).execute(Executor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,10 +18,10 @@ const DESCRIPTION: &str = "unbans a ip";
|
|||||||
|
|
||||||
const ARG_TARGET: &str = "ip";
|
const ARG_TARGET: &str = "ip";
|
||||||
|
|
||||||
struct PardonIpExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for PardonIpExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -64,5 +64,5 @@ impl CommandExecutor for PardonIpExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_TARGET, SimpleArgConsumer).execute(PardonIpExecutor))
|
.then(argument(ARG_TARGET, SimpleArgConsumer).execute(Executor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::command::{
|
|||||||
CommandError, CommandExecutor, CommandSender,
|
CommandError, CommandExecutor, CommandSender,
|
||||||
args::{
|
args::{
|
||||||
ConsumedArgs, FindArg, bounded_num::BoundedNumArgumentConsumer,
|
ConsumedArgs, FindArg, bounded_num::BoundedNumArgumentConsumer,
|
||||||
particle::ParticleArgumentConsumer, position_3d::Position3DArgumentConsumer,
|
position_3d::Position3DArgumentConsumer, resource::particle::ParticleArgumentConsumer,
|
||||||
},
|
},
|
||||||
tree::{CommandTree, builder::argument},
|
tree::{CommandTree, builder::argument},
|
||||||
};
|
};
|
||||||
@ -20,10 +20,10 @@ const ARG_DELTA: &str = "delta";
|
|||||||
const ARG_SPEED: &str = "speed";
|
const ARG_SPEED: &str = "speed";
|
||||||
const ARG_COUNT: &str = "count";
|
const ARG_COUNT: &str = "count";
|
||||||
|
|
||||||
struct ParticleExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for ParticleExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -64,25 +64,25 @@ impl CommandExecutor for ParticleExecutor {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_NAME, ParticleArgumentConsumer)
|
argument(ARG_NAME, ParticleArgumentConsumer)
|
||||||
.execute(ParticleExecutor)
|
.execute(Executor)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_POS, Position3DArgumentConsumer)
|
argument(ARG_POS, Position3DArgumentConsumer)
|
||||||
.execute(ParticleExecutor)
|
.execute(Executor)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_DELTA, Position3DArgumentConsumer)
|
argument(ARG_DELTA, Position3DArgumentConsumer)
|
||||||
.execute(ParticleExecutor)
|
.execute(Executor)
|
||||||
.then(
|
.then(
|
||||||
argument(
|
argument(
|
||||||
ARG_SPEED,
|
ARG_SPEED,
|
||||||
BoundedNumArgumentConsumer::<f32>::new().min(0.0),
|
BoundedNumArgumentConsumer::<f32>::new().min(0.0),
|
||||||
)
|
)
|
||||||
.execute(ParticleExecutor)
|
.execute(Executor)
|
||||||
.then(
|
.then(
|
||||||
argument(
|
argument(
|
||||||
ARG_COUNT,
|
ARG_COUNT,
|
||||||
BoundedNumArgumentConsumer::<i32>::new().min(0),
|
BoundedNumArgumentConsumer::<i32>::new().min(0),
|
||||||
)
|
)
|
||||||
.execute(ParticleExecutor),
|
.execute(Executor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -57,10 +57,10 @@ fn min_volume_consumer() -> BoundedNumArgumentConsumer<f32> {
|
|||||||
.max(1.0)
|
.max(1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SoundExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for SoundExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -183,18 +183,18 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
ARG_MIN_VOLUME,
|
ARG_MIN_VOLUME,
|
||||||
min_volume_consumer(),
|
min_volume_consumer(),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
.execute(SoundExecutor),
|
.execute(Executor),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,10 +12,10 @@ const NAMES: [&str; 1] = ["plugins"];
|
|||||||
|
|
||||||
const DESCRIPTION: &str = "List all available plugins.";
|
const DESCRIPTION: &str = "List all available plugins.";
|
||||||
|
|
||||||
struct ListExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for ListExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -63,5 +63,5 @@ impl CommandExecutor for ListExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).execute(ListExecutor)
|
CommandTree::new(NAMES, DESCRIPTION).execute(Executor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,13 +17,13 @@ const NAMES: [&str; 2] = ["pumpkin", "version"];
|
|||||||
|
|
||||||
const DESCRIPTION: &str = "Display information about Pumpkin.";
|
const DESCRIPTION: &str = "Display information about Pumpkin.";
|
||||||
|
|
||||||
struct PumpkinExecutor;
|
struct Executor;
|
||||||
|
|
||||||
const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
const CARGO_PKG_DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
|
const CARGO_PKG_DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for PumpkinExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -98,5 +98,5 @@ impl CommandExecutor for PumpkinExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).execute(PumpkinExecutor)
|
CommandTree::new(NAMES, DESCRIPTION).execute(Executor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@ const DESCRIPTION: &str = "Broadcast a message to all Players.";
|
|||||||
|
|
||||||
const ARG_MESSAGE: &str = "message";
|
const ARG_MESSAGE: &str = "message";
|
||||||
|
|
||||||
struct SayExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for SayExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -44,5 +44,5 @@ impl CommandExecutor for SayExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_MESSAGE, MsgArgConsumer).execute(SayExecutor))
|
.then(argument(ARG_MESSAGE, MsgArgConsumer).execute(Executor))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,10 +11,10 @@ const NAMES: [&str; 1] = ["seed"];
|
|||||||
|
|
||||||
const DESCRIPTION: &str = "Displays the world seed.";
|
const DESCRIPTION: &str = "Displays the world seed.";
|
||||||
|
|
||||||
struct PumpkinExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for PumpkinExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -54,5 +54,5 @@ impl CommandExecutor for PumpkinExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).execute(PumpkinExecutor)
|
CommandTree::new(NAMES, DESCRIPTION).execute(Executor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,10 +27,10 @@ enum Mode {
|
|||||||
Replace,
|
Replace,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetblockExecutor(Mode);
|
struct Executor(Mode);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for SetblockExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -90,10 +90,10 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_BLOCK_POS, BlockPosArgumentConsumer).then(
|
argument(ARG_BLOCK_POS, BlockPosArgumentConsumer).then(
|
||||||
argument(ARG_BLOCK, BlockArgumentConsumer)
|
argument(ARG_BLOCK, BlockArgumentConsumer)
|
||||||
.then(literal("replace").execute(SetblockExecutor(Mode::Replace)))
|
.then(literal("replace").execute(Executor(Mode::Replace)))
|
||||||
.then(literal("destroy").execute(SetblockExecutor(Mode::Destroy)))
|
.then(literal("destroy").execute(Executor(Mode::Destroy)))
|
||||||
.then(literal("keep").execute(SetblockExecutor(Mode::Keep)))
|
.then(literal("keep").execute(Executor(Mode::Keep)))
|
||||||
.execute(SetblockExecutor(Mode::Replace)),
|
.execute(Executor(Mode::Replace)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,10 +11,10 @@ const NAMES: [&str; 1] = ["stop"];
|
|||||||
|
|
||||||
const DESCRIPTION: &str = "Stop the server.";
|
const DESCRIPTION: &str = "Stop the server.";
|
||||||
|
|
||||||
struct StopExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for StopExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -32,5 +32,5 @@ impl CommandExecutor for StopExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).execute(StopExecutor)
|
CommandTree::new(NAMES, DESCRIPTION).execute(Executor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,10 +21,10 @@ const ARG_ENTITY: &str = "entity";
|
|||||||
|
|
||||||
const ARG_POS: &str = "pos";
|
const ARG_POS: &str = "pos";
|
||||||
|
|
||||||
struct SummonExecutor;
|
struct Executor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for SummonExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -54,8 +54,8 @@ impl CommandExecutor for SummonExecutor {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_ENTITY, SummonableEntitiesArgumentConsumer)
|
argument(ARG_ENTITY, SummonableEntitiesArgumentConsumer)
|
||||||
.execute(SummonExecutor)
|
.execute(Executor)
|
||||||
.then(argument(ARG_POS, Position3DArgumentConsumer).execute(SummonExecutor)),
|
.then(argument(ARG_POS, Position3DArgumentConsumer).execute(Executor)),
|
||||||
// TODO: Add NBT
|
// TODO: Add NBT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,10 +49,10 @@ fn yaw_pitch_facing_position(
|
|||||||
(yaw_degrees as f32, pitch_degrees as f32)
|
(yaw_degrees as f32, pitch_degrees as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpEntitiesToEntityExecutor;
|
struct EntitiesToEntityExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpEntitiesToEntityExecutor {
|
impl CommandExecutor for EntitiesToEntityExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
_sender: &mut CommandSender<'a>,
|
_sender: &mut CommandSender<'a>,
|
||||||
@ -74,10 +74,10 @@ impl CommandExecutor for TpEntitiesToEntityExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpEntitiesToPosFacingPosExecutor;
|
struct EntitiesToPosFacingPosExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpEntitiesToPosFacingPosExecutor {
|
impl CommandExecutor for EntitiesToPosFacingPosExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
_sender: &mut CommandSender<'a>,
|
_sender: &mut CommandSender<'a>,
|
||||||
@ -99,10 +99,10 @@ impl CommandExecutor for TpEntitiesToPosFacingPosExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpEntitiesToPosFacingEntityExecutor;
|
struct EntitiesToPosFacingEntityExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpEntitiesToPosFacingEntityExecutor {
|
impl CommandExecutor for EntitiesToPosFacingEntityExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
_sender: &mut CommandSender<'a>,
|
_sender: &mut CommandSender<'a>,
|
||||||
@ -126,10 +126,10 @@ impl CommandExecutor for TpEntitiesToPosFacingEntityExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpEntitiesToPosWithRotationExecutor;
|
struct EntitiesToPosWithRotationExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpEntitiesToPosWithRotationExecutor {
|
impl CommandExecutor for EntitiesToPosWithRotationExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
_sender: &mut CommandSender<'a>,
|
_sender: &mut CommandSender<'a>,
|
||||||
@ -150,10 +150,10 @@ impl CommandExecutor for TpEntitiesToPosWithRotationExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpEntitiesToPosExecutor;
|
struct EntitiesToPosExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpEntitiesToPosExecutor {
|
impl CommandExecutor for EntitiesToPosExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
_sender: &mut CommandSender<'a>,
|
_sender: &mut CommandSender<'a>,
|
||||||
@ -174,10 +174,10 @@ impl CommandExecutor for TpEntitiesToPosExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpSelfToEntityExecutor;
|
struct SelfToEntityExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpSelfToEntityExecutor {
|
impl CommandExecutor for SelfToEntityExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -204,10 +204,10 @@ impl CommandExecutor for TpSelfToEntityExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TpSelfToPosExecutor;
|
struct SelfToPosExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TpSelfToPosExecutor {
|
impl CommandExecutor for SelfToPosExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -234,34 +234,34 @@ impl CommandExecutor for TpSelfToPosExecutor {
|
|||||||
|
|
||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(argument(ARG_LOCATION, Position3DArgumentConsumer).execute(TpSelfToPosExecutor))
|
.then(argument(ARG_LOCATION, Position3DArgumentConsumer).execute(SelfToPosExecutor))
|
||||||
.then(argument(ARG_DESTINATION, EntityArgumentConsumer).execute(TpSelfToEntityExecutor))
|
.then(argument(ARG_DESTINATION, EntityArgumentConsumer).execute(SelfToEntityExecutor))
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_TARGETS, EntitiesArgumentConsumer)
|
argument(ARG_TARGETS, EntitiesArgumentConsumer)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_LOCATION, Position3DArgumentConsumer)
|
argument(ARG_LOCATION, Position3DArgumentConsumer)
|
||||||
.execute(TpEntitiesToPosExecutor)
|
.execute(EntitiesToPosExecutor)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_ROTATION, RotationArgumentConsumer)
|
argument(ARG_ROTATION, RotationArgumentConsumer)
|
||||||
.execute(TpEntitiesToPosWithRotationExecutor),
|
.execute(EntitiesToPosWithRotationExecutor),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("facing")
|
literal("facing")
|
||||||
.then(
|
.then(
|
||||||
literal("entity").then(
|
literal("entity").then(
|
||||||
argument(ARG_FACING_ENTITY, EntityArgumentConsumer)
|
argument(ARG_FACING_ENTITY, EntityArgumentConsumer)
|
||||||
.execute(TpEntitiesToPosFacingEntityExecutor),
|
.execute(EntitiesToPosFacingEntityExecutor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_FACING_LOCATION, Position3DArgumentConsumer)
|
argument(ARG_FACING_LOCATION, Position3DArgumentConsumer)
|
||||||
.execute(TpEntitiesToPosFacingPosExecutor),
|
.execute(EntitiesToPosFacingPosExecutor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_DESTINATION, EntityArgumentConsumer)
|
argument(ARG_DESTINATION, EntityArgumentConsumer)
|
||||||
.execute(TpEntitiesToEntityExecutor),
|
.execute(EntitiesToEntityExecutor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,10 +44,10 @@ enum QueryMode {
|
|||||||
Day,
|
Day,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimeQueryExecutor(QueryMode);
|
struct QueryExecutor(QueryMode);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TimeQueryExecutor {
|
impl CommandExecutor for QueryExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -91,10 +91,10 @@ impl CommandExecutor for TimeQueryExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimeChangeExecutor(Mode);
|
struct ChangeExecutor(Mode);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TimeChangeExecutor {
|
impl CommandExecutor for ChangeExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -153,33 +153,27 @@ impl CommandExecutor for TimeChangeExecutor {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION)
|
CommandTree::new(NAMES, DESCRIPTION)
|
||||||
.then(
|
.then(
|
||||||
literal("add").then(
|
literal("add")
|
||||||
argument(ARG_TIME, TimeArgumentConsumer).execute(TimeChangeExecutor(Mode::Add)),
|
.then(argument(ARG_TIME, TimeArgumentConsumer).execute(ChangeExecutor(Mode::Add))),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("query")
|
literal("query")
|
||||||
.then(literal("daytime").execute(TimeQueryExecutor(QueryMode::DayTime)))
|
.then(literal("daytime").execute(QueryExecutor(QueryMode::DayTime)))
|
||||||
.then(literal("gametime").execute(TimeQueryExecutor(QueryMode::GameTime)))
|
.then(literal("gametime").execute(QueryExecutor(QueryMode::GameTime)))
|
||||||
.then(literal("day").execute(TimeQueryExecutor(QueryMode::Day))),
|
.then(literal("day").execute(QueryExecutor(QueryMode::Day))),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("set")
|
literal("set")
|
||||||
.then(literal("day").execute(TimeChangeExecutor(Mode::Set(Some(PresetTime::Day)))))
|
.then(literal("day").execute(ChangeExecutor(Mode::Set(Some(PresetTime::Day)))))
|
||||||
.then(
|
.then(literal("noon").execute(ChangeExecutor(Mode::Set(Some(PresetTime::Noon)))))
|
||||||
literal("noon").execute(TimeChangeExecutor(Mode::Set(Some(PresetTime::Noon)))),
|
.then(literal("night").execute(ChangeExecutor(Mode::Set(Some(PresetTime::Night)))))
|
||||||
)
|
|
||||||
.then(
|
|
||||||
literal("night")
|
|
||||||
.execute(TimeChangeExecutor(Mode::Set(Some(PresetTime::Night)))),
|
|
||||||
)
|
|
||||||
.then(
|
.then(
|
||||||
literal("midnight")
|
literal("midnight")
|
||||||
.execute(TimeChangeExecutor(Mode::Set(Some(PresetTime::Midnight)))),
|
.execute(ChangeExecutor(Mode::Set(Some(PresetTime::Midnight)))),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_TIME, TimeArgumentConsumer)
|
argument(ARG_TIME, TimeArgumentConsumer)
|
||||||
.execute(TimeChangeExecutor(Mode::Set(None))),
|
.execute(ChangeExecutor(Mode::Set(None))),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,10 +29,10 @@ fn port_consumer() -> BoundedNumArgumentConsumer<i32> {
|
|||||||
.max(65535)
|
.max(65535)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TransferTargetSelf;
|
struct TargetSelfExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TransferTargetSelf {
|
impl CommandExecutor for TargetSelfExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -71,10 +71,10 @@ impl CommandExecutor for TransferTargetSelf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TransferTargetPlayer;
|
struct TargetPlayerExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for TransferTargetPlayer {
|
impl CommandExecutor for TargetPlayerExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -121,13 +121,13 @@ impl CommandExecutor for TransferTargetPlayer {
|
|||||||
pub fn init_command_tree() -> CommandTree {
|
pub fn init_command_tree() -> CommandTree {
|
||||||
CommandTree::new(NAMES, DESCRIPTION).then(
|
CommandTree::new(NAMES, DESCRIPTION).then(
|
||||||
argument(ARG_HOSTNAME, SimpleArgConsumer)
|
argument(ARG_HOSTNAME, SimpleArgConsumer)
|
||||||
.then(require(|sender| sender.is_player()).execute(TransferTargetSelf))
|
.then(require(|sender| sender.is_player()).execute(TargetSelfExecutor))
|
||||||
.then(
|
.then(
|
||||||
argument_default_name(port_consumer())
|
argument_default_name(port_consumer())
|
||||||
.then(require(|sender| sender.is_player()).execute(TransferTargetSelf))
|
.then(require(|sender| sender.is_player()).execute(TargetSelfExecutor))
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_PLAYERS, PlayersArgumentConsumer)
|
argument(ARG_PLAYERS, PlayersArgumentConsumer)
|
||||||
.execute(TransferTargetPlayer),
|
.execute(TargetPlayerExecutor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ const NAMES: [&str; 1] = ["weather"];
|
|||||||
const DESCRIPTION: &str = "Changes the weather.";
|
const DESCRIPTION: &str = "Changes the weather.";
|
||||||
const ARG_DURATION: &str = "duration";
|
const ARG_DURATION: &str = "duration";
|
||||||
|
|
||||||
struct WeatherExecutor {
|
struct Executor {
|
||||||
mode: WeatherMode,
|
mode: WeatherMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ enum WeatherMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WeatherExecutor {
|
impl CommandExecutor for Executor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -73,33 +73,33 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
.then(
|
.then(
|
||||||
literal("clear")
|
literal("clear")
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_DURATION, TimeArgumentConsumer).execute(WeatherExecutor {
|
argument(ARG_DURATION, TimeArgumentConsumer).execute(Executor {
|
||||||
mode: WeatherMode::Clear,
|
mode: WeatherMode::Clear,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.execute(WeatherExecutor {
|
.execute(Executor {
|
||||||
mode: WeatherMode::Clear,
|
mode: WeatherMode::Clear,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("rain")
|
literal("rain")
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_DURATION, TimeArgumentConsumer).execute(WeatherExecutor {
|
argument(ARG_DURATION, TimeArgumentConsumer).execute(Executor {
|
||||||
mode: WeatherMode::Rain,
|
mode: WeatherMode::Rain,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.execute(WeatherExecutor {
|
.execute(Executor {
|
||||||
mode: WeatherMode::Rain,
|
mode: WeatherMode::Rain,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("thunder")
|
literal("thunder")
|
||||||
.then(
|
.then(
|
||||||
argument(ARG_DURATION, TimeArgumentConsumer).execute(WeatherExecutor {
|
argument(ARG_DURATION, TimeArgumentConsumer).execute(Executor {
|
||||||
mode: WeatherMode::Thunder,
|
mode: WeatherMode::Thunder,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.execute(WeatherExecutor {
|
.execute(Executor {
|
||||||
mode: WeatherMode::Thunder,
|
mode: WeatherMode::Thunder,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -48,10 +48,10 @@ fn warning_distance_consumer() -> BoundedNumArgumentConsumer<i32> {
|
|||||||
BoundedNumArgumentConsumer::new().min(0).name("distance")
|
BoundedNumArgumentConsumer::new().min(0).name("distance")
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderGetExecutor;
|
struct GetExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderGetExecutor {
|
impl CommandExecutor for GetExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -76,10 +76,10 @@ impl CommandExecutor for WorldborderGetExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderSetExecutor;
|
struct SetExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderSetExecutor {
|
impl CommandExecutor for SetExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -128,10 +128,10 @@ impl CommandExecutor for WorldborderSetExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderSetTimeExecutor;
|
struct SetTimeExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderSetTimeExecutor {
|
impl CommandExecutor for SetTimeExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -213,10 +213,10 @@ impl CommandExecutor for WorldborderSetTimeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderAddExecutor;
|
struct AddExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderAddExecutor {
|
impl CommandExecutor for AddExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -267,10 +267,10 @@ impl CommandExecutor for WorldborderAddExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderAddTimeExecutor;
|
struct AddTimeExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderAddTimeExecutor {
|
impl CommandExecutor for AddTimeExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -354,10 +354,10 @@ impl CommandExecutor for WorldborderAddTimeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderCenterExecutor;
|
struct CenterExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderCenterExecutor {
|
impl CommandExecutor for CenterExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -387,10 +387,10 @@ impl CommandExecutor for WorldborderCenterExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderDamageAmountExecutor;
|
struct DamageAmountExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderDamageAmountExecutor {
|
impl CommandExecutor for DamageAmountExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -439,10 +439,10 @@ impl CommandExecutor for WorldborderDamageAmountExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderDamageBufferExecutor;
|
struct DamageBufferExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderDamageBufferExecutor {
|
impl CommandExecutor for DamageBufferExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -491,10 +491,10 @@ impl CommandExecutor for WorldborderDamageBufferExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderWarningDistanceExecutor;
|
struct WarningDistanceExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderWarningDistanceExecutor {
|
impl CommandExecutor for WarningDistanceExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -542,10 +542,10 @@ impl CommandExecutor for WorldborderWarningDistanceExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldborderWarningTimeExecutor;
|
struct WarningTimeExecutor;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CommandExecutor for WorldborderWarningTimeExecutor {
|
impl CommandExecutor for WarningTimeExecutor {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
&self,
|
&self,
|
||||||
sender: &mut CommandSender<'a>,
|
sender: &mut CommandSender<'a>,
|
||||||
@ -598,38 +598,32 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
.then(
|
.then(
|
||||||
literal("add").then(
|
literal("add").then(
|
||||||
argument_default_name(distance_consumer())
|
argument_default_name(distance_consumer())
|
||||||
.execute(WorldborderAddExecutor)
|
.execute(AddExecutor)
|
||||||
.then(
|
.then(argument_default_name(time_consumer()).execute(AddTimeExecutor)),
|
||||||
argument_default_name(time_consumer()).execute(WorldborderAddTimeExecutor),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(literal("center").then(
|
.then(
|
||||||
argument_default_name(Position2DArgumentConsumer).execute(WorldborderCenterExecutor),
|
literal("center")
|
||||||
))
|
.then(argument_default_name(Position2DArgumentConsumer).execute(CenterExecutor)),
|
||||||
|
)
|
||||||
.then(
|
.then(
|
||||||
literal("damage")
|
literal("damage")
|
||||||
.then(
|
.then(
|
||||||
literal("amount").then(
|
literal("amount").then(
|
||||||
argument_default_name(damage_per_block_consumer())
|
argument_default_name(damage_per_block_consumer())
|
||||||
.execute(WorldborderDamageAmountExecutor),
|
.execute(DamageAmountExecutor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(literal("buffer").then(
|
||||||
literal("buffer").then(
|
argument_default_name(damage_buffer_consumer()).execute(DamageBufferExecutor),
|
||||||
argument_default_name(damage_buffer_consumer())
|
)),
|
||||||
.execute(WorldborderDamageBufferExecutor),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.then(literal("get").execute(WorldborderGetExecutor))
|
.then(literal("get").execute(GetExecutor))
|
||||||
.then(
|
.then(
|
||||||
literal("set").then(
|
literal("set").then(
|
||||||
argument_default_name(distance_consumer())
|
argument_default_name(distance_consumer())
|
||||||
.execute(WorldborderSetExecutor)
|
.execute(SetExecutor)
|
||||||
.then(
|
.then(argument_default_name(time_consumer()).execute(SetTimeExecutor)),
|
||||||
argument_default_name(time_consumer()).execute(WorldborderSetTimeExecutor),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
@ -637,11 +631,12 @@ pub fn init_command_tree() -> CommandTree {
|
|||||||
.then(
|
.then(
|
||||||
literal("distance").then(
|
literal("distance").then(
|
||||||
argument_default_name(warning_distance_consumer())
|
argument_default_name(warning_distance_consumer())
|
||||||
.execute(WorldborderWarningDistanceExecutor),
|
.execute(WarningDistanceExecutor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.then(literal("time").then(
|
.then(
|
||||||
argument_default_name(time_consumer()).execute(WorldborderWarningTimeExecutor),
|
literal("time")
|
||||||
)),
|
.then(argument_default_name(time_consumer()).execute(WarningTimeExecutor)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -349,7 +349,7 @@ impl CommandDispatcher {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::command::{default_dispatcher, tree::CommandTree};
|
use crate::command::{commands::default_dispatcher, tree::CommandTree};
|
||||||
use pumpkin_util::permission::PermissionLvl;
|
use pumpkin_util::permission::PermissionLvl;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dynamic_command() {
|
fn test_dynamic_command() {
|
||||||
|
|||||||
@ -1,19 +1,12 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::command::commands::seed;
|
|
||||||
use crate::command::commands::{bossbar, transfer};
|
|
||||||
use crate::command::dispatcher::CommandDispatcher;
|
|
||||||
use crate::entity::player::Player;
|
use crate::entity::player::Player;
|
||||||
use crate::server::Server;
|
use crate::server::Server;
|
||||||
use crate::world::World;
|
use crate::world::World;
|
||||||
use args::ConsumedArgs;
|
use args::ConsumedArgs;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use commands::{
|
|
||||||
ban, banip, banlist, clear, damage, deop, experience, fill, gamemode, give, help, kick, kill,
|
|
||||||
list, me, msg, op, pardon, pardonip, particle, playsound, plugin, plugins, pumpkin, say,
|
|
||||||
setblock, stop, summon, teleport, time, title, weather, worldborder,
|
|
||||||
};
|
|
||||||
use dispatcher::CommandError;
|
use dispatcher::CommandError;
|
||||||
use pumpkin_util::math::vector3::Vector3;
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
use pumpkin_util::permission::PermissionLvl;
|
use pumpkin_util::permission::PermissionLvl;
|
||||||
@ -21,7 +14,7 @@ use pumpkin_util::text::TextComponent;
|
|||||||
|
|
||||||
pub mod args;
|
pub mod args;
|
||||||
pub mod client_suggestions;
|
pub mod client_suggestions;
|
||||||
mod commands;
|
pub mod commands;
|
||||||
pub mod dispatcher;
|
pub mod dispatcher;
|
||||||
pub mod tree;
|
pub mod tree;
|
||||||
|
|
||||||
@ -106,54 +99,6 @@ impl CommandSender<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_dispatcher() -> CommandDispatcher {
|
|
||||||
let mut dispatcher = CommandDispatcher::default();
|
|
||||||
|
|
||||||
// Zero
|
|
||||||
dispatcher.register(pumpkin::init_command_tree(), PermissionLvl::Zero);
|
|
||||||
dispatcher.register(help::init_command_tree(), PermissionLvl::Zero);
|
|
||||||
dispatcher.register(list::init_command_tree(), PermissionLvl::Zero);
|
|
||||||
dispatcher.register(transfer::init_command_tree(), PermissionLvl::Zero);
|
|
||||||
dispatcher.register(me::init_command_tree(), PermissionLvl::Zero);
|
|
||||||
dispatcher.register(msg::init_command_tree(), PermissionLvl::Zero);
|
|
||||||
// Two
|
|
||||||
dispatcher.register(kill::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(worldborder::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(teleport::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(time::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(give::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(clear::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(setblock::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(seed::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(fill::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(playsound::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(title::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(summon::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(experience::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(weather::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(particle::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(damage::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(bossbar::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(say::init_command_tree(), PermissionLvl::Two);
|
|
||||||
dispatcher.register(gamemode::init_command_tree(), PermissionLvl::Two);
|
|
||||||
// Three
|
|
||||||
dispatcher.register(op::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(deop::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(kick::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(plugin::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(plugins::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(ban::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(banip::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(banlist::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(pardon::init_command_tree(), PermissionLvl::Three);
|
|
||||||
dispatcher.register(pardonip::init_command_tree(), PermissionLvl::Three);
|
|
||||||
// Four
|
|
||||||
dispatcher.register(stop::init_command_tree(), PermissionLvl::Four);
|
|
||||||
|
|
||||||
dispatcher
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait CommandExecutor: Sync {
|
pub trait CommandExecutor: Sync {
|
||||||
async fn execute<'a>(
|
async fn execute<'a>(
|
||||||
|
|||||||
11
pumpkin/src/entity/effect/mod.rs
Normal file
11
pumpkin/src/entity/effect/mod.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use pumpkin_data::entity::EffectType;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Hash, Clone)]
|
||||||
|
pub struct Effect {
|
||||||
|
pub r#type: EffectType,
|
||||||
|
pub duration: i32,
|
||||||
|
pub amplifier: u8,
|
||||||
|
pub ambient: bool,
|
||||||
|
pub show_particles: bool,
|
||||||
|
pub show_icon: bool,
|
||||||
|
}
|
||||||
@ -1,7 +1,8 @@
|
|||||||
use std::sync::atomic::AtomicI32;
|
use std::{collections::HashMap, sync::atomic::AtomicI32};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
|
use pumpkin_data::entity::EffectType;
|
||||||
use pumpkin_data::{damage::DamageType, sound::Sound};
|
use pumpkin_data::{damage::DamageType, sound::Sound};
|
||||||
use pumpkin_nbt::tag::NbtTag;
|
use pumpkin_nbt::tag::NbtTag;
|
||||||
use pumpkin_protocol::{
|
use pumpkin_protocol::{
|
||||||
@ -12,8 +13,9 @@ use pumpkin_protocol::{
|
|||||||
};
|
};
|
||||||
use pumpkin_util::math::vector3::Vector3;
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
use pumpkin_world::item::ItemStack;
|
use pumpkin_world::item::ItemStack;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use super::{Entity, EntityId, NBTStorage};
|
use super::{Entity, EntityId, NBTStorage, effect::Effect};
|
||||||
|
|
||||||
/// Represents a living entity within the game world.
|
/// Represents a living entity within the game world.
|
||||||
///
|
///
|
||||||
@ -31,9 +33,10 @@ pub struct LivingEntity {
|
|||||||
pub health: AtomicCell<f32>,
|
pub health: AtomicCell<f32>,
|
||||||
/// The distance the entity has been falling
|
/// The distance the entity has been falling
|
||||||
pub fall_distance: AtomicCell<f32>,
|
pub fall_distance: AtomicCell<f32>,
|
||||||
|
pub active_effects: Mutex<HashMap<EffectType, Effect>>,
|
||||||
}
|
}
|
||||||
impl LivingEntity {
|
impl LivingEntity {
|
||||||
pub const fn new(entity: Entity) -> Self {
|
pub fn new(entity: Entity) -> Self {
|
||||||
Self {
|
Self {
|
||||||
entity,
|
entity,
|
||||||
last_pos: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)),
|
last_pos: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)),
|
||||||
@ -41,6 +44,7 @@ impl LivingEntity {
|
|||||||
last_damage_taken: AtomicCell::new(0.0),
|
last_damage_taken: AtomicCell::new(0.0),
|
||||||
health: AtomicCell::new(20.0),
|
health: AtomicCell::new(20.0),
|
||||||
fall_distance: AtomicCell::new(0.0),
|
fall_distance: AtomicCell::new(0.0),
|
||||||
|
active_effects: Mutex::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +135,22 @@ impl LivingEntity {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn add_effect(&self, effect: Effect) {
|
||||||
|
let mut effects = self.active_effects.lock().await;
|
||||||
|
effects.insert(effect.r#type, effect);
|
||||||
|
// TODO broadcast metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn has_effect(&self, effect: EffectType) -> bool {
|
||||||
|
let effects = self.active_effects.lock().await;
|
||||||
|
effects.contains_key(&effect)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_effect(&self, effect: EffectType) -> Option<Effect> {
|
||||||
|
let effects = self.active_effects.lock().await;
|
||||||
|
effects.get(&effect).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn damage(&self, amount: f32, damage_type: DamageType) -> bool {
|
pub async fn damage(&self, amount: f32, damage_type: DamageType) -> bool {
|
||||||
self.damage_with_context(amount, damage_type, None, None, None)
|
self.damage_with_context(amount, damage_type, None, None, None)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -32,6 +32,7 @@ use tokio::sync::RwLock;
|
|||||||
use crate::world::World;
|
use crate::world::World;
|
||||||
|
|
||||||
pub mod ai;
|
pub mod ai;
|
||||||
|
pub mod effect;
|
||||||
pub mod hunger;
|
pub mod hunger;
|
||||||
pub mod item;
|
pub mod item;
|
||||||
pub mod living;
|
pub mod living;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use crossbeam::atomic::AtomicCell;
|
|||||||
use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG};
|
use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG};
|
||||||
use pumpkin_data::{
|
use pumpkin_data::{
|
||||||
damage::DamageType,
|
damage::DamageType,
|
||||||
entity::EntityType,
|
entity::{EffectType, EntityType},
|
||||||
item::Operation,
|
item::Operation,
|
||||||
particle::Particle,
|
particle::Particle,
|
||||||
sound::{Sound, SoundCategory},
|
sound::{Sound, SoundCategory},
|
||||||
@ -27,7 +27,8 @@ use pumpkin_protocol::{
|
|||||||
CAcknowledgeBlockChange, CActionBar, CCombatDeath, CDisguisedChatMessage, CEntityStatus,
|
CAcknowledgeBlockChange, CActionBar, CCombatDeath, CDisguisedChatMessage, CEntityStatus,
|
||||||
CGameEvent, CHurtAnimation, CKeepAlive, CParticle, CPlayDisconnect, CPlayerAbilities,
|
CGameEvent, CHurtAnimation, CKeepAlive, CParticle, CPlayDisconnect, CPlayerAbilities,
|
||||||
CPlayerInfoUpdate, CPlayerPosition, CRespawn, CSetExperience, CSetHealth, CSubtitle,
|
CPlayerInfoUpdate, CPlayerPosition, CRespawn, CSetExperience, CSetHealth, CSubtitle,
|
||||||
CSystemChatMessage, CTitleText, CUnloadChunk, GameEvent, MetaDataType, PlayerAction,
|
CSystemChatMessage, CTitleText, CUnloadChunk, CUpdateMobEffect, GameEvent, MetaDataType,
|
||||||
|
PlayerAction,
|
||||||
},
|
},
|
||||||
server::play::{
|
server::play::{
|
||||||
SChatCommand, SChatMessage, SClientCommand, SClientInformationPlay, SClientTickEnd,
|
SChatCommand, SChatMessage, SClientCommand, SClientInformationPlay, SClientTickEnd,
|
||||||
@ -66,6 +67,7 @@ use tokio::sync::{Mutex, Notify, RwLock};
|
|||||||
use super::{
|
use super::{
|
||||||
Entity, EntityBase, EntityId, NBTStorage,
|
Entity, EntityBase, EntityId, NBTStorage,
|
||||||
combat::{self, AttackType, player_attack_sound},
|
combat::{self, AttackType, player_attack_sound},
|
||||||
|
effect::Effect,
|
||||||
hunger::HungerManager,
|
hunger::HungerManager,
|
||||||
item::ItemEntity,
|
item::ItemEntity,
|
||||||
};
|
};
|
||||||
@ -958,13 +960,52 @@ impl Player {
|
|||||||
.await
|
.await
|
||||||
.get_mining_speed(block_name)
|
.get_mining_speed(block_name)
|
||||||
.await;
|
.await;
|
||||||
// TODO: Handle effects
|
// Haste
|
||||||
|
if self.living_entity.has_effect(EffectType::Haste).await
|
||||||
|
|| self
|
||||||
|
.living_entity
|
||||||
|
.has_effect(EffectType::ConduitPower)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
speed *= 1.0 + (self.get_haste_amplifier().await + 1) as f32 * 0.2;
|
||||||
|
}
|
||||||
|
// Fatigue
|
||||||
|
if let Some(fatigue) = self
|
||||||
|
.living_entity
|
||||||
|
.get_effect(EffectType::MiningFatigue)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
let fatigue_speed = match fatigue.amplifier {
|
||||||
|
0 => 0.3,
|
||||||
|
1 => 0.09,
|
||||||
|
2 => 0.0027,
|
||||||
|
_ => 8.1E-4,
|
||||||
|
};
|
||||||
|
speed *= fatigue_speed;
|
||||||
|
}
|
||||||
|
// TODO: Handle when in Water
|
||||||
if !self.living_entity.entity.on_ground.load(Ordering::Relaxed) {
|
if !self.living_entity.entity.on_ground.load(Ordering::Relaxed) {
|
||||||
speed /= 5.0;
|
speed /= 5.0;
|
||||||
}
|
}
|
||||||
speed
|
speed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_haste_amplifier(&self) -> u32 {
|
||||||
|
let mut i = 0;
|
||||||
|
let mut j = 0;
|
||||||
|
if let Some(effect) = self.living_entity.get_effect(EffectType::Haste).await {
|
||||||
|
i = effect.amplifier;
|
||||||
|
}
|
||||||
|
if let Some(effect) = self
|
||||||
|
.living_entity
|
||||||
|
.get_effect(EffectType::ConduitPower)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
j = effect.amplifier;
|
||||||
|
}
|
||||||
|
u32::from(i.max(j))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn send_message(
|
pub async fn send_message(
|
||||||
&self,
|
&self,
|
||||||
message: &TextComponent,
|
message: &TextComponent,
|
||||||
@ -1049,6 +1090,34 @@ impl Player {
|
|||||||
self.set_experience(new_level, progress, points).await;
|
self.set_experience(new_level, progress, points).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn add_effect(&self, effect: Effect, keep_fading: bool) {
|
||||||
|
let mut flag: i8 = 0;
|
||||||
|
|
||||||
|
if effect.ambient {
|
||||||
|
flag |= 1;
|
||||||
|
}
|
||||||
|
if effect.show_particles {
|
||||||
|
flag |= 2;
|
||||||
|
}
|
||||||
|
if effect.show_icon {
|
||||||
|
flag |= 4;
|
||||||
|
}
|
||||||
|
if keep_fading {
|
||||||
|
flag |= 8;
|
||||||
|
}
|
||||||
|
let effect_id = VarInt(effect.r#type as i32);
|
||||||
|
self.client
|
||||||
|
.send_packet(&CUpdateMobEffect::new(
|
||||||
|
self.entity_id().into(),
|
||||||
|
effect_id,
|
||||||
|
effect.amplifier.into(),
|
||||||
|
effect.duration.into(),
|
||||||
|
flag,
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
self.living_entity.add_effect(effect).await;
|
||||||
|
}
|
||||||
|
|
||||||
/// Add experience levels to the player
|
/// Add experience levels to the player
|
||||||
pub async fn add_experience_levels(&self, added_levels: i32) {
|
pub async fn add_experience_levels(&self, added_levels: i32) {
|
||||||
let current_level = self.experience_level.load(Ordering::Relaxed);
|
let current_level = self.experience_level.load(Ordering::Relaxed);
|
||||||
|
|||||||
@ -31,15 +31,13 @@ use tokio::sync::{Mutex, RwLock};
|
|||||||
use crate::block::default_block_properties_manager;
|
use crate::block::default_block_properties_manager;
|
||||||
use crate::block::properties::BlockPropertiesManager;
|
use crate::block::properties::BlockPropertiesManager;
|
||||||
use crate::block::registry::BlockRegistry;
|
use crate::block::registry::BlockRegistry;
|
||||||
|
use crate::command::commands::default_dispatcher;
|
||||||
use crate::entity::{Entity, EntityId};
|
use crate::entity::{Entity, EntityId};
|
||||||
use crate::item::registry::ItemRegistry;
|
use crate::item::registry::ItemRegistry;
|
||||||
use crate::net::EncryptionError;
|
use crate::net::EncryptionError;
|
||||||
use crate::world::custom_bossbar::CustomBossbars;
|
use crate::world::custom_bossbar::CustomBossbars;
|
||||||
use crate::{
|
use crate::{
|
||||||
command::{default_dispatcher, dispatcher::CommandDispatcher},
|
command::dispatcher::CommandDispatcher, entity::player::Player, net::Client, world::World,
|
||||||
entity::player::Player,
|
|
||||||
net::Client,
|
|
||||||
world::World,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod connection_cache;
|
mod connection_cache;
|
||||||
|
|||||||
@ -101,8 +101,8 @@ impl PumpkinError for GetBlockError {
|
|||||||
/// **Key Responsibilities:**
|
/// **Key Responsibilities:**
|
||||||
///
|
///
|
||||||
/// - Manages the `Level` instance for handling chunk-related operations.
|
/// - Manages the `Level` instance for handling chunk-related operations.
|
||||||
/// - Stores and tracks active `Player` entities within the world.
|
/// - Active players and entities.
|
||||||
/// - Provides a central hub for interacting with the world's entities and environment.
|
/// - World-related systems like the scoreboard, world border, weather, and time.
|
||||||
pub struct World {
|
pub struct World {
|
||||||
/// The underlying level, responsible for chunk management and terrain generation.
|
/// The underlying level, responsible for chunk management and terrain generation.
|
||||||
pub level: Arc<Level>,
|
pub level: Arc<Level>,
|
||||||
@ -121,7 +121,6 @@ pub struct World {
|
|||||||
pub dimension_type: DimensionType,
|
pub dimension_type: DimensionType,
|
||||||
/// The world's weather, including rain and thunder levels
|
/// The world's weather, including rain and thunder levels
|
||||||
pub weather: Mutex<Weather>,
|
pub weather: Mutex<Weather>,
|
||||||
// TODO: entities
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user