Skip to content

Commit

Permalink
added level system
Browse files Browse the repository at this point in the history
  • Loading branch information
flafmg committed Jul 28, 2024
1 parent ad5ab20 commit 68ee574
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 57 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
/target
Cargo.lock
/maps
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2021"
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
async-trait = "0.1"
flate2 = "1.0.30"
1 change: 1 addition & 0 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod network;
pub mod server;
pub mod world;
5 changes: 4 additions & 1 deletion src/server/network/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ pub trait PacketTrait {
fn packet_id(&self) -> u8;
fn write(&mut self, writer: &mut PacketWriter);
fn read(&mut self, reader: &mut PacketReader);
async fn resolve(&self, socket: &mut TcpStream);
async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
}
2 changes: 1 addition & 1 deletion src/server/network/packet_stream/packet_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl PacketWriter {

pub fn write_byte_array(&mut self, value: &[u8], size: usize) {
let mut bytes = value.to_vec();
bytes.resize(size, 0);
bytes.resize(size, 0x00);
self.data.extend(&bytes);
}

Expand Down
182 changes: 129 additions & 53 deletions src/server/network/packets/clientbound.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
use async_trait::async_trait;
use tokio::{io::AsyncWriteExt, net::TcpStream};
use std::io::Write;
use std::time::Duration;

use crate::server::network::{
packet::PacketTrait,
packet_stream::{packet_reader::PacketReader, packet_writer::PacketWriter},
use async_trait::async_trait;
use flate2::write::GzEncoder;
use flate2::Compression;
use tokio::net::TcpStream;
use tokio::{io::AsyncWriteExt, time::sleep};

use crate::server::{
network::{
packet::PacketTrait,
packet_stream::{packet_reader::PacketReader, packet_writer::PacketWriter},
},
world::dmf_world::DmfWorld,
};

// server indentification packet
// server identification packet

pub struct ServerIdentificationPacket {
data: Vec<u8>,
Expand All @@ -17,19 +26,20 @@ pub struct ServerIdentificationPacket {
}
impl ServerIdentificationPacket {
pub fn new() -> Self {
return Self {
Self {
data: Vec::new(),
protocol_version: 0x07,
server_name: "dandelion".to_string(),
server_motd: "hello mom!".to_string(),
user_type: 0x64,
};
}
}
}

#[async_trait]
impl PacketTrait for ServerIdentificationPacket {
fn packet_id(&self) -> u8 {
return 0x00;
0x00
}
fn write(&mut self, writer: &mut PacketWriter) {
writer.write_byte(self.packet_id());
Expand All @@ -39,16 +49,19 @@ impl PacketTrait for ServerIdentificationPacket {
writer.write_byte(self.user_type);
self.data = writer.to_bytes().clone();
}
fn read(&mut self, reader: &mut PacketReader) {}
fn read(&mut self, _reader: &mut PacketReader) {}

async fn resolve(&self, socket: &mut TcpStream) {
if socket.write_all(&self.data).await.is_err() {
println!("Error sending packet id {}", self.packet_id())
}
async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
socket.write_all(&self.data).await?;
let mut resolve_packet_response = LevelInitializePacket::new();
let mut paclet_writer = PacketWriter::new();
resolve_packet_response.write(&mut paclet_writer);
resolve_packet_response.resolve(socket).await;
let mut packet_writer = PacketWriter::new();
resolve_packet_response.write(&mut packet_writer);
resolve_packet_response.resolve(socket).await?;

Ok(())
}
}

Expand All @@ -59,60 +72,117 @@ pub struct LevelInitializePacket {
}
impl LevelInitializePacket {
pub fn new() -> Self {
return Self { data: Vec::new() };
Self { data: Vec::new() }
}
}

#[async_trait]
impl PacketTrait for LevelInitializePacket {
fn packet_id(&self) -> u8 {
return 0x02;
0x02
}
fn write(&mut self, writer: &mut PacketWriter) {
writer.write_byte(self.packet_id());
self.data = writer.to_bytes().clone();
}
fn read(&mut self, reader: &mut PacketReader) {}

async fn resolve(&self, socket: &mut TcpStream) {
if socket.write_all(&self.data).await.is_err() {
println!("Error sending packet id {}", self.packet_id())
fn read(&mut self, _reader: &mut PacketReader) {}

async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
socket.write_all(&self.data).await?;

let mut world = DmfWorld::load_file("maps/default.dmf").unwrap();
let block_data = world.blocks;

let total_length = block_data.len();
let mut prefixed_data = Vec::with_capacity(4 + total_length);
prefixed_data.extend_from_slice(&(total_length as u32).to_be_bytes());
prefixed_data.extend_from_slice(&block_data);

//im dumb i needed to compress this shit
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(&prefixed_data).unwrap();
let compressed_data = encoder.finish().unwrap();
let chunk_size = 1024;

for (i, chunk) in compressed_data.chunks(chunk_size).enumerate() {
let chunk_length = chunk.len() as i16;
let percent_complete = ((i * chunk_size + chunk_length as usize) as f32
/ compressed_data.len() as f32
* 100.0) as u8;

let mut chunk_data = chunk.to_vec();
if chunk_data.len() < chunk_size {
chunk_data.resize(chunk_size, 0x00);
}

let mut packet = LevelDataChunkPacket::new(chunk_length, chunk_data, percent_complete);
let mut packet_writer = PacketWriter::new();
packet.write(&mut packet_writer);

if let Err(e) = packet.resolve(socket).await {
println!("Error sending chunk {}: {}", i, e);
break;
}

sleep(Duration::from_secs(1)).await;
}
let mut resolve_packet_response = LevelFinalizePacket::new(100, 100, 100);
let mut paclet_writer = PacketWriter::new();
resolve_packet_response.write(&mut paclet_writer);
resolve_packet_response.resolve(socket).await;

let mut level_finalize = LevelFinalizePacket::new(world.x_size, world.y_size, world.z_size);
let mut packet_writer = PacketWriter::new();
level_finalize.write(&mut packet_writer);
level_finalize.resolve(socket).await?;

Ok(())
}
}

// level data chunk packet

pub struct LevelDataChunkPacket {
chunk_lenght: u16,
data: Vec<u8>,
chunk_length: i16,
chunk_data: Vec<u8>,
percent_complete: u8,
completed: u8,
}

impl LevelDataChunkPacket {
pub fn new() -> Self {
return Self {
chunk_lenght: 0,
chunk_data: Vec::new(),
percent_complete: 0,
};
pub fn new(chunk_length: i16, chunk_data: Vec<u8>, completed: u8) -> Self {
Self {
data: Vec::new(),
chunk_length,
chunk_data,
completed,
}
}
}

#[async_trait]
impl PacketTrait for LevelDataChunkPacket {
fn packet_id(&self) -> u8 {
return 0x03;
0x03
}
fn write(&mut self, writer: &mut PacketWriter) {
writer.write_byte(self.packet_id());
writer.write_short(self.chunk_length);
writer.write_byte_array(self.chunk_data.as_slice(), 1024);
writer.write_byte(self.completed);
self.data = writer.to_bytes().clone();
}
fn read(&mut self, _reader: &mut PacketReader) {}

async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
socket.write_all(&self.data).await?;
Ok(())
}
fn write(&mut self, writer: &mut PacketWriter) {}
fn read(&mut self, reader: &mut PacketReader) {}
async fn resolve(&self, socket: &mut TcpStream) {}
}

// leval finalize packet
// level finalize packet

pub struct LevelFinalizePacket {
data: Vec<u8>,
Expand All @@ -123,12 +193,12 @@ pub struct LevelFinalizePacket {

impl LevelFinalizePacket {
pub fn new(x_size: i16, y_size: i16, z_size: i16) -> Self {
return Self {
Self {
data: Vec::new(),
x_size,
y_size,
z_size,
};
}
}
}

Expand All @@ -144,24 +214,30 @@ impl PacketTrait for LevelFinalizePacket {
writer.write_short(self.z_size);
self.data = writer.to_bytes().clone();
}
fn read(&mut self, reader: &mut PacketReader) {}
async fn resolve(&self, socket: &mut TcpStream) {
if socket.write_all(&self.data).await.is_err() {
println!("Error sending packet id {}", self.packet_id())
}
fn read(&mut self, _reader: &mut PacketReader) {}
async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
socket.write_all(&self.data).await?;

Ok(())
}
}

/*
fn packet_id(&self) -> u8 {
return 0x00;
}
fn write(&mut self, writer: &mut PacketWriter) {}
fn read(&mut self, reader: &mut PacketReader) {}
async fn resolve(&self, socket: &mut TcpStream) {
async fn resolve(&self, socket: &mut TcpStream) {
if socket.write_all(&self.data).await.is_err() {
println!("Error sending packet id {}", self.packet_id())
}
}
async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
socket.write_all(&self.data).await?;
Ok(())
}
*/
9 changes: 7 additions & 2 deletions src/server/network/packets/serverbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,16 @@ impl PacketTrait for PlayerIndentificationPacket {
self.username, self.protocol_version
)
}
async fn resolve(&self, socket: &mut TcpStream) {
async fn resolve(
&self,
socket: &mut TcpStream,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut resolve_packet_response = ServerIdentificationPacket::new();
let mut paclet_writer = PacketWriter::new();
resolve_packet_response.write(&mut paclet_writer);
resolve_packet_response.resolve(socket).await;
resolve_packet_response.resolve(socket).await?;

Ok(())
}
}

Expand Down
Loading

0 comments on commit 68ee574

Please sign in to comment.