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?
133async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
134 let swarm = bot.resource::<SwarmState>();
135
136 match event {
137 azalea::Event::Init => {
138 bot.set_client_information(ClientInformation {
139 view_distance: 32,
140 ..Default::default()
141 });
142 if swarm.args.pathfinder_debug_particles {
143 bot.ecs
144 .write()
145 .entity_mut(bot.entity)
146 .insert(PathfinderDebugParticles);
147 }
148 }
149 azalea::Event::Chat(chat) => {
150 let (Some(username), content) = chat.split_sender_and_content() else {
151 return Ok(());
152 };
153 if username != swarm.args.owner_username {
154 return Ok(());
155 }
156
157 println!("{:?}", chat.message());
158
159 let command = if chat.is_whisper() {
160 Some(content)
161 } else {
162 content.strip_prefix('!').map(|s| s.to_owned())
163 };
164 if let Some(command) = command {
165 match swarm.commands.execute(
166 command,
167 Mutex::new(CommandSource {
168 bot: bot.clone(),
169 chat: chat.clone(),
170 state: state.clone(),
171 }),
172 ) {
173 Ok(_) => {}
174 Err(err) => {
175 eprintln!("{err:?}");
176 let command_source = CommandSource {
177 bot,
178 chat: chat.clone(),
179 state: state.clone(),
180 };
181 command_source.reply(format!("{err:?}"));
182 }
183 }
184 }
185 }
186 azalea::Event::Tick => {
187 killaura::tick(bot.clone(), state.clone())?;
188
189 let task = *state.task.lock();
190 match task {
191 BotTask::None => {}
192 }
193 }
194 azalea::Event::Login => {
195 println!("Got login event")
196 }
197 _ => {}
198 }
199
200 Ok(())
201}
202async fn swarm_handle(_swarm: Swarm, event: SwarmEvent, _state: SwarmState) -> anyhow::Result<()> {
203 match &event {
204 SwarmEvent::Disconnect(account, _join_opts) => {
205 println!("bot got kicked! {}", account.username());
206 }
207 SwarmEvent::Chat(chat) => {
208 if chat.message().to_string() == "The particle was not visible for anybody" {
209 return Ok(());
210 }
211 println!("{}", chat.message().to_ansi());
212 }
213 _ => {}
214 }
215
216 Ok(())
217}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
133async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
134 let swarm = bot.resource::<SwarmState>();
135
136 match event {
137 azalea::Event::Init => {
138 bot.set_client_information(ClientInformation {
139 view_distance: 32,
140 ..Default::default()
141 });
142 if swarm.args.pathfinder_debug_particles {
143 bot.ecs
144 .write()
145 .entity_mut(bot.entity)
146 .insert(PathfinderDebugParticles);
147 }
148 }
149 azalea::Event::Chat(chat) => {
150 let (Some(username), content) = chat.split_sender_and_content() else {
151 return Ok(());
152 };
153 if username != swarm.args.owner_username {
154 return Ok(());
155 }
156
157 println!("{:?}", chat.message());
158
159 let command = if chat.is_whisper() {
160 Some(content)
161 } else {
162 content.strip_prefix('!').map(|s| s.to_owned())
163 };
164 if let Some(command) = command {
165 match swarm.commands.execute(
166 command,
167 Mutex::new(CommandSource {
168 bot: bot.clone(),
169 chat: chat.clone(),
170 state: state.clone(),
171 }),
172 ) {
173 Ok(_) => {}
174 Err(err) => {
175 eprintln!("{err:?}");
176 let command_source = CommandSource {
177 bot,
178 chat: chat.clone(),
179 state: state.clone(),
180 };
181 command_source.reply(format!("{err:?}"));
182 }
183 }
184 }
185 }
186 azalea::Event::Tick => {
187 killaura::tick(bot.clone(), state.clone())?;
188
189 let task = *state.task.lock();
190 match task {
191 BotTask::None => {}
192 }
193 }
194 azalea::Event::Login => {
195 println!("Got login event")
196 }
197 _ => {}
198 }
199
200 Ok(())
201}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?
23 pub fn reply(&self, message: impl Into<String>) {
24 let message = message.into();
25 if self.chat.is_whisper() {
26 self.bot
27 .chat(format!("/w {} {message}", self.chat.sender().unwrap()));
28 } else {
29 self.bot.chat(message);
30 }
31 }
32
33 pub fn entity(&self) -> Option<azalea::EntityRef> {
34 let username = self.chat.sender()?;
35 self.bot
36 .any_entity_by::<&GameProfileComponent, With<Player>>(
37 |profile: &GameProfileComponent| profile.name == username,
38 )
39 }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
133async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
134 let swarm = bot.resource::<SwarmState>();
135
136 match event {
137 azalea::Event::Init => {
138 bot.set_client_information(ClientInformation {
139 view_distance: 32,
140 ..Default::default()
141 });
142 if swarm.args.pathfinder_debug_particles {
143 bot.ecs
144 .write()
145 .entity_mut(bot.entity)
146 .insert(PathfinderDebugParticles);
147 }
148 }
149 azalea::Event::Chat(chat) => {
150 let (Some(username), content) = chat.split_sender_and_content() else {
151 return Ok(());
152 };
153 if username != swarm.args.owner_username {
154 return Ok(());
155 }
156
157 println!("{:?}", chat.message());
158
159 let command = if chat.is_whisper() {
160 Some(content)
161 } else {
162 content.strip_prefix('!').map(|s| s.to_owned())
163 };
164 if let Some(command) = command {
165 match swarm.commands.execute(
166 command,
167 Mutex::new(CommandSource {
168 bot: bot.clone(),
169 chat: chat.clone(),
170 state: state.clone(),
171 }),
172 ) {
173 Ok(_) => {}
174 Err(err) => {
175 eprintln!("{err:?}");
176 let command_source = CommandSource {
177 bot,
178 chat: chat.clone(),
179 state: state.clone(),
180 };
181 command_source.reply(format!("{err:?}"));
182 }
183 }
184 }
185 }
186 azalea::Event::Tick => {
187 killaura::tick(bot.clone(), state.clone())?;
188
189 let task = *state.task.lock();
190 match task {
191 BotTask::None => {}
192 }
193 }
194 azalea::Event::Login => {
195 println!("Got login event")
196 }
197 _ => {}
198 }
199
200 Ok(())
201}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.