mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-11 15:21:31 +11:00
Basic chat message support
This commit is contained in:
parent
a182f17c78
commit
fa2241c038
|
@ -6,7 +6,7 @@ use log::LevelFilter;
|
||||||
use noise::{NoiseFn, Seedable, SuperSimplex};
|
use noise::{NoiseFn, Seedable, SuperSimplex};
|
||||||
use rayon::iter::ParallelIterator;
|
use rayon::iter::ParallelIterator;
|
||||||
use valence::block::{BlockState, PropName, PropValue};
|
use valence::block::{BlockState, PropName, PropValue};
|
||||||
use valence::client::GameMode;
|
use valence::client::{ChatMessageType, GameMode};
|
||||||
use valence::config::{Config, ServerListPing};
|
use valence::config::{Config, ServerListPing};
|
||||||
use valence::text::Color;
|
use valence::text::Color;
|
||||||
use valence::util::chunks_in_view_distance;
|
use valence::util::chunks_in_view_distance;
|
||||||
|
@ -113,6 +113,8 @@ impl Config for Game {
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
client.send_message("welcome!", ChatMessageType::Chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dist = client.view_distance();
|
let dist = client.view_distance();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
mod event;
|
mod event;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::iter::FusedIterator;
|
use std::iter::FusedIterator;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
use flume::{Receiver, Sender, TrySendError};
|
use flume::{Receiver, Sender, TrySendError};
|
||||||
|
@ -16,6 +17,7 @@ use crate::dimension::{Dimension, DimensionEffects};
|
||||||
use crate::entity::types::Player;
|
use crate::entity::types::Player;
|
||||||
use crate::entity::{velocity_to_packet_units, EntityType};
|
use crate::entity::{velocity_to_packet_units, EntityType};
|
||||||
use crate::packets::play::c2s::{C2sPlayPacket, DiggingStatus};
|
use crate::packets::play::c2s::{C2sPlayPacket, DiggingStatus};
|
||||||
|
pub use crate::packets::play::s2c::ChatMessageType;
|
||||||
use crate::packets::play::s2c::{
|
use crate::packets::play::s2c::{
|
||||||
AcknowledgeBlockChanges, Biome as BiomeRegistryBiome, BiomeAdditionsSound, BiomeEffects,
|
AcknowledgeBlockChanges, Biome as BiomeRegistryBiome, BiomeAdditionsSound, BiomeEffects,
|
||||||
BiomeMoodSound, BiomeMusic, BiomeParticle, BiomeParticleOptions, BiomeProperty, BiomeRegistry,
|
BiomeMoodSound, BiomeMusic, BiomeParticle, BiomeParticleOptions, BiomeProperty, BiomeRegistry,
|
||||||
|
@ -23,7 +25,8 @@ use crate::packets::play::s2c::{
|
||||||
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect, EntityHeadLook, EntityMetadata,
|
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect, EntityHeadLook, EntityMetadata,
|
||||||
EntityPosition, EntityPositionAndRotation, EntityRotation, EntityTeleport, EntityVelocity,
|
EntityPosition, EntityPositionAndRotation, EntityRotation, EntityTeleport, EntityVelocity,
|
||||||
JoinGame, KeepAlive, PlayerPositionAndLook, PlayerPositionAndLookFlags, RegistryCodec,
|
JoinGame, KeepAlive, PlayerPositionAndLook, PlayerPositionAndLookFlags, RegistryCodec,
|
||||||
S2cPlayPacket, SpawnPosition, UnloadChunk, UpdateViewDistance, UpdateViewPosition,
|
S2cPlayPacket, SpawnPosition, SystemChatMessage, UnloadChunk, UpdateViewDistance,
|
||||||
|
UpdateViewPosition,
|
||||||
};
|
};
|
||||||
use crate::player_textures::SignedPlayerTextures;
|
use crate::player_textures::SignedPlayerTextures;
|
||||||
use crate::protocol::{BoundedInt, Nbt, RawBytes};
|
use crate::protocol::{BoundedInt, Nbt, RawBytes};
|
||||||
|
@ -136,6 +139,7 @@ pub struct Client {
|
||||||
old_game_mode: GameMode,
|
old_game_mode: GameMode,
|
||||||
settings: Option<Settings>,
|
settings: Option<Settings>,
|
||||||
dug_blocks: Vec<i32>,
|
dug_blocks: Vec<i32>,
|
||||||
|
msgs_to_send: Vec<(Text, ChatMessageType)>,
|
||||||
/// The metadata for the client's own player entity.
|
/// The metadata for the client's own player entity.
|
||||||
player_meta: Player,
|
player_meta: Player,
|
||||||
}
|
}
|
||||||
|
@ -178,6 +182,7 @@ impl Client {
|
||||||
old_game_mode: GameMode::Survival,
|
old_game_mode: GameMode::Survival,
|
||||||
settings: None,
|
settings: None,
|
||||||
dug_blocks: Vec::new(),
|
dug_blocks: Vec::new(),
|
||||||
|
msgs_to_send: Vec::new(),
|
||||||
player_meta: Player::new(),
|
player_meta: Player::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +203,10 @@ impl Client {
|
||||||
self.textures.as_ref()
|
self.textures.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn send_message(&mut self, msg: impl Into<Text>, typ: ChatMessageType) {
|
||||||
|
self.msgs_to_send.push((msg.into(), typ));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> Vec3<f64> {
|
pub fn position(&self) -> Vec3<f64> {
|
||||||
self.new_position
|
self.new_position
|
||||||
}
|
}
|
||||||
|
@ -402,7 +411,10 @@ impl Client {
|
||||||
C2sPlayPacket::QueryBlockNbt(_) => {}
|
C2sPlayPacket::QueryBlockNbt(_) => {}
|
||||||
C2sPlayPacket::SetDifficulty(_) => {}
|
C2sPlayPacket::SetDifficulty(_) => {}
|
||||||
C2sPlayPacket::ChatCommand(_) => {}
|
C2sPlayPacket::ChatCommand(_) => {}
|
||||||
C2sPlayPacket::ChatMessage(_) => {}
|
C2sPlayPacket::ChatMessage(p) => self.events.push(Event::ChatMessage {
|
||||||
|
message: p.message.0,
|
||||||
|
timestamp: Duration::from_millis(p.timestamp),
|
||||||
|
}),
|
||||||
C2sPlayPacket::ChatPreview(_) => {}
|
C2sPlayPacket::ChatPreview(_) => {}
|
||||||
C2sPlayPacket::ClientStatus(_) => {}
|
C2sPlayPacket::ClientStatus(_) => {}
|
||||||
C2sPlayPacket::ClientSettings(p) => {
|
C2sPlayPacket::ClientSettings(p) => {
|
||||||
|
@ -719,6 +731,11 @@ impl Client {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (msg, typ) in self.msgs_to_send.drain(..) {
|
||||||
|
// TODO: wont work without proper chat registry.
|
||||||
|
send_packet(&mut self.send, SystemChatMessage { chat: msg, typ });
|
||||||
|
}
|
||||||
|
|
||||||
let mut entities_to_unload = Vec::new();
|
let mut entities_to_unload = Vec::new();
|
||||||
|
|
||||||
// Update all entities that are visible and unload entities that are no
|
// Update all entities that are visible and unload entities that are no
|
||||||
|
@ -824,21 +841,18 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the client's own player metadata.
|
// Update the client's own player metadata.
|
||||||
{
|
let mut data = Vec::new();
|
||||||
let mut data = Vec::new();
|
self.player_meta.updated_metadata(&mut data);
|
||||||
self.player_meta.updated_metadata(&mut data);
|
|
||||||
|
|
||||||
if !data.is_empty() {
|
if !data.is_empty() {
|
||||||
data.push(0xff);
|
data.push(0xff);
|
||||||
|
|
||||||
self.send_packet(EntityMetadata {
|
self.send_packet(EntityMetadata {
|
||||||
entity_id: VarInt(0),
|
entity_id: VarInt(0),
|
||||||
metadata: RawBytes(data),
|
metadata: RawBytes(data),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
self.player_meta.clear_modifications();
|
|
||||||
}
|
}
|
||||||
|
self.player_meta.clear_modifications();
|
||||||
|
|
||||||
// Spawn new entities within the view distance.
|
// Spawn new entities within the view distance.
|
||||||
let pos = self.position();
|
let pos = self.position();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use vek::Vec3;
|
use vek::Vec3;
|
||||||
|
|
||||||
use crate::packets::play::c2s::BlockFace;
|
use crate::packets::play::c2s::BlockFace;
|
||||||
|
@ -7,6 +9,10 @@ use crate::{BlockPos, EntityId};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
ChatMessage {
|
||||||
|
message: String,
|
||||||
|
timestamp: Duration,
|
||||||
|
},
|
||||||
/// Settings were changed. The value in this variant is the previous client
|
/// Settings were changed. The value in this variant is the previous client
|
||||||
/// settings.
|
/// settings.
|
||||||
SettingsChanged(Option<Settings>),
|
SettingsChanged(Option<Settings>),
|
||||||
|
|
|
@ -1005,6 +1005,7 @@ pub mod play {
|
||||||
}
|
}
|
||||||
|
|
||||||
def_enum! {
|
def_enum! {
|
||||||
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
ChatMessageType: VarInt {
|
ChatMessageType: VarInt {
|
||||||
Chat = 0,
|
Chat = 0,
|
||||||
SystemMessage = 1,
|
SystemMessage = 1,
|
||||||
|
@ -1017,6 +1018,12 @@ pub mod play {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ChatMessageType {
|
||||||
|
fn default() -> Self {
|
||||||
|
ChatMessageType::Chat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def_enum! {
|
def_enum! {
|
||||||
PlayerInfo 0x34: VarInt {
|
PlayerInfo 0x34: VarInt {
|
||||||
AddPlayer: Vec<PlayerInfoAddPlayer> = 0,
|
AddPlayer: Vec<PlayerInfoAddPlayer> = 0,
|
||||||
|
@ -1132,6 +1139,13 @@ pub mod play {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def_struct! {
|
||||||
|
SystemChatMessage 0x5f {
|
||||||
|
chat: Text,
|
||||||
|
typ: ChatMessageType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def_struct! {
|
def_struct! {
|
||||||
PlayerListHeaderFooter 0x60 {
|
PlayerListHeaderFooter 0x60 {
|
||||||
header: Text,
|
header: Text,
|
||||||
|
@ -1240,6 +1254,7 @@ pub mod play {
|
||||||
EntityMetadata,
|
EntityMetadata,
|
||||||
EntityVelocity,
|
EntityVelocity,
|
||||||
TimeUpdate,
|
TimeUpdate,
|
||||||
|
SystemChatMessage,
|
||||||
PlayerListHeaderFooter,
|
PlayerListHeaderFooter,
|
||||||
EntityTeleport,
|
EntityTeleport,
|
||||||
}
|
}
|
||||||
|
@ -1280,8 +1295,11 @@ pub mod play {
|
||||||
|
|
||||||
def_struct! {
|
def_struct! {
|
||||||
ChatMessage 0x04 {
|
ChatMessage 0x04 {
|
||||||
message: BoundedString<0, 256>
|
message: BoundedString<0, 256>,
|
||||||
// TODO:
|
timestamp: u64,
|
||||||
|
salt: u64,
|
||||||
|
signature: Vec<u8>,
|
||||||
|
signed_preview: bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue