mirror of
https://github.com/GIKExe/rust_mc_serv.git
synced 2025-06-24 02:12:58 +03:00
send players
This commit is contained in:
parent
4036be8cc1
commit
8b5084460e
64
Cargo.lock
generated
64
Cargo.lock
generated
@ -109,6 +109,15 @@ version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.17.0"
|
||||
@ -214,6 +223,16 @@ version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.11"
|
||||
@ -273,6 +292,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
@ -330,6 +359,16 @@ version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@ -495,6 +534,16 @@ version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
@ -967,6 +1016,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
@ -984,6 +1039,15 @@ name = "uuid"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||
dependencies = [
|
||||
"md-5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
|
@ -17,7 +17,7 @@ palette = "0.7.6"
|
||||
craftflow-nbt = "2.1.0"
|
||||
colog = "1.3.0"
|
||||
log = "0.4.27"
|
||||
uuid = "1.16.0"
|
||||
uuid = { version = "1.16.0", features = ["v3"] }
|
||||
dashmap = "6.1.0"
|
||||
paste = "1.0.15"
|
||||
ignore-result = "0.2.0"
|
||||
|
@ -1,4 +1,7 @@
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
use std::{
|
||||
net::SocketAddr,
|
||||
sync::{Arc, atomic::AtomicI32},
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use itertools::Itertools;
|
||||
@ -15,6 +18,7 @@ use super::{
|
||||
pub struct ServerContext {
|
||||
pub config: Arc<Config>,
|
||||
pub clients: DashMap<SocketAddr, Arc<ClientContext>>,
|
||||
pub world: WorldContext,
|
||||
listeners: Vec<Box<dyn Listener>>,
|
||||
handlers: Vec<Box<dyn PacketHandler>>,
|
||||
}
|
||||
@ -26,6 +30,7 @@ impl ServerContext {
|
||||
listeners: Vec::new(),
|
||||
handlers: Vec::new(),
|
||||
clients: DashMap::new(),
|
||||
world: WorldContext::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,3 +97,15 @@ impl ServerContext {
|
||||
self.listeners.iter().sorted_by_key(sort_by).collect_vec()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WorldContext {
|
||||
pub entity_id_counter: AtomicI32,
|
||||
}
|
||||
|
||||
impl WorldContext {
|
||||
pub fn new() -> WorldContext {
|
||||
WorldContext {
|
||||
entity_id_counter: AtomicI32::new(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::{sync::Arc, thread, time::Duration};
|
||||
|
||||
use config::handle_configuration_state;
|
||||
@ -6,7 +7,9 @@ use helper::{
|
||||
unload_chunk,
|
||||
};
|
||||
use rust_mc_proto::{DataReader, DataWriter, Packet};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::player::context::EntityInfo;
|
||||
use crate::{
|
||||
ServerError, data::text_component::TextComponent, event::PacketHandler,
|
||||
player::context::ClientContext,
|
||||
@ -57,7 +60,7 @@ pub fn send_login(client: Arc<ClientContext>) -> Result<(), ServerError> {
|
||||
// Отправка пакета Login
|
||||
let mut packet = Packet::empty(clientbound::play::LOGIN);
|
||||
|
||||
packet.write_int(0)?; // Entity ID
|
||||
packet.write_int(client.entity_info().entity_id)?; // Entity ID
|
||||
packet.write_boolean(false)?; // Is hardcore
|
||||
packet.write_varint(4)?; // Dimension Names
|
||||
packet.write_string("minecraft:overworld")?;
|
||||
@ -96,10 +99,13 @@ pub fn send_example_chunk(client: Arc<ClientContext>, x: i32, z: i32) -> Result<
|
||||
// heightmap
|
||||
|
||||
packet.write_varint(1)?; // heightmaps count
|
||||
packet.write_varint(0)?; // MOTION_BLOCKING
|
||||
packet.write_varint(256)?; // Length of the following long array (16 * 16 = 256)
|
||||
for _ in 0..256 {
|
||||
packet.write_long(0)?; // height - 0
|
||||
packet.write_varint(0)?; // MOTION_BLOCKING - 0
|
||||
// bits per entry is ceil(log2(385)) = 9 where 385 is the world height
|
||||
// so, the length of the following array is (9 * 16 * 16) / 8 = 37
|
||||
// ... idk how it came to that
|
||||
packet.write_varint(37)?; // Length of the following long array
|
||||
for _ in 0..37 {
|
||||
packet.write_long(0)?; // THIS WORKS ONLY BECAUSE OUR HEIGHT IS 0
|
||||
}
|
||||
|
||||
// sending chunk data
|
||||
@ -117,7 +123,7 @@ pub fn send_example_chunk(client: Arc<ClientContext>, x: i32, z: i32) -> Result<
|
||||
|
||||
// biomes palleted container
|
||||
chunk_data.write_byte(0)?; // Bits Per Entry, use Single valued palette format
|
||||
chunk_data.write_varint(27)?; // biome id in the registry
|
||||
chunk_data.write_varint(1)?; // biome id in the registry
|
||||
}
|
||||
|
||||
// air chunk sections
|
||||
@ -181,10 +187,60 @@ pub fn send_example_chunks_in_distance(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn send_player(
|
||||
receiver: Arc<ClientContext>,
|
||||
player: Arc<ClientContext>,
|
||||
) -> Result<(), ServerError> {
|
||||
// Отправка пакета Login
|
||||
let mut packet = Packet::empty(clientbound::play::SPAWN_ENTITY);
|
||||
|
||||
let (x, y, z) = player.entity_info().position();
|
||||
let (yaw, pitch) = player.entity_info().rotation();
|
||||
let (vel_x, vel_y, vel_z) = player.entity_info().velocity();
|
||||
|
||||
packet.write_varint(player.entity_info().entity_id)?; // Entity ID
|
||||
packet.write_uuid(&player.entity_info().uuid)?; // Entity UUID
|
||||
packet.write_varint(148)?; // Entity type TODO: move to const
|
||||
packet.write_double(x)?;
|
||||
packet.write_double(y)?;
|
||||
packet.write_double(z)?;
|
||||
packet.write_byte((pitch / 360.0 * 256.0) as u8)?;
|
||||
packet.write_byte((yaw / 360.0 * 256.0) as u8)?;
|
||||
packet.write_byte((yaw / 360.0 * 256.0) as u8)?; // head yaw TODO: make player head yaw field
|
||||
packet.write_varint(0)?;
|
||||
packet.write_short(vel_x as i16)?;
|
||||
packet.write_short(vel_y as i16)?;
|
||||
packet.write_short(vel_z as i16)?;
|
||||
|
||||
receiver.write_packet(&packet)
|
||||
}
|
||||
|
||||
pub fn get_offline_uuid(name: &str) -> Uuid {
|
||||
let mut namespaces_bytes: [u8; 16] = [0; 16];
|
||||
for (i, byte) in format!("OfflinePlayer:{}", &name[..2])
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
namespaces_bytes[i] = *byte;
|
||||
}
|
||||
let namespace = Uuid::from_bytes(namespaces_bytes);
|
||||
Uuid::new_v3(&namespace, (&name[2..]).as_bytes())
|
||||
}
|
||||
|
||||
// Отдельная функция для работы с самой игрой
|
||||
pub fn handle_play_state(
|
||||
client: Arc<ClientContext>, // Контекст клиента
|
||||
) -> Result<(), ServerError> {
|
||||
client.set_entity_info(EntityInfo::new(
|
||||
client
|
||||
.server
|
||||
.world
|
||||
.entity_id_counter
|
||||
.fetch_add(1, Ordering::SeqCst),
|
||||
get_offline_uuid(&client.player_info().unwrap().name), // TODO: authenticated uuid
|
||||
));
|
||||
|
||||
thread::spawn({
|
||||
let client = client.clone();
|
||||
|
||||
@ -195,7 +251,7 @@ pub fn handle_play_state(
|
||||
});
|
||||
|
||||
send_login(client.clone())?;
|
||||
sync_player_pos(client.clone(), 8.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0)?; // idk why, but now you need to set y to 3 here
|
||||
sync_player_pos(client.clone(), 8.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0)?;
|
||||
send_game_event(client.clone(), 13, 0.0)?; // 13 - Start waiting for level chunks
|
||||
set_center_chunk(client.clone(), 0, 0)?;
|
||||
|
||||
@ -207,12 +263,21 @@ pub fn handle_play_state(
|
||||
|
||||
// sync_player_pos(client.clone(), 8.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0)?;
|
||||
|
||||
for player in client.server.players() {
|
||||
send_player(client.clone(), player.clone())?;
|
||||
send_player(player.clone(), client.clone())?;
|
||||
}
|
||||
|
||||
thread::spawn({
|
||||
let client = client.clone();
|
||||
|
||||
move || -> Result<(), ServerError> {
|
||||
while client.is_alive() {
|
||||
let mut packet = client.read_any_packet()?;
|
||||
let mut packet = client.read_packet(&[
|
||||
serverbound::play::SET_PLAYER_POSITION,
|
||||
serverbound::play::SET_PLAYER_POSITION_AND_ROTATION,
|
||||
serverbound::play::SET_PLAYER_ROTATION,
|
||||
])?;
|
||||
|
||||
match packet.id() {
|
||||
serverbound::play::SET_PLAYER_POSITION => {
|
||||
@ -221,7 +286,7 @@ pub fn handle_play_state(
|
||||
let z = packet.read_double()?;
|
||||
let _ = packet.read_byte()?; // flags
|
||||
|
||||
client.set_position((x, y, z));
|
||||
client.entity_info().set_position((x, y, z));
|
||||
}
|
||||
serverbound::play::SET_PLAYER_POSITION_AND_ROTATION => {
|
||||
let x = packet.read_double()?;
|
||||
@ -231,19 +296,17 @@ pub fn handle_play_state(
|
||||
let pitch = packet.read_float()?;
|
||||
let _ = packet.read_byte()?; // flags
|
||||
|
||||
client.set_position((x, y, z));
|
||||
client.set_rotation((yaw, pitch));
|
||||
client.entity_info().set_position((x, y, z));
|
||||
client.entity_info().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);
|
||||
client.entity_info().set_rotation((yaw, pitch));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +324,7 @@ pub fn handle_play_state(
|
||||
|
||||
if ticks_alive % 20 == 0 {
|
||||
// 1 sec timer
|
||||
let (x, _, z) = client.position();
|
||||
let (x, _, z) = client.entity_info().position();
|
||||
|
||||
let (chunk_x, chunk_z) = ((x / 16.0) as i64, (z / 16.0) as i64);
|
||||
let (chunk_x, chunk_z) = (chunk_x as i32, chunk_z as i32);
|
||||
|
@ -29,9 +29,7 @@ pub struct ClientContext {
|
||||
packet_buffer: Mutex<VecDeque<Packet>>,
|
||||
read_loop: AtomicBool,
|
||||
is_alive: AtomicBool,
|
||||
position: RwLock<(f64, f64, f64)>,
|
||||
velocity: RwLock<(f64, f64, f64)>,
|
||||
rotation: RwLock<(f32, f32)>,
|
||||
entity_info: RwLock<Option<Arc<EntityInfo>>>,
|
||||
}
|
||||
|
||||
// Реализуем сравнение через адрес
|
||||
@ -63,9 +61,7 @@ impl ClientContext {
|
||||
packet_buffer: Mutex::new(VecDeque::new()),
|
||||
read_loop: AtomicBool::new(false),
|
||||
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)),
|
||||
entity_info: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,6 +77,10 @@ impl ClientContext {
|
||||
*self.player_info.write().unwrap() = Some(player_info);
|
||||
}
|
||||
|
||||
pub fn set_entity_info(self: &Arc<Self>, entity_info: EntityInfo) {
|
||||
*self.entity_info.write().unwrap() = Some(Arc::new(entity_info));
|
||||
}
|
||||
|
||||
pub fn set_state(self: &Arc<Self>, state: ConnectionState) -> Result<(), ServerError> {
|
||||
*self.state.write().unwrap() = state.clone();
|
||||
|
||||
@ -107,34 +107,14 @@ impl ClientContext {
|
||||
self.player_info.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn entity_info(self: &Arc<Self>) -> Arc<EntityInfo> {
|
||||
self.entity_info.read().unwrap().clone().unwrap()
|
||||
}
|
||||
|
||||
pub fn state(self: &Arc<Self>) -> ConnectionState {
|
||||
self.state.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn set_position(self: &Arc<Self>, position: (f64, f64, f64)) {
|
||||
*self.position.write().unwrap() = position;
|
||||
}
|
||||
|
||||
pub fn set_velocity(self: &Arc<Self>, velocity: (f64, f64, f64)) {
|
||||
*self.velocity.write().unwrap() = velocity;
|
||||
}
|
||||
|
||||
pub fn set_rotation(self: &Arc<Self>, rotation: (f32, f32)) {
|
||||
*self.rotation.write().unwrap() = rotation;
|
||||
}
|
||||
|
||||
pub fn position(self: &Arc<Self>) -> (f64, f64, f64) {
|
||||
self.position.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn velocity(self: &Arc<Self>) -> (f64, f64, f64) {
|
||||
self.velocity.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn rotation(self: &Arc<Self>) -> (f32, f32) {
|
||||
self.rotation.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn write_packet(self: &Arc<Self>, packet: &Packet) -> Result<(), ServerError> {
|
||||
let state = self.state();
|
||||
let mut packet = packet.clone();
|
||||
@ -304,3 +284,47 @@ pub struct PlayerInfo {
|
||||
pub name: String,
|
||||
pub uuid: Uuid,
|
||||
}
|
||||
|
||||
pub struct EntityInfo {
|
||||
pub entity_id: i32,
|
||||
pub uuid: Uuid,
|
||||
position: RwLock<(f64, f64, f64)>,
|
||||
velocity: RwLock<(f64, f64, f64)>,
|
||||
rotation: RwLock<(f32, f32)>,
|
||||
}
|
||||
|
||||
impl EntityInfo {
|
||||
pub fn new(entity_id: i32, uuid: Uuid) -> EntityInfo {
|
||||
EntityInfo {
|
||||
entity_id,
|
||||
uuid,
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_position(self: &Arc<Self>, position: (f64, f64, f64)) {
|
||||
*self.position.write().unwrap() = position;
|
||||
}
|
||||
|
||||
pub fn set_velocity(self: &Arc<Self>, velocity: (f64, f64, f64)) {
|
||||
*self.velocity.write().unwrap() = velocity;
|
||||
}
|
||||
|
||||
pub fn set_rotation(self: &Arc<Self>, rotation: (f32, f32)) {
|
||||
*self.rotation.write().unwrap() = rotation;
|
||||
}
|
||||
|
||||
pub fn position(self: &Arc<Self>) -> (f64, f64, f64) {
|
||||
self.position.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn velocity(self: &Arc<Self>) -> (f64, f64, f64) {
|
||||
self.velocity.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn rotation(self: &Arc<Self>) -> (f32, f32) {
|
||||
self.rotation.read().unwrap().clone()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user