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:
parent
ad6da947cd
commit
7ad4b22726
6 changed files with 68 additions and 13 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -212,9 +212,11 @@ dependencies = [
|
|||
"azalea-physics",
|
||||
"azalea-protocol",
|
||||
"azalea-world",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nohash-hasher",
|
||||
"parking_lot",
|
||||
"regex",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"typemap_rev",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>>,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue