merge commit

This commit is contained in:
MeexReay 2025-05-05 04:32:52 +03:00
commit 94bf69d420
15 changed files with 1537 additions and 1490 deletions

16
.vscode/settings.json vendored
View File

@ -1,5 +1,19 @@
{ {
"editor.fontFamily": "Fira Code", "editor.fontFamily": "Fira Code",
"editor.fontLigatures": true, "editor.fontLigatures": true,
"editor.tabSize": 4,
"editor.tabSize": 2,
"editor.insertSpaces": false,
"editor.detectIndentation": false,
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true
},
"rust-analyzer.rustfmt.extraArgs": [
"--config",
"tab_spaces=2"
]
} }

3
rustfmt.toml Normal file
View File

@ -0,0 +1,3 @@
# Пример настроек
tab_spaces = 2
hard_tabs = true

View File

@ -30,7 +30,8 @@ impl ServerContext {
} }
pub fn get_player_by_uuid(self: &Arc<Self>, uuid: Uuid) -> Option<Arc<ClientContext>> { pub fn get_player_by_uuid(self: &Arc<Self>, uuid: Uuid) -> Option<Arc<ClientContext>> {
self.clients self
.clients
.iter() .iter()
.find(|o| { .find(|o| {
let info = o.player_info(); let info = o.player_info();
@ -44,7 +45,8 @@ impl ServerContext {
} }
pub fn get_player_by_name(self: &Arc<Self>, name: &str) -> Option<Arc<ClientContext>> { pub fn get_player_by_name(self: &Arc<Self>, name: &str) -> Option<Arc<ClientContext>> {
self.clients self
.clients
.iter() .iter()
.find(|o| { .find(|o| {
let info = o.player_info(); let info = o.player_info();
@ -58,7 +60,8 @@ impl ServerContext {
} }
pub fn players(self: &Arc<Self>) -> Vec<Arc<ClientContext>> { pub fn players(self: &Arc<Self>) -> Vec<Arc<ClientContext>> {
self.clients self
.clients
.iter() .iter()
.filter(|o| o.player_info().is_some()) .filter(|o| o.player_info().is_some())
.map(|o| o.clone()) .map(|o| o.clone())

View File

@ -17,12 +17,13 @@ impl ReadWriteNBT<DynNBT> for Packet {
fn read_nbt(&mut self) -> Result<DynNBT, ServerError> { fn read_nbt(&mut self) -> Result<DynNBT, ServerError> {
let mut data = Vec::new(); let mut data = Vec::new();
let pos = self.get_ref().position(); let pos = self.get_ref().position();
self.get_mut() self
.get_mut()
.read_to_end(&mut data) .read_to_end(&mut data)
.map_err(|_| ServerError::DeNbt)?; .map_err(|_| ServerError::DeNbt)?;
let (remaining, value) = let (remaining, value) = craftflow_nbt::from_slice(&data).map_err(|_| ServerError::DeNbt)?;
craftflow_nbt::from_slice(&data).map_err(|_| ServerError::DeNbt)?; self
self.get_mut() .get_mut()
.set_position(pos + (data.len() - remaining.len()) as u64); .set_position(pos + (data.len() - remaining.len()) as u64);
Ok(value) Ok(value)
} }

View File

@ -165,12 +165,14 @@ impl ReadWriteNBT<TextComponent> for Packet {
fn read_nbt(&mut self) -> Result<TextComponent, ServerError> { fn read_nbt(&mut self) -> Result<TextComponent, ServerError> {
let mut data = Vec::new(); let mut data = Vec::new();
let pos = self.get_ref().position(); let pos = self.get_ref().position();
self.get_mut() self
.get_mut()
.read_to_end(&mut data) .read_to_end(&mut data)
.map_err(|_| ServerError::DeTextComponent)?; .map_err(|_| ServerError::DeTextComponent)?;
let (remaining, value) = let (remaining, value) =
craftflow_nbt::from_slice(&data).map_err(|_| ServerError::DeTextComponent)?; craftflow_nbt::from_slice(&data).map_err(|_| ServerError::DeTextComponent)?;
self.get_mut() self
.get_mut()
.set_position(pos + (data.len() - remaining.len()) as u64); .set_position(pos + (data.len() - remaining.len()) as u64);
Ok(value) Ok(value)
} }

View File

@ -1,7 +1,13 @@
use std::{ use std::{
collections::VecDeque, hash::Hash, net::{SocketAddr, TcpStream}, sync::{ collections::VecDeque,
atomic::{AtomicBool, Ordering}, Arc, Mutex, RwLock hash::Hash,
}, thread, time::Duration net::{SocketAddr, TcpStream},
sync::{
Arc, Mutex, RwLock,
atomic::{AtomicBool, Ordering},
},
thread,
time::Duration,
}; };
use rust_mc_proto::{MinecraftConnection, Packet}; use rust_mc_proto::{MinecraftConnection, Packet};
@ -60,7 +66,7 @@ impl ClientContext {
is_alive: AtomicBool::new(true), is_alive: AtomicBool::new(true),
position: RwLock::new((0.0, 0.0, 0.0)), position: RwLock::new((0.0, 0.0, 0.0)),
velocity: RwLock::new((0.0, 0.0, 0.0)), velocity: RwLock::new((0.0, 0.0, 0.0)),
rotation: RwLock::new((0.0, 0.0)) rotation: RwLock::new((0.0, 0.0)),
} }
} }
@ -139,17 +145,12 @@ impl ClientContext {
.packet_handlers(|o| o.on_outcoming_packet_priority()) .packet_handlers(|o| o.on_outcoming_packet_priority())
.iter() .iter()
{ {
handler.on_outcoming_packet( handler.on_outcoming_packet(self.clone(), &mut packet, &mut cancelled, state.clone())?;
self.clone(),
&mut packet,
&mut cancelled,
state.clone(),
)?;
packet.get_mut().set_position(0); packet.get_mut().set_position(0);
} }
if !cancelled { if !cancelled {
match self.conn.write().unwrap().write_packet(&packet) { match self.conn.write().unwrap().write_packet(&packet) {
Ok(_) => {}, Ok(_) => {}
Err(e) => { Err(e) => {
self.is_alive.store(false, Ordering::SeqCst); self.is_alive.store(false, Ordering::SeqCst);
return Err(e.into()); return Err(e.into());
@ -159,9 +160,7 @@ impl ClientContext {
Ok(()) Ok(())
} }
pub fn run_read_loop( pub fn run_read_loop(self: &Arc<Self>) -> Result<(), ServerError> {
self: &Arc<Self>
) -> Result<(), ServerError> {
self.read_loop.store(true, Ordering::SeqCst); self.read_loop.store(true, Ordering::SeqCst);
let mut conn = self.conn.read().unwrap().try_clone()?; // так можно делать т.к сокет это просто поинтер let mut conn = self.conn.read().unwrap().try_clone()?; // так можно делать т.к сокет это просто поинтер
@ -181,12 +180,7 @@ impl ClientContext {
.packet_handlers(|o| o.on_incoming_packet_priority()) .packet_handlers(|o| o.on_incoming_packet_priority())
.iter() .iter()
{ {
handler.on_incoming_packet( handler.on_incoming_packet(self.clone(), &mut packet, &mut cancelled, state.clone())?;
self.clone(),
&mut packet,
&mut cancelled,
state.clone(),
)?;
packet.get_mut().set_position(0); packet.get_mut().set_position(0);
} }
if !cancelled { if !cancelled {
@ -223,12 +217,7 @@ impl ClientContext {
.packet_handlers(|o| o.on_incoming_packet_priority()) .packet_handlers(|o| o.on_incoming_packet_priority())
.iter() .iter()
{ {
handler.on_incoming_packet( handler.on_incoming_packet(self.clone(), &mut packet, &mut cancelled, state.clone())?;
self.clone(),
&mut packet,
&mut cancelled,
state.clone(),
)?;
packet.get_mut().set_position(0); packet.get_mut().set_position(0);
} }
if !cancelled { if !cancelled {
@ -269,7 +258,7 @@ impl ClientContext {
} }
} }
pub fn push_packet_back(self: &Arc<Self>, packet: Packet){ pub fn push_packet_back(self: &Arc<Self>, packet: Packet) {
self.packet_buffer.lock().unwrap().push_back(packet) self.packet_buffer.lock().unwrap().push_back(packet)
} }

View File

@ -40,7 +40,8 @@ impl ProtocolHelper {
pub fn reset_chat(&self) -> Result<(), ServerError> { pub fn reset_chat(&self) -> Result<(), ServerError> {
match self.state { match self.state {
ConnectionState::Configuration => { ConnectionState::Configuration => {
self.client self
.client
.write_packet(&Packet::empty(clientbound::configuration::RESET_CHAT))?; .write_packet(&Packet::empty(clientbound::configuration::RESET_CHAT))?;
Ok(()) Ok(())
} }
@ -67,9 +68,11 @@ impl ProtocolHelper {
pub fn leave_configuration(&self) -> Result<(), ServerError> { pub fn leave_configuration(&self) -> Result<(), ServerError> {
match self.state { match self.state {
ConnectionState::Configuration => { ConnectionState::Configuration => {
self.client self
.client
.write_packet(&Packet::empty(clientbound::configuration::FINISH))?; .write_packet(&Packet::empty(clientbound::configuration::FINISH))?;
self.client self
.client
.read_packet(&[serverbound::configuration::ACKNOWLEDGE_FINISH])?; .read_packet(&[serverbound::configuration::ACKNOWLEDGE_FINISH])?;
self.client.set_state(ConnectionState::Play)?; self.client.set_state(ConnectionState::Play)?;
Ok(()) Ok(())
@ -82,9 +85,11 @@ impl ProtocolHelper {
pub fn enter_configuration(&self) -> Result<(), ServerError> { pub fn enter_configuration(&self) -> Result<(), ServerError> {
match self.state { match self.state {
ConnectionState::Play => { ConnectionState::Play => {
self.client self
.client
.write_packet(&Packet::empty(clientbound::play::START_CONFIGURATION))?; .write_packet(&Packet::empty(clientbound::play::START_CONFIGURATION))?;
self.client self
.client
.read_packet(&[serverbound::play::ACKNOWLEDGE_CONFIGURATION])?; .read_packet(&[serverbound::play::ACKNOWLEDGE_CONFIGURATION])?;
self.client.set_state(ConnectionState::Configuration)?; self.client.set_state(ConnectionState::Configuration)?;
Ok(()) Ok(())
@ -98,16 +103,20 @@ impl ProtocolHelper {
match self.state { match self.state {
ConnectionState::Play => { ConnectionState::Play => {
let time = SystemTime::now(); let time = SystemTime::now();
self.client self
.client
.write_packet(&Packet::empty(clientbound::play::PING))?; .write_packet(&Packet::empty(clientbound::play::PING))?;
self.client.read_packet(&[serverbound::play::PONG])?; self.client.read_packet(&[serverbound::play::PONG])?;
Ok(SystemTime::now().duration_since(time).unwrap()) Ok(SystemTime::now().duration_since(time).unwrap())
} }
ConnectionState::Configuration => { ConnectionState::Configuration => {
let time = SystemTime::now(); let time = SystemTime::now();
self.client self
.client
.write_packet(&Packet::empty(clientbound::configuration::PING))?; .write_packet(&Packet::empty(clientbound::configuration::PING))?;
self.client.read_packet(&[serverbound::configuration::PONG])?; self
.client
.read_packet(&[serverbound::configuration::PONG])?;
Ok(SystemTime::now().duration_since(time).unwrap()) Ok(SystemTime::now().duration_since(time).unwrap())
} }
_ => Err(ServerError::UnexpectedState), _ => Err(ServerError::UnexpectedState),
@ -217,9 +226,7 @@ impl ProtocolHelper {
pub fn send_plugin_message(&self, channel: &str, data: &[u8]) -> Result<(), ServerError> { pub fn send_plugin_message(&self, channel: &str, data: &[u8]) -> Result<(), ServerError> {
let mut packet = match self.state { let mut packet = match self.state {
ConnectionState::Configuration => { ConnectionState::Configuration => Packet::empty(clientbound::configuration::PLUGIN_MESSAGE),
Packet::empty(clientbound::configuration::PLUGIN_MESSAGE)
}
ConnectionState::Play => Packet::empty(clientbound::play::PLUGIN_MESSAGE), ConnectionState::Play => Packet::empty(clientbound::play::PLUGIN_MESSAGE),
_ => return Err(ServerError::UnexpectedState), _ => return Err(ServerError::UnexpectedState),
}; };

View File

@ -1,8 +1,17 @@
use std::{io::Cursor, sync::Arc, thread, time::{Duration, SystemTime, UNIX_EPOCH}}; use std::{
io::Cursor,
sync::Arc,
thread,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use rust_mc_proto::{read_packet, DataReader, DataWriter, Packet}; use rust_mc_proto::{DataReader, DataWriter, Packet, read_packet};
use crate::server::{data::{text_component::TextComponent, ReadWriteNBT}, player::context::ClientContext, ServerError}; use crate::server::{
ServerError,
data::{ReadWriteNBT, text_component::TextComponent},
player::context::ClientContext,
};
use super::id::*; use super::id::*;
@ -84,7 +93,11 @@ pub fn send_login(client: Arc<ClientContext>) -> Result<(), ServerError> {
client.write_packet(&packet) client.write_packet(&packet)
} }
pub fn send_game_event(client: Arc<ClientContext>, event: u8, value: f32) -> Result<(), ServerError> { pub fn send_game_event(
client: Arc<ClientContext>,
event: u8,
value: f32,
) -> Result<(), ServerError> {
let mut packet = Packet::empty(clientbound::play::GAME_EVENT); let mut packet = Packet::empty(clientbound::play::GAME_EVENT);
packet.write_byte(event)?; packet.write_byte(event)?;
@ -103,9 +116,13 @@ pub fn sync_player_pos(
vel_z: f64, vel_z: f64,
yaw: f32, yaw: f32,
pitch: f32, pitch: f32,
flags: i32 flags: i32,
) -> Result<(), ServerError> { ) -> Result<(), ServerError> {
let timestamp = (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() & 0xFFFFFFFF) as i32; let timestamp = (SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
& 0xFFFFFFFF) as i32;
let mut packet = Packet::empty(clientbound::play::SYNCHRONIZE_PLAYER_POSITION); let mut packet = Packet::empty(clientbound::play::SYNCHRONIZE_PLAYER_POSITION);
@ -186,7 +203,6 @@ pub fn send_example_chunk(client: Arc<ClientContext>, x: i32, z: i32) -> Result<
packet.write_byte(0)?; packet.write_byte(0)?;
// light data // light data
packet.write_byte(0)?; packet.write_byte(0)?;
@ -196,14 +212,16 @@ pub fn send_example_chunk(client: Arc<ClientContext>, x: i32, z: i32) -> Result<
packet.write_byte(0)?; packet.write_byte(0)?;
packet.write_byte(0)?; packet.write_byte(0)?;
client.write_packet(&packet)?; client.write_packet(&packet)?;
Ok(()) Ok(())
} }
pub fn send_keep_alive(client: Arc<ClientContext>) -> Result<(), ServerError> { pub fn send_keep_alive(client: Arc<ClientContext>) -> Result<(), ServerError> {
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64; let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
let mut packet = Packet::empty(clientbound::play::KEEP_ALIVE); let mut packet = Packet::empty(clientbound::play::KEEP_ALIVE);
packet.write_long(timestamp)?; packet.write_long(timestamp)?;
@ -221,7 +239,11 @@ pub fn send_keep_alive(client: Arc<ClientContext>) -> Result<(), ServerError> {
Ok(()) Ok(())
} }
pub fn send_system_message(client: Arc<ClientContext>, message: TextComponent, is_action_bar: bool) -> Result<(), ServerError> { pub fn send_system_message(
client: Arc<ClientContext>,
message: TextComponent,
is_action_bar: bool,
) -> Result<(), ServerError> {
let mut packet = Packet::empty(clientbound::play::SYSTEM_CHAT_MESSAGE); let mut packet = Packet::empty(clientbound::play::SYSTEM_CHAT_MESSAGE);
packet.write_nbt(&message)?; packet.write_nbt(&message)?;
packet.write_boolean(is_action_bar)?; packet.write_boolean(is_action_bar)?;
@ -232,7 +254,6 @@ pub fn send_system_message(client: Arc<ClientContext>, message: TextComponent, i
pub fn handle_play_state( pub fn handle_play_state(
client: Arc<ClientContext>, // Контекст клиента client: Arc<ClientContext>, // Контекст клиента
) -> Result<(), ServerError> { ) -> Result<(), ServerError> {
thread::spawn({ thread::spawn({
let client = client.clone(); let client = client.clone();
@ -263,7 +284,7 @@ pub fn handle_play_state(
let _ = packet.read_byte()?; // flags let _ = packet.read_byte()?; // flags
client.set_position((x, y, z)); client.set_position((x, y, z));
}, }
serverbound::play::SET_PLAYER_POSITION_AND_ROTATION => { serverbound::play::SET_PLAYER_POSITION_AND_ROTATION => {
let x = packet.read_double()?; let x = packet.read_double()?;
let y = packet.read_double()?; let y = packet.read_double()?;
@ -274,14 +295,14 @@ pub fn handle_play_state(
client.set_position((x, y, z)); client.set_position((x, y, z));
client.set_rotation((yaw, pitch)); client.set_rotation((yaw, pitch));
}, }
serverbound::play::SET_PLAYER_ROTATION => { serverbound::play::SET_PLAYER_ROTATION => {
let yaw = packet.read_float()?; let yaw = packet.read_float()?;
let pitch = packet.read_float()?; let pitch = packet.read_float()?;
let _ = packet.read_byte()?; // flags let _ = packet.read_byte()?; // flags
client.set_rotation((yaw, pitch)); client.set_rotation((yaw, pitch));
}, }
_ => { _ => {
client.push_packet_back(packet); client.push_packet_back(packet);
} }
@ -296,20 +317,27 @@ pub fn handle_play_state(
while client.is_alive() { while client.is_alive() {
println!("{ticks_alive}"); println!("{ticks_alive}");
if ticks_alive % 200 == 0 { // 10 secs timer if ticks_alive % 200 == 0 {
// 10 secs timer
send_keep_alive(client.clone())?; send_keep_alive(client.clone())?;
} }
if ticks_alive % 20 == 0 { // 1 sec timer if ticks_alive % 20 == 0 {
// 1 sec timer
let (x, y, z) = client.position(); let (x, y, z) = client.position();
send_system_message(client.clone(), send_system_message(
TextComponent::rainbow(format!( client.clone(),
"Pos: {} {} {}", x as i64, y as i64, z as i64 TextComponent::rainbow(format!("Pos: {} {} {}", x as i64, y as i64, z as i64)),
)), false)?; false,
)?;
} }
send_system_message(client.clone(), TextComponent::rainbow(format!("Ticks alive: {}", ticks_alive)), true)?; send_system_message(
client.clone(),
TextComponent::rainbow(format!("Ticks alive: {}", ticks_alive)),
true,
)?;
thread::sleep(Duration::from_millis(50)); // 1 tick thread::sleep(Duration::from_millis(50)); // 1 tick
ticks_alive += 1; ticks_alive += 1;