1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

Add functions to get ChatPacket author and content (#42)

* Add functions to get ChatPacket author and content

* add ChatPacket::username and ChatPacket::content
This commit is contained in:
mat 2022-11-18 21:52:09 -06:00 committed by GitHub
parent ad6da947cd
commit 7ad4b22726
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 13 deletions

2
Cargo.lock generated
View file

@ -212,9 +212,11 @@ dependencies = [
"azalea-physics",
"azalea-protocol",
"azalea-world",
"lazy_static",
"log",
"nohash-hasher",
"parking_lot",
"regex",
"thiserror",
"tokio",
"typemap_rev",

View file

@ -19,9 +19,11 @@ azalea-crypto = {path = "../azalea-crypto", version = "0.3.0"}
azalea-physics = {path = "../azalea-physics", version = "0.3.0"}
azalea-protocol = {path = "../azalea-protocol", version = "0.3.0"}
azalea-world = {path = "../azalea-world", version = "0.3.0"}
lazy_static = "1.4.0"
log = "0.4.17"
nohash-hasher = "0.2.0"
parking_lot = {version = "^0.12.1", features = ["deadlock_detection"]}
regex = "1.7.0"
thiserror = "^1.0.34"
tokio = {version = "^1.21.2", features = ["sync"]}
typemap_rev = "0.2.0"

View file

@ -9,6 +9,8 @@ use azalea_protocol::packets::game::{
serverbound_chat_command_packet::ServerboundChatCommandPacket,
serverbound_chat_packet::ServerboundChatPacket,
};
use lazy_static::lazy_static;
use regex::Regex;
use std::time::{SystemTime, UNIX_EPOCH};
/// A chat packet, either a system message or a chat message.
@ -26,6 +28,53 @@ impl ChatPacket {
ChatPacket::Player(p) => p.message(false),
}
}
/// Determine the username of the sender and content of the message. This
/// does not preserve formatting codes. If it's not a player-sent chat
/// message or the sender couldn't be determined, the username part will be
/// None.
pub fn split_sender_and_content(&self) -> (Option<String>, String) {
match self {
ChatPacket::Player(p) => (
// If it's a player chat packet, then the sender and content
// are already split for us.
Some(p.chat_type.name.to_string()),
p.message.content(false).to_string(),
),
ChatPacket::System(p) => {
let message = p.content.to_string();
// Overlay messages aren't in chat
if p.overlay {
return (None, message);
}
// It's a system message, so we'll have to match the content
// with regex
lazy_static! {
static ref ANGLE_BRACKETS_RE: Regex =
Regex::new("^<([a-zA-Z_0-9]{1,16})> (.+)$").unwrap();
}
if let Some(m) = ANGLE_BRACKETS_RE.captures(&message) {
return (Some(m[1].to_string()), m[2].to_string());
}
(None, message)
}
}
}
/// 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.
pub fn username(&self) -> Option<String> {
self.split_sender_and_content().0
}
/// 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.
pub fn content(&self) -> String {
self.split_sender_and_content().1
}
}
impl Client {

View file

@ -64,7 +64,7 @@ pub enum Event {
/// A player that you control that is currently in a Minecraft server.
#[derive(Clone)]
pub struct Client {
game_profile: GameProfile,
pub game_profile: GameProfile,
pub read_conn: Arc<tokio::sync::Mutex<ReadConnection<ClientboundGamePacket>>>,
pub write_conn: Arc<tokio::sync::Mutex<WriteConnection<ServerboundGamePacket>>>,
pub player: Arc<RwLock<Player>>,

View file

@ -27,17 +27,17 @@ async fn main() {
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
match event {
Event::Chat(m) => {
if m.username == bot.player.username {
if m.username() == Some(bot.game_profile.name) {
return Ok(());
};
if m.content == "go" {
// make sure we only start once
let ctx_lock = ctx.lock().unwrap();
if ctx_lock.started {
return;
};
ctx_lock.started = true;
drop(ctx_lock);
if m.content() == "go" {
{
// make sure we only start once
if *state.started.lock() {
return Ok(());
};
*state.started.lock() = true;
}
bot.goto(pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0)))
.await;

View file

@ -24,10 +24,12 @@ pub struct State {}
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
match event {
Event::Chat(m) => {
if m.username == bot.username {
return Ok(()); // ignore our own messages
if let (Some(sender), content) = m.split_sender_and_content() {
if sender == bot.game_profile.name {
return Ok(()); // ignore our own messages
}
bot.chat(&content).await?;
};
bot.chat(m.content).await;
}
_ => {}
}