Send correct dig packet for each version
This commit is contained in:
parent
700a31013f
commit
18b2641d66
|
@ -948,19 +948,36 @@ impl fmt::Debug for VarLong {
|
||||||
impl Serializable for Position {
|
impl Serializable for Position {
|
||||||
fn read_from<R: io::Read>(buf: &mut R) -> Result<Position, Error> {
|
fn read_from<R: io::Read>(buf: &mut R) -> Result<Position, Error> {
|
||||||
let pos = buf.read_u64::<BigEndian>()?;
|
let pos = buf.read_u64::<BigEndian>()?;
|
||||||
Ok(Position::new(
|
let protocol_version = current_protocol_version();
|
||||||
((pos as i64) >> 38) as i32,
|
if protocol_version < 477 {
|
||||||
((pos as i64) & 0xFFF) as i32,
|
Ok(Position::new(
|
||||||
((pos as i64) << 26 >> 38) as i32,
|
((pos as i64) >> 38) as i32,
|
||||||
))
|
(((pos as i64) >> 26) & 0xFFF) as i32,
|
||||||
|
((pos as i64) << 38 >> 38) as i32,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(Position::new(
|
||||||
|
((pos as i64) >> 38) as i32,
|
||||||
|
((pos as i64) << 52 >> 52) as i32,
|
||||||
|
((pos as i64) << 26 >> 38) as i32,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), Error> {
|
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), Error> {
|
||||||
let pos = (((self.x as u64) & 0x3FFFFFF) << 38)
|
let pos;
|
||||||
| ((self.y as u64) & 0xFFF)
|
let protocol_version = current_protocol_version();
|
||||||
| (((self.z as u64) & 0x3FFFFFF) << 12);
|
if protocol_version < 477 {
|
||||||
|
pos = (((self.x as u64) & 0x3FFFFFF) << 38)
|
||||||
|
| (((self.y as u64) & 0xFFF) << 26)
|
||||||
|
| ((self.z as u64) & 0x3FFFFFF);
|
||||||
|
} else {
|
||||||
|
pos = (((self.x as u64) & 0x3FFFFFF) << 38)
|
||||||
|
| ((self.y as u64) & 0xFFF)
|
||||||
|
| (((self.z as u64) & 0x3FFFFFF) << 12);
|
||||||
|
}
|
||||||
|
|
||||||
buf.write_u64::<BigEndian>(pos)?;
|
buf.write_u64::<BigEndian>(pos)?;
|
||||||
Result::Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,6 @@ pub struct DiggingState {
|
||||||
pub struct Digging {
|
pub struct Digging {
|
||||||
pub last: Option<DiggingState>,
|
pub last: Option<DiggingState>,
|
||||||
pub current: Option<DiggingState>,
|
pub current: Option<DiggingState>,
|
||||||
pub packets: std::collections::VecDeque<packet::play::serverbound::PlayerDigging>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Digging {
|
impl Digging {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::collections::VecDeque;
|
use std::sync::Arc;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ecs;
|
use crate::ecs;
|
||||||
|
@ -7,6 +8,7 @@ use crate::shared::Position as BPos;
|
||||||
use crate::world;
|
use crate::world;
|
||||||
use cgmath::InnerSpace;
|
use cgmath::InnerSpace;
|
||||||
use steven_protocol::protocol;
|
use steven_protocol::protocol;
|
||||||
|
use steven_protocol::protocol::Conn;
|
||||||
|
|
||||||
pub struct ApplyVelocity {
|
pub struct ApplyVelocity {
|
||||||
filter: ecs::Filter,
|
filter: ecs::Filter,
|
||||||
|
@ -293,6 +295,7 @@ pub struct ApplyDigging {
|
||||||
filter: ecs::Filter,
|
filter: ecs::Filter,
|
||||||
mouse_buttons: ecs::Key<MouseButtons>,
|
mouse_buttons: ecs::Key<MouseButtons>,
|
||||||
digging: ecs::Key<Digging>,
|
digging: ecs::Key<Digging>,
|
||||||
|
conn: ecs::Key<Arc<RwLock<Option<Conn>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApplyDigging {
|
impl ApplyDigging {
|
||||||
|
@ -303,11 +306,12 @@ impl ApplyDigging {
|
||||||
filter: ecs::Filter::new().with(mouse_buttons).with(digging),
|
filter: ecs::Filter::new().with(mouse_buttons).with(digging),
|
||||||
mouse_buttons,
|
mouse_buttons,
|
||||||
digging,
|
digging,
|
||||||
|
conn: m.get_key(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_packet(&self,
|
fn send_packet(&self,
|
||||||
packets: &mut VecDeque<packet::play::serverbound::PlayerDigging>,
|
conn: &mut Conn,
|
||||||
target: &DiggingState,
|
target: &DiggingState,
|
||||||
state: i32
|
state: i32
|
||||||
) {
|
) {
|
||||||
|
@ -318,11 +322,28 @@ impl ApplyDigging {
|
||||||
n => panic!("Invalid dig state {}", n),
|
n => panic!("Invalid dig state {}", n),
|
||||||
}
|
}
|
||||||
|
|
||||||
packets.push_back(packet::play::serverbound::PlayerDigging {
|
match conn.protocol_version {
|
||||||
status: protocol::VarInt(state),
|
// 1.7.10
|
||||||
location: target.position,
|
5 => conn.write_packet(packet::play::serverbound::PlayerDigging_u8_u8y {
|
||||||
face: target.face.index() as u8,
|
status: state as u8,
|
||||||
});
|
x: target.position.x,
|
||||||
|
y: target.position.y as u8,
|
||||||
|
z: target.position.z,
|
||||||
|
face: target.face.index() as u8,
|
||||||
|
}).unwrap(),
|
||||||
|
// 1.8.9 or v15w39c
|
||||||
|
47|74 => conn.write_packet(packet::play::serverbound::PlayerDigging_u8 {
|
||||||
|
status: state as u8,
|
||||||
|
location: target.position,
|
||||||
|
face: target.face.index() as u8,
|
||||||
|
}).unwrap(),
|
||||||
|
// 1.9+
|
||||||
|
_ => conn.write_packet(packet::play::serverbound::PlayerDigging {
|
||||||
|
status: protocol::VarInt(state),
|
||||||
|
location: target.position,
|
||||||
|
face: target.face.index() as u8,
|
||||||
|
}).unwrap(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_state(&self,
|
fn next_state(&self,
|
||||||
|
@ -381,6 +402,15 @@ impl ecs::System for ApplyDigging {
|
||||||
use crate::server::target::{trace_ray, test_block};
|
use crate::server::target::{trace_ray, test_block};
|
||||||
use cgmath::EuclideanSpace;
|
use cgmath::EuclideanSpace;
|
||||||
|
|
||||||
|
let world_entity = m.get_world();
|
||||||
|
let mut conn = m.get_component(world_entity, self.conn).unwrap().write().unwrap();
|
||||||
|
let conn = match conn.as_mut() {
|
||||||
|
Some(conn) => conn,
|
||||||
|
// Don't keep processing digging operations if the connection was
|
||||||
|
// closed.
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
let target = trace_ray(
|
let target = trace_ray(
|
||||||
world,
|
world,
|
||||||
4.0,
|
4.0,
|
||||||
|
@ -392,7 +422,6 @@ impl ecs::System for ApplyDigging {
|
||||||
for e in m.find(&self.filter) {
|
for e in m.find(&self.filter) {
|
||||||
let mouse_buttons = m.get_component(e, self.mouse_buttons).unwrap();
|
let mouse_buttons = m.get_component(e, self.mouse_buttons).unwrap();
|
||||||
let digging = m.get_component_mut(e, self.digging).unwrap();
|
let digging = m.get_component_mut(e, self.digging).unwrap();
|
||||||
let packets = &mut digging.packets;
|
|
||||||
|
|
||||||
// Update last and current state
|
// Update last and current state
|
||||||
std::mem::swap(&mut digging.last, &mut digging.current);
|
std::mem::swap(&mut digging.last, &mut digging.current);
|
||||||
|
@ -401,21 +430,21 @@ impl ecs::System for ApplyDigging {
|
||||||
// Handle digging packets
|
// Handle digging packets
|
||||||
match (&digging.last, &mut digging.current) {
|
match (&digging.last, &mut digging.current) {
|
||||||
// Start the new digging operation.
|
// Start the new digging operation.
|
||||||
(None, Some(current)) => self.send_packet(packets, current, 0),
|
(None, Some(current)) => self.send_packet(conn, current, 0),
|
||||||
// Cancel the previous digging operation.
|
// Cancel the previous digging operation.
|
||||||
(Some(last), None) if !last.finished => self.send_packet(packets, last, 1),
|
(Some(last), None) if !last.finished => self.send_packet(conn, last, 1),
|
||||||
// Move to digging a new block
|
// Move to digging a new block
|
||||||
(Some(last), Some(current)) if last.position != current.position => {
|
(Some(last), Some(current)) if last.position != current.position => {
|
||||||
// Cancel the previous digging operation.
|
// Cancel the previous digging operation.
|
||||||
if !current.finished {
|
if !current.finished {
|
||||||
self.send_packet(packets, last, 1);
|
self.send_packet(conn, last, 1);
|
||||||
}
|
}
|
||||||
// Start the new digging operation.
|
// Start the new digging operation.
|
||||||
self.send_packet(packets, current, 0);
|
self.send_packet(conn, current, 0);
|
||||||
},
|
},
|
||||||
// Finish the new digging operation.
|
// Finish the new digging operation.
|
||||||
(Some(_), Some(current)) if !self.is_finished(current) && !current.finished => {
|
(Some(_), Some(current)) if !self.is_finished(current) && !current.finished => {
|
||||||
self.send_packet(packets, current, 2);
|
self.send_packet(conn, current, 2);
|
||||||
current.finished = true;
|
current.finished = true;
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub mod target;
|
||||||
|
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
uuid: protocol::UUID,
|
uuid: protocol::UUID,
|
||||||
conn: Option<protocol::Conn>,
|
conn: Arc<RwLock<Option<protocol::Conn>>>,
|
||||||
protocol_version: i32,
|
protocol_version: i32,
|
||||||
forge_mods: Vec<forge::ForgeMod>,
|
forge_mods: Vec<forge::ForgeMod>,
|
||||||
read_queue: Option<mpsc::Receiver<Result<packet::Packet, protocol::Error>>>,
|
read_queue: Option<mpsc::Receiver<Result<packet::Packet, protocol::Error>>>,
|
||||||
|
@ -62,7 +62,6 @@ pub struct Server {
|
||||||
game_info: ecs::Key<entity::GameInfo>,
|
game_info: ecs::Key<entity::GameInfo>,
|
||||||
player_movement: ecs::Key<entity::player::PlayerMovement>,
|
player_movement: ecs::Key<entity::player::PlayerMovement>,
|
||||||
mouse_buttons: ecs::Key<entity::MouseButtons>,
|
mouse_buttons: ecs::Key<entity::MouseButtons>,
|
||||||
digging: ecs::Key<entity::Digging>,
|
|
||||||
gravity: ecs::Key<entity::Gravity>,
|
gravity: ecs::Key<entity::Gravity>,
|
||||||
position: ecs::Key<entity::Position>,
|
position: ecs::Key<entity::Position>,
|
||||||
target_position: ecs::Key<entity::TargetPosition>,
|
target_position: ecs::Key<entity::TargetPosition>,
|
||||||
|
@ -170,7 +169,7 @@ impl Server {
|
||||||
forge_mods,
|
forge_mods,
|
||||||
protocol::UUID::from_str(&val.uuid).unwrap(),
|
protocol::UUID::from_str(&val.uuid).unwrap(),
|
||||||
resources,
|
resources,
|
||||||
Some(write),
|
Arc::new(RwLock::new(Some(write))),
|
||||||
Some(rx),
|
Some(rx),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -187,7 +186,7 @@ impl Server {
|
||||||
forge_mods,
|
forge_mods,
|
||||||
val.uuid,
|
val.uuid,
|
||||||
resources,
|
resources,
|
||||||
Some(write),
|
Arc::new(RwLock::new(Some(write))),
|
||||||
Some(rx),
|
Some(rx),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -331,7 +330,7 @@ impl Server {
|
||||||
forge_mods,
|
forge_mods,
|
||||||
uuid,
|
uuid,
|
||||||
resources,
|
resources,
|
||||||
Some(write),
|
Arc::new(RwLock::new(Some(write))),
|
||||||
Some(rx),
|
Some(rx),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -359,7 +358,7 @@ impl Server {
|
||||||
vec![],
|
vec![],
|
||||||
protocol::UUID::default(),
|
protocol::UUID::default(),
|
||||||
resources,
|
resources,
|
||||||
None,
|
Arc::new(RwLock::new(None)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
@ -447,7 +446,7 @@ impl Server {
|
||||||
forge_mods: Vec<forge::ForgeMod>,
|
forge_mods: Vec<forge::ForgeMod>,
|
||||||
uuid: protocol::UUID,
|
uuid: protocol::UUID,
|
||||||
resources: Arc<RwLock<resources::Manager>>,
|
resources: Arc<RwLock<resources::Manager>>,
|
||||||
conn: Option<protocol::Conn>,
|
conn: Arc<RwLock<Option<protocol::Conn>>>,
|
||||||
read_queue: Option<mpsc::Receiver<Result<packet::Packet, protocol::Error>>>,
|
read_queue: Option<mpsc::Receiver<Result<packet::Packet, protocol::Error>>>,
|
||||||
) -> Server {
|
) -> Server {
|
||||||
let mut entities = ecs::Manager::new();
|
let mut entities = ecs::Manager::new();
|
||||||
|
@ -456,6 +455,7 @@ impl Server {
|
||||||
let world_entity = entities.get_world();
|
let world_entity = entities.get_world();
|
||||||
let game_info = entities.get_key();
|
let game_info = entities.get_key();
|
||||||
entities.add_component(world_entity, game_info, entity::GameInfo::new());
|
entities.add_component(world_entity, game_info, entity::GameInfo::new());
|
||||||
|
entities.add_component(world_entity, entities.get_key(), conn.clone());
|
||||||
|
|
||||||
let version = resources.read().unwrap().version();
|
let version = resources.read().unwrap().version();
|
||||||
Server {
|
Server {
|
||||||
|
@ -480,7 +480,6 @@ impl Server {
|
||||||
game_info,
|
game_info,
|
||||||
player_movement: entities.get_key(),
|
player_movement: entities.get_key(),
|
||||||
mouse_buttons: entities.get_key(),
|
mouse_buttons: entities.get_key(),
|
||||||
digging: entities.get_key(),
|
|
||||||
gravity: entities.get_key(),
|
gravity: entities.get_key(),
|
||||||
position: entities.get_key(),
|
position: entities.get_key(),
|
||||||
target_position: entities.get_key(),
|
target_position: entities.get_key(),
|
||||||
|
@ -504,7 +503,7 @@ impl Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disconnect(&mut self, reason: Option<format::Component>) {
|
pub fn disconnect(&mut self, reason: Option<format::Component>) {
|
||||||
self.conn = None;
|
self.conn.write().unwrap().take();
|
||||||
self.disconnect_reason = reason;
|
self.disconnect_reason = reason;
|
||||||
if let Some(player) = self.player.take() {
|
if let Some(player) = self.player.take() {
|
||||||
self.entities.remove_entity(player);
|
self.entities.remove_entity(player);
|
||||||
|
@ -513,7 +512,7 @@ impl Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_connected(&self) -> bool {
|
pub fn is_connected(&self) -> bool {
|
||||||
self.conn.is_some()
|
self.conn.read().unwrap().is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, renderer: &mut render::Renderer, delta: f64) {
|
pub fn tick(&mut self, renderer: &mut render::Renderer, delta: f64) {
|
||||||
|
@ -659,12 +658,12 @@ impl Server {
|
||||||
Err(err) => panic!("Err: {:?}", err),
|
Err(err) => panic!("Err: {:?}", err),
|
||||||
}
|
}
|
||||||
// Disconnected
|
// Disconnected
|
||||||
if self.conn.is_none() {
|
if self.conn.read().unwrap().is_none() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.conn.is_some() {
|
if self.conn.read().unwrap().is_some() {
|
||||||
self.read_queue = Some(rx);
|
self.read_queue = Some(rx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -782,12 +781,6 @@ impl Server {
|
||||||
};
|
};
|
||||||
self.write_packet(packet);
|
self.write_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
let digging = self.entities.get_component_mut(player, self.digging).unwrap();
|
|
||||||
let packets = &mut digging.packets;
|
|
||||||
while let Some(packet) = packets.pop_front() {
|
|
||||||
self.write_packet(packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,8 +924,9 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_packet<T: protocol::PacketType>(&mut self, p: T) {
|
pub fn write_packet<T: protocol::PacketType>(&self, p: T) {
|
||||||
let _ = self.conn.as_mut().unwrap().write_packet(p); // TODO handle errors
|
let mut conn = self.conn.write().unwrap();
|
||||||
|
let _ = conn.as_mut().unwrap().write_packet(p); // TODO handle errors
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_keep_alive_i64(
|
fn on_keep_alive_i64(
|
||||||
|
@ -1079,12 +1073,13 @@ impl Server {
|
||||||
|
|
||||||
// TODO: remove wrappers and directly call on Conn
|
// TODO: remove wrappers and directly call on Conn
|
||||||
fn write_fmlhs_plugin_message(&mut self, msg: &forge::FmlHs) {
|
fn write_fmlhs_plugin_message(&mut self, msg: &forge::FmlHs) {
|
||||||
let _ = self.conn.as_mut().unwrap().write_fmlhs_plugin_message(msg); // TODO handle errors
|
let mut conn = self.conn.write().unwrap();
|
||||||
|
let _ = conn.as_mut().unwrap().write_fmlhs_plugin_message(msg); // TODO handle errors
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_plugin_message(&mut self, channel: &str, data: &[u8]) {
|
fn write_plugin_message(&mut self, channel: &str, data: &[u8]) {
|
||||||
let _ = self
|
let mut conn = self.conn.write().unwrap();
|
||||||
.conn
|
let _ = conn
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write_plugin_message(channel, data); // TODO handle errors
|
.write_plugin_message(channel, data); // TODO handle errors
|
||||||
|
|
Loading…
Reference in New Issue