Stuck before sending chunk data

This commit is contained in:
Garen Tyler 2021-03-05 08:55:04 -07:00
parent e923e2ad3c
commit a0cebf6d44
4 changed files with 203 additions and 28 deletions

View File

@ -1,5 +1,5 @@
use crate::world::location::Location;
use crate::server::NetworkClient;
use crate::world::location::Location;
pub struct Player {
position: Location,

View File

@ -1,13 +1,13 @@
/// Definitions for all the packets in the Minecraft protocol.
pub mod packets;
use crate::entity::player::Player;
use crate::{mctypes::*, CONFIG, FAVICON};
use log::{debug, info};
use packets::*;
use serde_json::json;
use std::sync::mpsc::{self, Receiver, TryRecvError};
use tokio::net::{TcpListener, TcpStream, ToSocketAddrs};
use crate::entity::player::Player;
/// The struct containing all the data and running all the updates.
pub struct Server {
@ -29,7 +29,7 @@ impl Server {
.await
.expect("Network receiver disconnected");
tx.send(NetworkClient::new(stream, id as u128))
.expect("Network receiver disconnected");
.expect("Network receiver disconnected");
id += 1;
}
});
@ -202,24 +202,35 @@ impl NetworkClient {
self.username = Some(loginsuccess.username.clone().into());
self.state = NetworkClientState::Play;
let joingame = JoinGame::new();
/// TODO: Fill out `joingame` with actual information.
// TODO: Fill out `joingame` with actual information.
joingame.write(&mut self.stream).await.unwrap();
debug!("{:?}", joingame);
let (packet_length, packet_id) =
let (_packet_length, _packet_id) =
read_packet_header(&mut self.stream).await.unwrap();
let clientsettings = ClientSettings::read(&mut self.stream).await.unwrap();
// TODO: Actualy use client settings.
debug!("{:?}", clientsettings);
// TODO: S->C Held Item Change
// TODO: S->C Declare Recipes
// TODO: S->C Tags
// TODO: S->C Entity Status
// TODO: S->C Declare Commands
// TODO: S->C Unlock Recipes
// All good up to here.
let helditemchange = HeldItemChange::new();
// TODO: Retrieve selected slot from storage.
helditemchange.write(&mut self.stream).await.unwrap();
debug!("{:?}", helditemchange);
// TODO: S->C Declare Recipes (1.16?)
// TODO: S->C Tags (1.16?)
// TODO: S->C Entity Status (optional?)
// TODO: S->C Declare Commands (1.16?)
// TODO: S->C Unlock Recipes (1.16?)
// TODO: S->C Player Position and Look
// TODO: S->C Player Info (Add Player action)
// TODO: S->C Player Info (Update latency action)
// TODO: S->C Update View Position
// TODO: S->C Update Light
let playerpositionandlook = PlayerPositionAndLook::new();
// TODO: Retrieve player position from storage.
// playerpositionandlook.write(&mut self.stream).await.unwrap();
debug!("{:?}", playerpositionandlook);
// TODO: S->C Player Info (Add Player action) (1.16?)
// TODO: S->C Player Info (Update latency action) (1.16?)
// TODO: S->C Update View Position (1.16?)
// TODO: S->C Update Light (1.16?)
// TODO: S->C Chunk Data
// TODO: S->C World Border
// TODO: S->C Spawn Position

View File

@ -167,12 +167,12 @@ impl LoginDisconnect {
#[derive(Debug, Clone)]
pub struct JoinGame {
entity_id: MCInt, // The player's Entity ID (EID)
entity_id: MCInt, // The player's Entity ID (EID)
gamemode: MCUnsignedByte, // 0: Survival, 1: Creative, 2: Adventure, 3: Spectator. Bit 3 (0x8) is the hardcore flag.
dimension: MCByte, // -1: Nether, 0: Overworld, 1: End
dimension: MCByte, // -1: Nether, 0: Overworld, 1: End
difficulty: MCUnsignedByte, // 0: Peaceful, 1: Easy, 2: Normal, 3: Hard
max_players: MCUnsignedByte, // Used by the client to draw the player list
level_type: MCString, // default, flat, largeBiomes, amplified, default_1_1
level_type: MCString, // default, flat, largeBiomes, amplified, default_1_1
reduced_debug_info: MCBoolean, // If true, a Notchian client shows reduced information on the debug screen.
}
impl Into<Vec<u8>> for JoinGame {
@ -201,7 +201,7 @@ impl JoinGame {
pub fn new() -> Self {
JoinGame {
entity_id: 0.into(),
gamemode: 1.into(), // Default to creative mode.
gamemode: 1.into(), // Default to creative mode.
dimension: 0.into(), // Default to overworld.
difficulty: 2.into(),
max_players: (CONFIG.max_players as u8).into(),
@ -227,3 +227,167 @@ impl JoinGame {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct HeldItemChange {
selected_slot: MCByte,
}
impl Into<Vec<u8>> for HeldItemChange {
fn into(self) -> Vec<u8> {
let mut out = vec![];
let mut temp: Vec<u8> = MCVarInt::from(0x09).into(); // 0x09 Held Item Change.
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.selected_slot));
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 HeldItemChange {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("unimplemented")
}
}
impl HeldItemChange {
pub fn new() -> Self {
HeldItemChange {
selected_slot: 0.into(),
}
}
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
let mut helditemchange = HeldItemChange::new();
helditemchange.selected_slot = MCByte::read(t).await?;
Ok(helditemchange)
}
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(())
}
}
#[derive(Debug, Clone)]
pub struct EntityStatus {
entity_id: MCInt,
entity_status: MCByte, // See table below.
// 1: Sent when resetting a mob spawn minecart's timer / Rabbit jump animation
// 2: Living Entity hurt
// 3: Living Entity dead
// 4: Iron Golem throwing up arms
// 6: Wolf/Ocelot/Horse taming — Spawn “heart” particles
// 7: Wolf/Ocelot/Horse tamed — Spawn “smoke” particles
// 8: Wolf shaking water — Trigger the shaking animation
// 9: (of self) Eating accepted by server
// 10: Sheep eating grass
// 10: Play TNT ignite sound
// 11: Iron Golem handing over a rose
// 12: Villager mating — Spawn “heart” particles
// 13: Spawn particles indicating that a villager is angry and seeking revenge
// 14: Spawn happy particles near a villager
// 15: Witch animation — Spawn “magic” particles
// 16: Play zombie converting into a villager sound
// 17: Firework exploding
// 18: Animal in love (ready to mate) — Spawn “heart” particles
// 19: Reset squid rotation
// 20: Spawn explosion particle — works for some living entities
// 21: Play guardian sound — works for only for guardians
// 22: Enables reduced debug for players
// 23: Disables reduced debug for players
}
impl Into<Vec<u8>> for EntityStatus {
fn into(self) -> Vec<u8> {
let mut out = vec![];
let mut temp: Vec<u8> = MCVarInt::from(0x1a).into(); // 0x1a Entity Status.
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.entity_id));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.entity_status));
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 EntityStatus {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("unimplemented")
}
}
impl EntityStatus {
pub fn new() -> Self {
EntityStatus {
entity_id: 0.into(),
entity_status: 0.into(),
}
}
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
let mut entitystatus = EntityStatus::new();
entitystatus.entity_id = MCInt::read(t).await?;
entitystatus.entity_status = MCByte::read(t).await?;
Ok(entitystatus)
}
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(())
}
}
#[derive(Debug, Clone)]
pub struct PlayerPositionAndLook {
x: MCDouble,
y: MCDouble,
z: MCDouble,
yaw: MCFloat,
pitch: MCFloat,
flags: MCByte,
}
impl Into<Vec<u8>> for PlayerPositionAndLook {
fn into(self) -> Vec<u8> {
let mut out = vec![];
let mut temp: Vec<u8> = MCVarInt::from(0x08).into(); // 0x08 Player Position and Look.
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.x));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.y));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.z));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.yaw));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.pitch));
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.flags));
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 PlayerPositionAndLook {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("unimplemented")
}
}
impl PlayerPositionAndLook {
pub fn new() -> Self {
PlayerPositionAndLook {
x: 0.0.into(),
y: 0.0.into(),
z: 0.0.into(),
yaw: 0.0.into(),
pitch: 0.0.into(),
flags: 0x00.into(),
}
}
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
let mut playerpositionandlook = PlayerPositionAndLook::new();
playerpositionandlook.x = MCDouble::read(t).await?;
playerpositionandlook.y = MCDouble::read(t).await?;
playerpositionandlook.z = MCDouble::read(t).await?;
playerpositionandlook.yaw = MCFloat::read(t).await?;
playerpositionandlook.pitch = MCFloat::read(t).await?;
playerpositionandlook.flags = MCByte::read(t).await?;
Ok(playerpositionandlook)
}
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(())
}
}

View File

@ -170,14 +170,14 @@ pub struct ClientSettings {
pub chat_mode: MCVarInt, // 0: enabled, 1: commands only, 2: hidden.
pub chat_colors: MCBoolean,
pub displayed_skin_parts: MCUnsignedByte, // Bit mask
// Displayed skin parts flags:
// Bit 0 (0x01): Cape enabled
// Bit 1 (0x02): Jacket enabled
// Bit 2 (0x04): Left Sleeve enabled
// Bit 3 (0x08): Right Sleeve enabled
// Bit 4 (0x10): Left Pants Leg enabled
// Bit 5 (0x20): Right Pants Leg enabled
// Bit 6 (0x40): Hat enabled
// Displayed skin parts flags:
// Bit 0 (0x01): Cape enabled
// Bit 1 (0x02): Jacket enabled
// Bit 2 (0x04): Left Sleeve enabled
// Bit 3 (0x08): Right Sleeve enabled
// Bit 4 (0x10): Left Pants Leg enabled
// Bit 5 (0x20): Right Pants Leg enabled
// Bit 6 (0x40): Hat enabled
}
impl Into<Vec<u8>> for ClientSettings {
fn into(self) -> Vec<u8> {
@ -204,7 +204,7 @@ impl ClientSettings {
ClientSettings {
locale: "en_US".into(),
view_distance: 8.into(), // 8 chunks.
chat_mode: 0.into(), // All chat enabled.
chat_mode: 0.into(), // All chat enabled.
chat_colors: true.into(),
displayed_skin_parts: 0xff.into(), // Enable all parts.
}