Add entity status codes

This commit is contained in:
Ryan 2022-07-03 23:17:51 -07:00
parent fb09ab7f8c
commit e8451da55e
4 changed files with 119 additions and 22 deletions

View file

@ -7,7 +7,7 @@ use std::sync::Mutex;
use log::LevelFilter;
use num::Integer;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
use valence::client::{ClientId, Event, GameMode};
use valence::client::{ClientId, ClientEvent, GameMode, EntityEvent};
use valence::config::{Config, ServerListPing};
use valence::text::Color;
use valence::{
@ -169,7 +169,7 @@ impl Config for Game {
.unwrap();
while let Some(event) = client.pop_event() {
match event {
Event::Digging(e) => {
ClientEvent::Digging(e) => {
let pos = e.position;
if (0..SIZE_X as i32).contains(&pos.x)
@ -179,7 +179,7 @@ impl Config for Game {
board[pos.x as usize + pos.z as usize * SIZE_X] = true;
}
}
Event::Movement { .. } => {
ClientEvent::Movement { .. } => {
if client.position().y <= 0.0 {
client.teleport(spawn_pos, client.yaw(), client.pitch());
}

View file

@ -16,15 +16,17 @@ use crate::entity::types::Player;
use crate::entity::{velocity_to_packet_units, EntityType};
use crate::player_textures::SignedPlayerTextures;
use crate::protocol::packets::play::c2s::{C2sPlayPacket, DiggingStatus, InteractType};
pub use crate::protocol::packets::play::s2c::EntityEventStatus as EntityEvent;
use crate::protocol::packets::play::s2c::{
Biome as BiomeRegistryBiome, BiomeAdditionsSound, BiomeEffects, BiomeMoodSound, BiomeMusic,
BiomeParticle, BiomeParticleOptions, BiomeProperty, BiomeRegistry, BlockChangeAck, ChatType,
ChatTypeChat, ChatTypeNarration, ChatTypeRegistry, ChatTypeRegistryEntry, DimensionType,
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect, ForgetLevelChunk, GameEvent,
GameEventReason, KeepAlive, Login, MoveEntityPosition, MoveEntityPositionAndRotation,
MoveEntityRotation, PlayerPosition, PlayerPositionFlags, RegistryCodec, RemoveEntities,
Respawn, RotateHead, S2cPlayPacket, SetChunkCacheCenter, SetChunkCacheRadius,
SetEntityMetadata, SetEntityMotion, SpawnPosition, SystemChat, TeleportEntity,
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect,
EntityEvent as EntityEventPacket, ForgetLevelChunk, GameEvent, GameEventReason, KeepAlive,
Login, MoveEntityPosition, MoveEntityPositionAndRotation, MoveEntityRotation, PlayerPosition,
PlayerPositionFlags, RegistryCodec, RemoveEntities, Respawn, RotateHead, S2cPlayPacket,
SetChunkCacheCenter, SetChunkCacheRadius, SetEntityMetadata, SetEntityMotion, SpawnPosition,
SystemChat, TeleportEntity,
};
use crate::protocol::{BoundedInt, ByteAngle, Nbt, RawBytes, VarInt};
use crate::server::C2sPacketChannels;
@ -126,7 +128,7 @@ pub struct Client {
/// If spawn_position or spawn_position_yaw were modified this tick.
modified_spawn_position: bool,
death_location: Option<(DimensionId, BlockPos)>,
events: VecDeque<Event>,
events: VecDeque<ClientEvent>,
/// The ID of the last keepalive sent.
last_keepalive_id: i64,
/// If the last sent keepalive got a response.
@ -143,6 +145,7 @@ pub struct Client {
settings: Option<Settings>,
dug_blocks: Vec<i32>,
msgs_to_send: Vec<Text>,
entity_events: Vec<(Option<EntityId>, EntityEvent)>,
/// The metadata for the client's own player entity.
player_meta: Player,
}
@ -188,6 +191,7 @@ impl Client {
settings: None,
dug_blocks: Vec::new(),
msgs_to_send: Vec::new(),
entity_events: Vec::new(),
player_meta: Player::new(),
}
}
@ -308,10 +312,14 @@ impl Client {
self.send.is_none()
}
pub fn pop_event(&mut self) -> Option<Event> {
pub fn pop_event(&mut self) -> Option<ClientEvent> {
self.events.pop_front()
}
pub fn push_entity_event(&mut self, target: Option<EntityId>, event: EntityEvent) {
self.entity_events.push((target, event));
}
/// The current view distance of this client measured in chunks.
pub fn view_distance(&self) -> u8 {
self.settings
@ -384,7 +392,7 @@ impl Client {
if client.pending_teleports == 0 {
// TODO: validate movement using swept AABB collision with the blocks.
// TODO: validate that the client is actually inside/outside the vehicle?
let event = Event::Movement {
let event = ClientEvent::Movement {
position: client.new_position,
yaw: client.yaw,
pitch: client.pitch,
@ -427,7 +435,7 @@ impl Client {
C2sPlayPacket::BlockEntityTagQuery(_) => {}
C2sPlayPacket::ChangeDifficulty(_) => {}
C2sPlayPacket::ChatCommand(_) => {}
C2sPlayPacket::Chat(p) => self.events.push_back(Event::ChatMessage {
C2sPlayPacket::Chat(p) => self.events.push_back(ClientEvent::ChatMessage {
message: p.message.0,
timestamp: Duration::from_millis(p.timestamp),
}),
@ -444,7 +452,7 @@ impl Client {
allow_server_listings: p.allow_server_listings,
});
self.events.push_back(Event::SettingsChanged(old));
self.events.push_back(ClientEvent::SettingsChanged(old));
}
C2sPlayPacket::CommandSuggestion(_) => {}
C2sPlayPacket::ContainerButtonClick(_) => {}
@ -457,7 +465,7 @@ impl Client {
// TODO: verify that the client has line of sight to the targeted entity and
// that the distance is <=4 blocks.
self.events.push_back(Event::InteractWithEntity {
self.events.push_back(ClientEvent::InteractWithEntity {
id,
sneaking: p.sneaking,
typ: match p.typ {
@ -510,7 +518,7 @@ impl Client {
handle_movement_packet(self, true, p.position, p.yaw, p.pitch, self.on_ground);
}
C2sPlayPacket::PaddleBoat(p) => {
self.events.push_back(Event::SteerBoat {
self.events.push_back(ClientEvent::SteerBoat {
left_paddle_turning: p.left_paddle_turning,
right_paddle_turning: p.right_paddle_turning,
});
@ -527,17 +535,17 @@ impl Client {
}
self.events.push_back(match p.status {
DiggingStatus::StartedDigging => Event::Digging(Digging {
DiggingStatus::StartedDigging => ClientEvent::Digging(Digging {
status: event::DiggingStatus::Start,
position: p.location,
face: p.face,
}),
DiggingStatus::CancelledDigging => Event::Digging(Digging {
DiggingStatus::CancelledDigging => ClientEvent::Digging(Digging {
status: event::DiggingStatus::Cancel,
position: p.location,
face: p.face,
}),
DiggingStatus::FinishedDigging => Event::Digging(Digging {
DiggingStatus::FinishedDigging => ClientEvent::Digging(Digging {
status: event::DiggingStatus::Finish,
position: p.location,
face: p.face,
@ -565,7 +573,7 @@ impl Client {
C2sPlayPacket::SetJigsawBlock(_) => {}
C2sPlayPacket::SetStructureBlock(_) => {}
C2sPlayPacket::SignUpdate(_) => {}
C2sPlayPacket::Swing(p) => self.events.push_back(Event::ArmSwing(p.hand)),
C2sPlayPacket::Swing(p) => self.events.push_back(ClientEvent::ArmSwing(p.hand)),
C2sPlayPacket::TeleportToEntity(_) => {}
C2sPlayPacket::UseItemOn(_) => {}
C2sPlayPacket::UseItem(_) => {}
@ -964,6 +972,28 @@ impl Client {
},
);
for (target, event) in self.entity_events.drain(..) {
if let Some(target) = target {
if self.loaded_entities.contains(&target) {
send_packet(
&mut self.send,
EntityEventPacket {
entity_id: target.to_network_id(),
entity_status: event,
},
)
}
} else {
send_packet(
&mut self.send,
EntityEventPacket {
entity_id: 0,
entity_status: event,
},
);
}
}
self.old_position = self.new_position;
self.spawn = false;
}

View file

@ -8,7 +8,7 @@ pub use crate::protocol::packets::play::s2c::GameMode;
use crate::{BlockPos, EntityId};
#[derive(Debug)]
pub enum Event {
pub enum ClientEvent {
ChatMessage {
message: String,
timestamp: Duration,

View file

@ -744,8 +744,75 @@ pub mod play {
def_struct! {
EntityEvent 0x18 {
entity_id: i32,
/// TODO: enum
entity_status: u8,
entity_status: EntityEventStatus,
}
}
def_enum! {
#[derive(Copy, PartialEq, Eq)]
EntityEventStatus: u8 {
Jump = 1,
Hurt = 2,
Death = 3,
StartAttacking = 4,
StopAttacking = 5,
TamingFailed = 6,
TamingSucceeded = 7,
ShakeWetness = 8,
UseItemComplete = 9,
EatGrass = 10,
OfferFlower = 11,
LoveHearts = 12,
VillagerAngry = 13,
VillagerHappy = 14,
WitchHatMagic = 15,
ZombieConverting = 16,
FireworksExplode = 17,
InLoveHearts = 18,
SquidAnimSynch = 19,
SilverfishMergeAnim = 20,
GuardianAttackSound = 21,
ReducedDebugInfo = 22,
FullDebugInfo = 23,
PermissionLevelAll = 24,
PermissionLevelModerators = 25,
PermissionLevelGamemasters = 26,
PermissionLevelAdmins = 27,
PermissionLevelOwners = 28,
AttackBlocked = 29,
ShieldDisabled = 30,
FishingRodReelIn = 31,
ArmorstandWobble = 32,
Thorned = 33,
StopOfferFlower = 34,
TalismanActivate = 35,
Drowned = 36,
Burned = 37,
DolphinLookingForTreasure = 38,
RavagerStunned = 39,
TrustingFailed = 40,
TrustingSucceeded = 41,
VillagerSweat = 42,
BadOmenTriggered = 43,
Poked = 44,
FoxEat = 45,
Teleport = 46,
MainhandBreak = 47,
OffhandBreak = 48,
HeadBreak = 49,
ChestBreak = 50,
LegsBreak = 51,
FeetBreak = 52,
HoneySlide = 53,
HoneyJump = 54,
SwapHands = 55,
CancelShakeWetness = 56,
Frozen = 57,
StartRam = 58,
EndRam = 59,
Poof = 60,
TendrilsShiver = 61,
SonicCharge = 62,
}
}