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 {
|
||||
fn read_from<R: io::Read>(buf: &mut R) -> Result<Position, Error> {
|
||||
let pos = buf.read_u64::<BigEndian>()?;
|
||||
Ok(Position::new(
|
||||
((pos as i64) >> 38) as i32,
|
||||
((pos as i64) & 0xFFF) as i32,
|
||||
((pos as i64) << 26 >> 38) as i32,
|
||||
))
|
||||
let protocol_version = current_protocol_version();
|
||||
if protocol_version < 477 {
|
||||
Ok(Position::new(
|
||||
((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> {
|
||||
let pos = (((self.x as u64) & 0x3FFFFFF) << 38)
|
||||
| ((self.y as u64) & 0xFFF)
|
||||
| (((self.z as u64) & 0x3FFFFFF) << 12);
|
||||
let pos;
|
||||
let protocol_version = current_protocol_version();
|
||||
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)?;
|
||||
Result::Ok(())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,6 @@ pub struct DiggingState {
|
|||
pub struct Digging {
|
||||
pub last: Option<DiggingState>,
|
||||
pub current: Option<DiggingState>,
|
||||
pub packets: std::collections::VecDeque<packet::play::serverbound::PlayerDigging>,
|
||||
}
|
||||
|
||||
impl Digging {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use super::*;
|
||||
use crate::ecs;
|
||||
|
@ -7,6 +8,7 @@ use crate::shared::Position as BPos;
|
|||
use crate::world;
|
||||
use cgmath::InnerSpace;
|
||||
use steven_protocol::protocol;
|
||||
use steven_protocol::protocol::Conn;
|
||||
|
||||
pub struct ApplyVelocity {
|
||||
filter: ecs::Filter,
|
||||
|
@ -293,6 +295,7 @@ pub struct ApplyDigging {
|
|||
filter: ecs::Filter,
|
||||
mouse_buttons: ecs::Key<MouseButtons>,
|
||||
digging: ecs::Key<Digging>,
|
||||
conn: ecs::Key<Arc<RwLock<Option<Conn>>>>,
|
||||
}
|
||||
|
||||
impl ApplyDigging {
|
||||
|
@ -303,11 +306,12 @@ impl ApplyDigging {
|
|||
filter: ecs::Filter::new().with(mouse_buttons).with(digging),
|
||||
mouse_buttons,
|
||||
digging,
|
||||
conn: m.get_key(),
|
||||
}
|
||||
}
|
||||
|
||||
fn send_packet(&self,
|
||||
packets: &mut VecDeque<packet::play::serverbound::PlayerDigging>,
|
||||
conn: &mut Conn,
|
||||
target: &DiggingState,
|
||||
state: i32
|
||||
) {
|
||||
|
@ -318,11 +322,28 @@ impl ApplyDigging {
|
|||
n => panic!("Invalid dig state {}", n),
|
||||
}
|
||||
|
||||
packets.push_back(packet::play::serverbound::PlayerDigging {
|
||||
status: protocol::VarInt(state),
|
||||
location: target.position,
|
||||
face: target.face.index() as u8,
|
||||
});
|
||||
match conn.protocol_version {
|
||||
// 1.7.10
|
||||
5 => conn.write_packet(packet::play::serverbound::PlayerDigging_u8_u8y {
|
||||
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,
|
||||
|
@ -381,6 +402,15 @@ impl ecs::System for ApplyDigging {
|
|||
use crate::server::target::{trace_ray, test_block};
|
||||
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(
|
||||
world,
|
||||
4.0,
|
||||
|
@ -392,7 +422,6 @@ impl ecs::System for ApplyDigging {
|
|||
for e in m.find(&self.filter) {
|
||||
let mouse_buttons = m.get_component(e, self.mouse_buttons).unwrap();
|
||||
let digging = m.get_component_mut(e, self.digging).unwrap();
|
||||
let packets = &mut digging.packets;
|
||||
|
||||
// Update last and current state
|
||||
std::mem::swap(&mut digging.last, &mut digging.current);
|
||||
|
@ -401,21 +430,21 @@ impl ecs::System for ApplyDigging {
|
|||
// Handle digging packets
|
||||
match (&digging.last, &mut digging.current) {
|
||||
// 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.
|
||||
(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
|
||||
(Some(last), Some(current)) if last.position != current.position => {
|
||||
// Cancel the previous digging operation.
|
||||
if !current.finished {
|
||||
self.send_packet(packets, last, 1);
|
||||
self.send_packet(conn, last, 1);
|
||||
}
|
||||
// Start the new digging operation.
|
||||
self.send_packet(packets, current, 0);
|
||||
self.send_packet(conn, current, 0);
|
||||
},
|
||||
// Finish the new digging operation.
|
||||
(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;
|
||||
},
|
||||
_ => {},
|
||||
|
|
|
@ -41,7 +41,7 @@ pub mod target;
|
|||
|
||||
pub struct Server {
|
||||
uuid: protocol::UUID,
|
||||
conn: Option<protocol::Conn>,
|
||||
conn: Arc<RwLock<Option<protocol::Conn>>>,
|
||||
protocol_version: i32,
|
||||
forge_mods: Vec<forge::ForgeMod>,
|
||||
read_queue: Option<mpsc::Receiver<Result<packet::Packet, protocol::Error>>>,
|
||||
|
@ -62,7 +62,6 @@ pub struct Server {
|
|||
game_info: ecs::Key<entity::GameInfo>,
|
||||
player_movement: ecs::Key<entity::player::PlayerMovement>,
|
||||
mouse_buttons: ecs::Key<entity::MouseButtons>,
|
||||
digging: ecs::Key<entity::Digging>,
|
||||
gravity: ecs::Key<entity::Gravity>,
|
||||
position: ecs::Key<entity::Position>,
|
||||
target_position: ecs::Key<entity::TargetPosition>,
|
||||
|
@ -170,7 +169,7 @@ impl Server {
|
|||
forge_mods,
|
||||
protocol::UUID::from_str(&val.uuid).unwrap(),
|
||||
resources,
|
||||
Some(write),
|
||||
Arc::new(RwLock::new(Some(write))),
|
||||
Some(rx),
|
||||
));
|
||||
}
|
||||
|
@ -187,7 +186,7 @@ impl Server {
|
|||
forge_mods,
|
||||
val.uuid,
|
||||
resources,
|
||||
Some(write),
|
||||
Arc::new(RwLock::new(Some(write))),
|
||||
Some(rx),
|
||||
));
|
||||
}
|
||||
|
@ -331,7 +330,7 @@ impl Server {
|
|||
forge_mods,
|
||||
uuid,
|
||||
resources,
|
||||
Some(write),
|
||||
Arc::new(RwLock::new(Some(write))),
|
||||
Some(rx),
|
||||
))
|
||||
}
|
||||
|
@ -359,7 +358,7 @@ impl Server {
|
|||
vec![],
|
||||
protocol::UUID::default(),
|
||||
resources,
|
||||
None,
|
||||
Arc::new(RwLock::new(None)),
|
||||
None,
|
||||
);
|
||||
let mut rng = rand::thread_rng();
|
||||
|
@ -447,7 +446,7 @@ impl Server {
|
|||
forge_mods: Vec<forge::ForgeMod>,
|
||||
uuid: protocol::UUID,
|
||||
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>>>,
|
||||
) -> Server {
|
||||
let mut entities = ecs::Manager::new();
|
||||
|
@ -456,6 +455,7 @@ impl Server {
|
|||
let world_entity = entities.get_world();
|
||||
let game_info = entities.get_key();
|
||||
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();
|
||||
Server {
|
||||
|
@ -480,7 +480,6 @@ impl Server {
|
|||
game_info,
|
||||
player_movement: entities.get_key(),
|
||||
mouse_buttons: entities.get_key(),
|
||||
digging: entities.get_key(),
|
||||
gravity: entities.get_key(),
|
||||
position: entities.get_key(),
|
||||
target_position: entities.get_key(),
|
||||
|
@ -504,7 +503,7 @@ impl Server {
|
|||
}
|
||||
|
||||
pub fn disconnect(&mut self, reason: Option<format::Component>) {
|
||||
self.conn = None;
|
||||
self.conn.write().unwrap().take();
|
||||
self.disconnect_reason = reason;
|
||||
if let Some(player) = self.player.take() {
|
||||
self.entities.remove_entity(player);
|
||||
|
@ -513,7 +512,7 @@ impl Server {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -659,12 +658,12 @@ impl Server {
|
|||
Err(err) => panic!("Err: {:?}", err),
|
||||
}
|
||||
// Disconnected
|
||||
if self.conn.is_none() {
|
||||
if self.conn.read().unwrap().is_none() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if self.conn.is_some() {
|
||||
if self.conn.read().unwrap().is_some() {
|
||||
self.read_queue = Some(rx);
|
||||
}
|
||||
}
|
||||
|
@ -782,12 +781,6 @@ impl Server {
|
|||
};
|
||||
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) {
|
||||
let _ = self.conn.as_mut().unwrap().write_packet(p); // TODO handle errors
|
||||
pub fn write_packet<T: protocol::PacketType>(&self, p: T) {
|
||||
let mut conn = self.conn.write().unwrap();
|
||||
let _ = conn.as_mut().unwrap().write_packet(p); // TODO handle errors
|
||||
}
|
||||
|
||||
fn on_keep_alive_i64(
|
||||
|
@ -1079,12 +1073,13 @@ impl Server {
|
|||
|
||||
// TODO: remove wrappers and directly call on Conn
|
||||
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]) {
|
||||
let _ = self
|
||||
.conn
|
||||
let mut conn = self.conn.write().unwrap();
|
||||
let _ = conn
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.write_plugin_message(channel, data); // TODO handle errors
|
||||
|
|
Loading…
Reference in New Issue