Enum ChatPacket
pub enum ChatPacket {
System(Arc<ClientboundSystemChat>),
Player(Arc<ClientboundPlayerChat>),
Disguised(Arc<ClientboundDisguisedChat>),
}Expand description
A chat packet, either a system message or a chat message.
Variants§
System(Arc<ClientboundSystemChat>)
Player(Arc<ClientboundPlayerChat>)
Disguised(Arc<ClientboundDisguisedChat>)
Implementations§
§impl ChatPacket
impl ChatPacket
pub fn message(&self) -> FormattedText
pub fn message(&self) -> FormattedText
Get the message shown in chat for this packet.
See Self::split_sender_and_content for more details about how this
works.
Examples found in repository?
121async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
122 let swarm = bot.resource::<SwarmState>();
123
124 match event {
125 azalea::Event::Init => {
126 bot.set_client_information(ClientInformation {
127 view_distance: 32,
128 ..Default::default()
129 });
130 if swarm.args.pathfinder_debug_particles {
131 bot.ecs
132 .lock()
133 .entity_mut(bot.entity)
134 .insert(PathfinderDebugParticles);
135 }
136 }
137 azalea::Event::Chat(chat) => {
138 let (Some(username), content) = chat.split_sender_and_content() else {
139 return Ok(());
140 };
141 if username != swarm.args.owner_username {
142 return Ok(());
143 }
144
145 println!("{:?}", chat.message());
146
147 let command = if chat.is_whisper() {
148 Some(content)
149 } else {
150 content.strip_prefix('!').map(|s| s.to_owned())
151 };
152 if let Some(command) = command {
153 match swarm.commands.execute(
154 command,
155 Mutex::new(CommandSource {
156 bot: bot.clone(),
157 chat: chat.clone(),
158 state: state.clone(),
159 }),
160 ) {
161 Ok(_) => {}
162 Err(err) => {
163 eprintln!("{err:?}");
164 let command_source = CommandSource {
165 bot,
166 chat: chat.clone(),
167 state: state.clone(),
168 };
169 command_source.reply(format!("{err:?}"));
170 }
171 }
172 }
173 }
174 azalea::Event::Tick => {
175 killaura::tick(bot.clone(), state.clone())?;
176
177 let task = *state.task.lock();
178 match task {
179 BotTask::None => {}
180 }
181 }
182 azalea::Event::Login => {
183 println!("Got login event")
184 }
185 _ => {}
186 }
187
188 Ok(())
189}
190async fn swarm_handle(_swarm: Swarm, event: SwarmEvent, _state: SwarmState) -> anyhow::Result<()> {
191 match &event {
192 SwarmEvent::Disconnect(account, _join_opts) => {
193 println!("bot got kicked! {}", account.username);
194 }
195 SwarmEvent::Chat(chat) => {
196 if chat.message().to_string() == "The particle was not visible for anybody" {
197 return Ok(());
198 }
199 println!("{}", chat.message().to_ansi());
200 }
201 _ => {}
202 }
203
204 Ok(())
205}pub fn split_sender_and_content(&self) -> (Option<String>, String)
pub fn split_sender_and_content(&self) -> (Option<String>, String)
A convenience function to determine the username of the sender and the content of a chat message.
This does not preserve formatting codes.
This function uses a few checks to attempt to split the chat message, and is intended to work on most servers. It won’t work for every server though, so in certain cases you may have to reimplement this yourself.
If it’s not a player-sent chat message or the sender couldn’t be determined, the username part will be None.
Also see Self::sender and Self::content if you only need one of
the parts.
Examples found in repository?
19async fn handle(bot: Client, event: Event, _state: State) -> anyhow::Result<()> {
20 if let Event::Chat(m) = event
21 && let (Some(sender), content) = m.split_sender_and_content()
22 {
23 if sender == bot.username() {
24 // ignore our own messages
25 return Ok(());
26 }
27 bot.chat(content);
28 }
29
30 Ok(())
31}More examples
121async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
122 let swarm = bot.resource::<SwarmState>();
123
124 match event {
125 azalea::Event::Init => {
126 bot.set_client_information(ClientInformation {
127 view_distance: 32,
128 ..Default::default()
129 });
130 if swarm.args.pathfinder_debug_particles {
131 bot.ecs
132 .lock()
133 .entity_mut(bot.entity)
134 .insert(PathfinderDebugParticles);
135 }
136 }
137 azalea::Event::Chat(chat) => {
138 let (Some(username), content) = chat.split_sender_and_content() else {
139 return Ok(());
140 };
141 if username != swarm.args.owner_username {
142 return Ok(());
143 }
144
145 println!("{:?}", chat.message());
146
147 let command = if chat.is_whisper() {
148 Some(content)
149 } else {
150 content.strip_prefix('!').map(|s| s.to_owned())
151 };
152 if let Some(command) = command {
153 match swarm.commands.execute(
154 command,
155 Mutex::new(CommandSource {
156 bot: bot.clone(),
157 chat: chat.clone(),
158 state: state.clone(),
159 }),
160 ) {
161 Ok(_) => {}
162 Err(err) => {
163 eprintln!("{err:?}");
164 let command_source = CommandSource {
165 bot,
166 chat: chat.clone(),
167 state: state.clone(),
168 };
169 command_source.reply(format!("{err:?}"));
170 }
171 }
172 }
173 }
174 azalea::Event::Tick => {
175 killaura::tick(bot.clone(), state.clone())?;
176
177 let task = *state.task.lock();
178 match task {
179 BotTask::None => {}
180 }
181 }
182 azalea::Event::Login => {
183 println!("Got login event")
184 }
185 _ => {}
186 }
187
188 Ok(())
189}pub fn sender(&self) -> Option<String>
pub fn sender(&self) -> Option<String>
Get the username of the sender of the message.
If it’s not a player-sent chat message or the sender couldn’t be determined, this will be None.
See Self::split_sender_and_content for more details about how this
works.
Examples found in repository?
22 pub fn reply(&self, message: impl Into<String>) {
23 let message = message.into();
24 if self.chat.is_whisper() {
25 self.bot
26 .chat(format!("/w {} {message}", self.chat.sender().unwrap()));
27 } else {
28 self.bot.chat(message);
29 }
30 }
31
32 pub fn entity(&mut self) -> Option<Entity> {
33 let username = self.chat.sender()?;
34 self.bot
35 .any_entity_by::<&GameProfileComponent, With<Player>>(
36 |profile: &GameProfileComponent| profile.name == username,
37 )
38 }More examples
27async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
28 if let Event::Chat(m) = event {
29 if m.sender() == Some(bot.username()) {
30 return Ok(());
31 };
32 if m.content() != "go" {
33 return Ok(());
34 }
35
36 steal(bot, state).await?;
37 }
38
39 Ok(())
40}pub fn sender_uuid(&self) -> Option<Uuid>
pub fn sender_uuid(&self) -> Option<Uuid>
Get the UUID of the sender of the message.
If it’s not a player-sent chat message, this will be None (this is sometimes the case when a server uses a plugin to modify chat messages).
pub fn content(&self) -> String
pub fn content(&self) -> String
Get the content part of the message as a string.
This does not preserve formatting codes. If it’s not a player-sent chat message or the sender couldn’t be determined, this will contain the entire message.
Examples found in repository?
27async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
28 if let Event::Chat(m) = event {
29 if m.sender() == Some(bot.username()) {
30 return Ok(());
31 };
32 if m.content() != "go" {
33 return Ok(());
34 }
35
36 steal(bot, state).await?;
37 }
38
39 Ok(())
40}pub fn new(message: &str) -> ChatPacket
pub fn new(message: &str) -> ChatPacket
Create a new ChatPacket from a string. This is meant to be used as a
convenience function for testing.
pub fn is_whisper(&self) -> bool
pub fn is_whisper(&self) -> bool
Whether this message is an incoming whisper message (i.e. someone else messaged the bot with /msg).
This is not guaranteed to work correctly on custom servers.
Examples found in repository?
More examples
121async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
122 let swarm = bot.resource::<SwarmState>();
123
124 match event {
125 azalea::Event::Init => {
126 bot.set_client_information(ClientInformation {
127 view_distance: 32,
128 ..Default::default()
129 });
130 if swarm.args.pathfinder_debug_particles {
131 bot.ecs
132 .lock()
133 .entity_mut(bot.entity)
134 .insert(PathfinderDebugParticles);
135 }
136 }
137 azalea::Event::Chat(chat) => {
138 let (Some(username), content) = chat.split_sender_and_content() else {
139 return Ok(());
140 };
141 if username != swarm.args.owner_username {
142 return Ok(());
143 }
144
145 println!("{:?}", chat.message());
146
147 let command = if chat.is_whisper() {
148 Some(content)
149 } else {
150 content.strip_prefix('!').map(|s| s.to_owned())
151 };
152 if let Some(command) = command {
153 match swarm.commands.execute(
154 command,
155 Mutex::new(CommandSource {
156 bot: bot.clone(),
157 chat: chat.clone(),
158 state: state.clone(),
159 }),
160 ) {
161 Ok(_) => {}
162 Err(err) => {
163 eprintln!("{err:?}");
164 let command_source = CommandSource {
165 bot,
166 chat: chat.clone(),
167 state: state.clone(),
168 };
169 command_source.reply(format!("{err:?}"));
170 }
171 }
172 }
173 }
174 azalea::Event::Tick => {
175 killaura::tick(bot.clone(), state.clone())?;
176
177 let task = *state.task.lock();
178 match task {
179 BotTask::None => {}
180 }
181 }
182 azalea::Event::Login => {
183 println!("Got login event")
184 }
185 _ => {}
186 }
187
188 Ok(())
189}Trait Implementations§
§impl Clone for ChatPacket
impl Clone for ChatPacket
§fn clone(&self) -> ChatPacket
fn clone(&self) -> ChatPacket
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more§impl Debug for ChatPacket
impl Debug for ChatPacket
§impl PartialEq for ChatPacket
impl PartialEq for ChatPacket
impl StructuralPartialEq for ChatPacket
Auto Trait Implementations§
impl Freeze for ChatPacket
impl RefUnwindSafe for ChatPacket
impl Send for ChatPacket
impl Sync for ChatPacket
impl Unpin for ChatPacket
impl UnwindSafe for ChatPacket
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.