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.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>> {
self.clients
self
.clients
.iter()
.find(|o| {
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>> {
self.clients
self
.clients
.iter()
.find(|o| {
let info = o.player_info();
@ -58,7 +60,8 @@ impl ServerContext {
}
pub fn players(self: &Arc<Self>) -> Vec<Arc<ClientContext>> {
self.clients
self
.clients
.iter()
.filter(|o| o.player_info().is_some())
.map(|o| o.clone())

View File

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

View File

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

View File

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

View File

@ -40,7 +40,8 @@ impl ProtocolHelper {
pub fn reset_chat(&self) -> Result<(), ServerError> {
match self.state {
ConnectionState::Configuration => {
self.client
self
.client
.write_packet(&Packet::empty(clientbound::configuration::RESET_CHAT))?;
Ok(())
}
@ -67,9 +68,11 @@ impl ProtocolHelper {
pub fn leave_configuration(&self) -> Result<(), ServerError> {
match self.state {
ConnectionState::Configuration => {
self.client
self
.client
.write_packet(&Packet::empty(clientbound::configuration::FINISH))?;
self.client
self
.client
.read_packet(&[serverbound::configuration::ACKNOWLEDGE_FINISH])?;
self.client.set_state(ConnectionState::Play)?;
Ok(())
@ -82,9 +85,11 @@ impl ProtocolHelper {
pub fn enter_configuration(&self) -> Result<(), ServerError> {
match self.state {
ConnectionState::Play => {
self.client
self
.client
.write_packet(&Packet::empty(clientbound::play::START_CONFIGURATION))?;
self.client
self
.client
.read_packet(&[serverbound::play::ACKNOWLEDGE_CONFIGURATION])?;
self.client.set_state(ConnectionState::Configuration)?;
Ok(())
@ -98,16 +103,20 @@ impl ProtocolHelper {
match self.state {
ConnectionState::Play => {
let time = SystemTime::now();
self.client
self
.client
.write_packet(&Packet::empty(clientbound::play::PING))?;
self.client.read_packet(&[serverbound::play::PONG])?;
Ok(SystemTime::now().duration_since(time).unwrap())
}
ConnectionState::Configuration => {
let time = SystemTime::now();
self.client
self
.client
.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())
}
_ => Err(ServerError::UnexpectedState),
@ -217,9 +226,7 @@ impl ProtocolHelper {
pub fn send_plugin_message(&self, channel: &str, data: &[u8]) -> Result<(), ServerError> {
let mut packet = match self.state {
ConnectionState::Configuration => {
Packet::empty(clientbound::configuration::PLUGIN_MESSAGE)
}
ConnectionState::Configuration => Packet::empty(clientbound::configuration::PLUGIN_MESSAGE),
ConnectionState::Play => Packet::empty(clientbound::play::PLUGIN_MESSAGE),
_ => 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::*;
@ -84,7 +93,11 @@ pub fn send_login(client: Arc<ClientContext>) -> Result<(), ServerError> {
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);
packet.write_byte(event)?;
@ -103,9 +116,13 @@ pub fn sync_player_pos(
vel_z: f64,
yaw: f32,
pitch: f32,
flags: i32
flags: i32,
) -> 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);
@ -186,7 +203,6 @@ pub fn send_example_chunk(client: Arc<ClientContext>, x: i32, z: i32) -> Result<
packet.write_byte(0)?;
// light data
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)?;
client.write_packet(&packet)?;
Ok(())
}
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);
packet.write_long(timestamp)?;
@ -221,7 +239,11 @@ pub fn send_keep_alive(client: Arc<ClientContext>) -> Result<(), ServerError> {
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);
packet.write_nbt(&message)?;
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(
client: Arc<ClientContext>, // Контекст клиента
) -> Result<(), ServerError> {
thread::spawn({
let client = client.clone();
@ -263,7 +284,7 @@ pub fn handle_play_state(
let _ = packet.read_byte()?; // flags
client.set_position((x, y, z));
},
}
serverbound::play::SET_PLAYER_POSITION_AND_ROTATION => {
let x = 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_rotation((yaw, pitch));
},
}
serverbound::play::SET_PLAYER_ROTATION => {
let yaw = packet.read_float()?;
let pitch = packet.read_float()?;
let _ = packet.read_byte()?; // flags
client.set_rotation((yaw, pitch));
},
}
_ => {
client.push_packet_back(packet);
}
@ -296,20 +317,27 @@ pub fn handle_play_state(
while client.is_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())?;
}
if ticks_alive % 20 == 0 { // 1 sec timer
if ticks_alive % 20 == 0 {
// 1 sec timer
let (x, y, z) = client.position();
send_system_message(client.clone(),
TextComponent::rainbow(format!(
"Pos: {} {} {}", x as i64, y as i64, z as i64
)), false)?;
send_system_message(
client.clone(),
TextComponent::rainbow(format!("Pos: {} {} {}", x as i64, y as i64, z as i64)),
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
ticks_alive += 1;