Clientbound chat

This commit is contained in:
Garen Tyler 2021-03-17 22:41:40 -06:00
parent c4c7e069b9
commit bdc56326c0
3 changed files with 89 additions and 0 deletions

View File

@ -205,6 +205,38 @@ pub mod other {
pub struct MCChat {
pub text: MCString,
}
impl From<&str> for MCChat {
fn from(s: &str) -> MCChat {
MCChat { text: s.into() }
}
}
impl From<String> for MCChat {
fn from(s: String) -> MCChat {
MCChat {
text: s.clone().into(),
}
}
}
impl Into<String> for MCChat {
fn into(self) -> String {
self.text.value
}
}
impl PartialEq<&str> for MCChat {
fn eq(&self, other: &&str) -> bool {
self.text.value == **other
}
}
impl PartialEq<String> for MCChat {
fn eq(&self, other: &String) -> bool {
self.text.value == *other
}
}
impl PartialEq<&String> for MCChat {
fn eq(&self, other: &&String) -> bool {
self.text.value == **other
}
}
impl Clone for MCChat {
fn clone(&self) -> Self {
MCChat {

View File

@ -241,15 +241,22 @@ impl NetworkClient {
spawnposition.write(&mut self.stream).await.unwrap();
debug!("{:?}", spawnposition);
// Send initial keep alive.
self.send_chat_message("keep alive").await;
self.keep_alive().await;
// TODO: S->C Player Position and Look
// TODO: C->S Teleport Confirm
// TODO: C->S Player Position and Look
// TODO: C->S Client Status
// TODO: S->C inventories, entities, etc.
self.send_chat_message(format!(
"Welcome {} to the server!",
self.username.as_ref().unwrap_or(&"unknown".to_owned())
))
.await;
}
NetworkClientState::Play => {
if self.last_keep_alive.elapsed() > Duration::from_secs(10) {
self.send_chat_message("keep alive").await;
self.keep_alive().await;
}
}
@ -261,6 +268,13 @@ impl NetworkClient {
}
}
async fn send_chat_message<C: Into<MCChat>>(&mut self, message: C) {
let mut chatmessage = ClientboundChatMessage::new();
chatmessage.text = message.into();
chatmessage.write(&mut self.stream).await.unwrap();
debug!("{:?}", chatmessage);
}
async fn disconnect(&mut self, reason: Option<&str>) {
self.connected = false;
self.state = NetworkClientState::Disconnected;

View File

@ -510,3 +510,46 @@ impl Disconnect {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct ClientboundChatMessage {
pub text: MCChat,
pub position: MCByte, // 0: chat (chat box), 1: system message (chat box), 2: above hotbar
}
impl Into<Vec<u8>> for ClientboundChatMessage {
fn into(self) -> Vec<u8> {
let mut out = vec![];
let mut temp: Vec<u8> = MCVarInt::from(0x02).into(); // 0x02 Clientbound Chat Message.
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.text));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.position));
out.extend_from_slice(&Into::<Vec<u8>>::into(MCVarInt::from(temp.len() as i32)));
out.extend_from_slice(&temp);
out
}
}
impl TryFrom<Vec<u8>> for ClientboundChatMessage {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("unimplemented")
}
}
impl ClientboundChatMessage {
pub fn new() -> Self {
ClientboundChatMessage {
text: MCChat { text: "".into() },
position: 0.into(),
}
}
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
let mut clientboundchatmessage = ClientboundChatMessage::new();
clientboundchatmessage.text = MCChat::read(t).await?;
clientboundchatmessage.position = MCByte::read(t).await?;
Ok(clientboundchatmessage)
}
pub async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> {
for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b).await?;
}
Ok(())
}
}