Move from ids to uuids
This commit is contained in:
parent
e396399e66
commit
14ff151d88
@ -18,7 +18,7 @@ use pumpkin_protocol::{
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
client::authentication::{self, validate_textures, GameProfile},
|
client::authentication::{self, offline_uuid, validate_textures, GameProfile},
|
||||||
entity::player::{ChatMode, Hand},
|
entity::player::{ChatMode, Hand},
|
||||||
proxy::{
|
proxy::{
|
||||||
bungeecord,
|
bungeecord,
|
||||||
@ -39,11 +39,7 @@ impl Client {
|
|||||||
.store(version, std::sync::atomic::Ordering::Relaxed);
|
.store(version, std::sync::atomic::Ordering::Relaxed);
|
||||||
*self.server_address.lock().await = handshake.server_address;
|
*self.server_address.lock().await = handshake.server_address;
|
||||||
|
|
||||||
log::debug!(
|
log::debug!("Handshake: next state {:?}", &handshake.next_state);
|
||||||
"Handshake: id {} is now in state {:?}",
|
|
||||||
self.id,
|
|
||||||
&handshake.next_state
|
|
||||||
);
|
|
||||||
self.connection_state.store(handshake.next_state);
|
self.connection_state.store(handshake.next_state);
|
||||||
if self.connection_state.load() != ConnectionState::Status {
|
if self.connection_state.load() != ConnectionState::Status {
|
||||||
let protocol = version;
|
let protocol = version;
|
||||||
@ -60,13 +56,13 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_status_request(&self, server: &Server, _status_request: SStatusRequest) {
|
pub async fn handle_status_request(&self, server: &Server, _status_request: SStatusRequest) {
|
||||||
log::debug!("Handling status request for id {}", self.id);
|
log::debug!("Handling status request for id");
|
||||||
let status = server.get_status();
|
let status = server.get_status();
|
||||||
self.send_packet(&status.lock().await.get_status()).await;
|
self.send_packet(&status.lock().await.get_status()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_ping_request(&self, ping_request: SStatusPingRequest) {
|
pub async fn handle_ping_request(&self, ping_request: SStatusPingRequest) {
|
||||||
log::debug!("Handling ping request for id {}", self.id);
|
log::debug!("Handling ping request for id");
|
||||||
self.send_packet(&CPingResponse::new(ping_request.payload))
|
self.send_packet(&CPingResponse::new(ping_request.payload))
|
||||||
.await;
|
.await;
|
||||||
self.close();
|
self.close();
|
||||||
@ -80,11 +76,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_login_start(&self, server: &Server, login_start: SLoginStart) {
|
pub async fn handle_login_start(&self, server: &Server, login_start: SLoginStart) {
|
||||||
log::debug!(
|
log::debug!("login start");
|
||||||
"login start for id {}, State {:?}",
|
|
||||||
self.id,
|
|
||||||
self.connection_state
|
|
||||||
);
|
|
||||||
|
|
||||||
if !Self::is_valid_player_name(&login_start.name) {
|
if !Self::is_valid_player_name(&login_start.name) {
|
||||||
self.kick("Invalid characters in username").await;
|
self.kick("Invalid characters in username").await;
|
||||||
@ -108,8 +100,14 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let id = if BASIC_CONFIG.online_mode {
|
||||||
|
login_start.uuid
|
||||||
|
} else {
|
||||||
|
offline_uuid(&login_start.name).expect("This is very not safe and bad")
|
||||||
|
};
|
||||||
|
|
||||||
let profile = GameProfile {
|
let profile = GameProfile {
|
||||||
id: login_start.uuid,
|
id,
|
||||||
name: login_start.name,
|
name: login_start.name,
|
||||||
properties: vec![],
|
properties: vec![],
|
||||||
profile_actions: None,
|
profile_actions: None,
|
||||||
@ -137,7 +135,7 @@ impl Client {
|
|||||||
server: &Server,
|
server: &Server,
|
||||||
encryption_response: SEncryptionResponse,
|
encryption_response: SEncryptionResponse,
|
||||||
) {
|
) {
|
||||||
log::debug!("Handling encryption for id {}", self.id);
|
log::debug!("Handling encryption for id");
|
||||||
let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();
|
let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();
|
||||||
|
|
||||||
if let Err(error) = self.set_encryption(Some(&shared_secret)).await {
|
if let Err(error) = self.set_encryption(Some(&shared_secret)).await {
|
||||||
@ -228,7 +226,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) {
|
pub async fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) {
|
||||||
log::debug!("Handling plugin for id {}", self.id);
|
log::debug!("Handling plugin for id");
|
||||||
let velocity_config = &ADVANCED_CONFIG.proxy.velocity;
|
let velocity_config = &ADVANCED_CONFIG.proxy.velocity;
|
||||||
if velocity_config.enabled {
|
if velocity_config.enabled {
|
||||||
let mut address = self.address.lock().await;
|
let mut address = self.address.lock().await;
|
||||||
@ -252,7 +250,7 @@ impl Client {
|
|||||||
server: &Server,
|
server: &Server,
|
||||||
_login_acknowledged: SLoginAcknowledged,
|
_login_acknowledged: SLoginAcknowledged,
|
||||||
) {
|
) {
|
||||||
log::debug!("Handling login acknowledged for id {}", self.id);
|
log::debug!("Handling login acknowledged for id");
|
||||||
self.connection_state.store(ConnectionState::Config);
|
self.connection_state.store(ConnectionState::Config);
|
||||||
self.send_packet(&server.get_branding()).await;
|
self.send_packet(&server.get_branding()).await;
|
||||||
|
|
||||||
@ -289,7 +287,7 @@ impl Client {
|
|||||||
&self,
|
&self,
|
||||||
client_information: SClientInformationConfig,
|
client_information: SClientInformationConfig,
|
||||||
) {
|
) {
|
||||||
log::debug!("Handling client settings for id {}", self.id);
|
log::debug!("Handling client settings for id");
|
||||||
if let (Some(main_hand), Some(chat_mode)) = (
|
if let (Some(main_hand), Some(chat_mode)) = (
|
||||||
Hand::from_i32(client_information.main_hand.into()),
|
Hand::from_i32(client_information.main_hand.into()),
|
||||||
ChatMode::from_i32(client_information.chat_mode.into()),
|
ChatMode::from_i32(client_information.chat_mode.into()),
|
||||||
@ -310,7 +308,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) {
|
pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) {
|
||||||
log::debug!("Handling plugin message for id {}", self.id);
|
log::debug!("Handling plugin message for id");
|
||||||
if plugin_message.channel.starts_with("minecraft:brand")
|
if plugin_message.channel.starts_with("minecraft:brand")
|
||||||
|| plugin_message.channel.starts_with("MC|Brand")
|
|| plugin_message.channel.starts_with("MC|Brand")
|
||||||
{
|
{
|
||||||
@ -323,7 +321,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_known_packs(&self, server: &Server, _config_acknowledged: SKnownPacks) {
|
pub async fn handle_known_packs(&self, server: &Server, _config_acknowledged: SKnownPacks) {
|
||||||
log::debug!("Handling known packs for id {}", self.id);
|
log::debug!("Handling known packs for id");
|
||||||
for registry in &server.cached_registry {
|
for registry in &server.cached_registry {
|
||||||
self.send_packet(&CRegistryData::new(
|
self.send_packet(&CRegistryData::new(
|
||||||
®istry.registry_id,
|
®istry.registry_id,
|
||||||
@ -338,7 +336,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_config_acknowledged(&self, _config_acknowledged: &SAcknowledgeFinishConfig) {
|
pub fn handle_config_acknowledged(&self, _config_acknowledged: &SAcknowledgeFinishConfig) {
|
||||||
log::debug!("Handling config acknowledge for id {}", self.id);
|
log::debug!("Handling config acknowledge for id");
|
||||||
self.connection_state.store(ConnectionState::Play);
|
self.connection_state.store(ConnectionState::Play);
|
||||||
self.make_player
|
self.make_player
|
||||||
.store(true, std::sync::atomic::Ordering::Relaxed);
|
.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
|||||||
@ -406,7 +406,7 @@ impl Player {
|
|||||||
.filter(|player_id| *player_id != self.entity_id())
|
.filter(|player_id| *player_id != self.entity_id())
|
||||||
.collect_vec()
|
.collect_vec()
|
||||||
};
|
};
|
||||||
let player_token = self.client.id;
|
let player_token = self.gameprofile.id;
|
||||||
|
|
||||||
// TODO: Figure out better way to get only the players from player_ids
|
// TODO: Figure out better way to get only the players from player_ids
|
||||||
// Also refactor out a better method to get individual advanced state ids
|
// Also refactor out a better method to get individual advanced state ids
|
||||||
|
|||||||
@ -107,8 +107,6 @@ pub struct Client {
|
|||||||
pub encryption: AtomicBool,
|
pub encryption: AtomicBool,
|
||||||
/// Indicates if the client connection is closed.
|
/// Indicates if the client connection is closed.
|
||||||
pub closed: AtomicBool,
|
pub closed: AtomicBool,
|
||||||
/// A unique id identifying the client.
|
|
||||||
pub id: usize,
|
|
||||||
/// The underlying TCP connection to the client.
|
/// The underlying TCP connection to the client.
|
||||||
pub connection_reader: Arc<Mutex<tokio::net::tcp::OwnedReadHalf>>,
|
pub connection_reader: Arc<Mutex<tokio::net::tcp::OwnedReadHalf>>,
|
||||||
pub connection_writer: Arc<Mutex<tokio::net::tcp::OwnedWriteHalf>>,
|
pub connection_writer: Arc<Mutex<tokio::net::tcp::OwnedWriteHalf>>,
|
||||||
@ -126,7 +124,7 @@ pub struct Client {
|
|||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(id: usize, connection: tokio::net::TcpStream, address: SocketAddr) -> Self {
|
pub fn new(connection: tokio::net::TcpStream, address: SocketAddr) -> Self {
|
||||||
let (connection_reader, connection_writer) = connection.into_split();
|
let (connection_reader, connection_writer) = connection.into_split();
|
||||||
Self {
|
Self {
|
||||||
protocol_version: AtomicI32::new(0),
|
protocol_version: AtomicI32::new(0),
|
||||||
@ -134,7 +132,6 @@ impl Client {
|
|||||||
config: Mutex::new(None),
|
config: Mutex::new(None),
|
||||||
brand: Mutex::new(None),
|
brand: Mutex::new(None),
|
||||||
server_address: Mutex::new(String::new()),
|
server_address: Mutex::new(String::new()),
|
||||||
id,
|
|
||||||
address: Mutex::new(address),
|
address: Mutex::new(address),
|
||||||
connection_state: AtomicCell::new(ConnectionState::HandShake),
|
connection_state: AtomicCell::new(ConnectionState::HandShake),
|
||||||
connection_reader: Arc::new(Mutex::new(connection_reader)),
|
connection_reader: Arc::new(Mutex::new(connection_reader)),
|
||||||
@ -198,11 +195,7 @@ impl Client {
|
|||||||
{
|
{
|
||||||
self.kick(&error.to_string()).await;
|
self.kick(&error.to_string()).await;
|
||||||
} else if let Err(error) = writer.flush().await {
|
} else if let Err(error) = writer.flush().await {
|
||||||
log::warn!(
|
log::warn!("Failed to flush writer for: {}", error.to_string());
|
||||||
"Failed to flush writer for id {}: {}",
|
|
||||||
self.id,
|
|
||||||
error.to_string()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +273,7 @@ impl Client {
|
|||||||
&self,
|
&self,
|
||||||
packet: &mut RawPacket,
|
packet: &mut RawPacket,
|
||||||
) -> Result<(), DeserializerError> {
|
) -> Result<(), DeserializerError> {
|
||||||
log::debug!("Handling handshake group for id {}", self.id);
|
log::debug!("Handling handshake group");
|
||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
match packet.id.0 {
|
match packet.id.0 {
|
||||||
0 => {
|
0 => {
|
||||||
@ -301,7 +294,7 @@ impl Client {
|
|||||||
server: &Arc<Server>,
|
server: &Arc<Server>,
|
||||||
packet: &mut RawPacket,
|
packet: &mut RawPacket,
|
||||||
) -> Result<(), DeserializerError> {
|
) -> Result<(), DeserializerError> {
|
||||||
log::debug!("Handling status group for id {}", self.id);
|
log::debug!("Handling status group");
|
||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
if let Some(packet) = ServerboundStatusPackets::from_i32(packet.id.0) {
|
if let Some(packet) = ServerboundStatusPackets::from_i32(packet.id.0) {
|
||||||
match packet {
|
match packet {
|
||||||
@ -329,7 +322,7 @@ impl Client {
|
|||||||
server: &Arc<Server>,
|
server: &Arc<Server>,
|
||||||
packet: &mut RawPacket,
|
packet: &mut RawPacket,
|
||||||
) -> Result<(), DeserializerError> {
|
) -> Result<(), DeserializerError> {
|
||||||
log::debug!("Handling login group for id {}", self.id);
|
log::debug!("Handling login group for id");
|
||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
if let Some(packet) = ServerboundLoginPackets::from_i32(packet.id.0) {
|
if let Some(packet) = ServerboundLoginPackets::from_i32(packet.id.0) {
|
||||||
match packet {
|
match packet {
|
||||||
@ -366,7 +359,7 @@ impl Client {
|
|||||||
server: &Arc<Server>,
|
server: &Arc<Server>,
|
||||||
packet: &mut RawPacket,
|
packet: &mut RawPacket,
|
||||||
) -> Result<(), DeserializerError> {
|
) -> Result<(), DeserializerError> {
|
||||||
log::debug!("Handling config group for id {}", self.id);
|
log::debug!("Handling config group");
|
||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
if let Some(packet) = ServerboundConfigPackets::from_i32(packet.id.0) {
|
if let Some(packet) = ServerboundConfigPackets::from_i32(packet.id.0) {
|
||||||
#[expect(clippy::match_same_arms)]
|
#[expect(clippy::match_same_arms)]
|
||||||
@ -414,11 +407,7 @@ impl Client {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Ok(None) => (), //log::debug!("Waiting for more data to complete packet..."),
|
Ok(None) => (), //log::debug!("Waiting for more data to complete packet..."),
|
||||||
Err(err) => log::warn!(
|
Err(err) => log::warn!("Failed to decode packet for: {}", err.to_string()),
|
||||||
"Failed to decode packet for id {}: {}",
|
|
||||||
self.id,
|
|
||||||
err.to_string()
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dec.reserve(4096);
|
dec.reserve(4096);
|
||||||
@ -448,7 +437,7 @@ impl Client {
|
|||||||
|
|
||||||
/// Kicks the Client with a reason depending on the connection state
|
/// Kicks the Client with a reason depending on the connection state
|
||||||
pub async fn kick(&self, reason: &str) {
|
pub async fn kick(&self, reason: &str) {
|
||||||
log::info!("Kicking Client id {} for {}", self.id, reason);
|
log::info!("Kicking Client for {}", reason);
|
||||||
match self.connection_state.load() {
|
match self.connection_state.load() {
|
||||||
ConnectionState::Login => {
|
ConnectionState::Login => {
|
||||||
self.try_send_packet(&CLoginDisconnect::new(
|
self.try_send_packet(&CLoginDisconnect::new(
|
||||||
|
|||||||
@ -113,7 +113,7 @@ impl Player {
|
|||||||
// send new position to all other players
|
// send new position to all other players
|
||||||
world
|
world
|
||||||
.broadcast_packet_expect(
|
.broadcast_packet_expect(
|
||||||
&[self.client.id],
|
&[self.gameprofile.id],
|
||||||
&CUpdateEntityPos::new(
|
&CUpdateEntityPos::new(
|
||||||
entity_id.into(),
|
entity_id.into(),
|
||||||
x.mul_add(4096.0, -(last_x * 4096.0)) as i16,
|
x.mul_add(4096.0, -(last_x * 4096.0)) as i16,
|
||||||
@ -186,7 +186,7 @@ impl Player {
|
|||||||
|
|
||||||
world
|
world
|
||||||
.broadcast_packet_expect(
|
.broadcast_packet_expect(
|
||||||
&[self.client.id],
|
&[self.gameprofile.id],
|
||||||
&CUpdateEntityPosRot::new(
|
&CUpdateEntityPosRot::new(
|
||||||
entity_id.into(),
|
entity_id.into(),
|
||||||
x.mul_add(4096.0, -(last_x * 4096.0)) as i16,
|
x.mul_add(4096.0, -(last_x * 4096.0)) as i16,
|
||||||
@ -200,7 +200,7 @@ impl Player {
|
|||||||
.await;
|
.await;
|
||||||
world
|
world
|
||||||
.broadcast_packet_expect(
|
.broadcast_packet_expect(
|
||||||
&[self.client.id],
|
&[self.gameprofile.id],
|
||||||
&CHeadRot::new(entity_id.into(), yaw as u8),
|
&CHeadRot::new(entity_id.into(), yaw as u8),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -230,11 +230,11 @@ impl Player {
|
|||||||
let packet =
|
let packet =
|
||||||
CUpdateEntityRot::new(entity_id.into(), yaw as u8, pitch as u8, rotation.ground);
|
CUpdateEntityRot::new(entity_id.into(), yaw as u8, pitch as u8, rotation.ground);
|
||||||
world
|
world
|
||||||
.broadcast_packet_expect(&[self.client.id], &packet)
|
.broadcast_packet_expect(&[self.gameprofile.id], &packet)
|
||||||
.await;
|
.await;
|
||||||
let packet = CHeadRot::new(entity_id.into(), yaw as u8);
|
let packet = CHeadRot::new(entity_id.into(), yaw as u8);
|
||||||
world
|
world
|
||||||
.broadcast_packet_expect(&[self.client.id], &packet)
|
.broadcast_packet_expect(&[self.gameprofile.id], &packet)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +325,7 @@ impl Player {
|
|||||||
let world = &self.living_entity.entity.world;
|
let world = &self.living_entity.entity.world;
|
||||||
world
|
world
|
||||||
.broadcast_packet_expect(
|
.broadcast_packet_expect(
|
||||||
&[self.client.id],
|
&[self.gameprofile.id],
|
||||||
&CEntityAnimation::new(id.into(), animation as u8),
|
&CEntityAnimation::new(id.into(), animation as u8),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@ -157,7 +157,7 @@ impl Player {
|
|||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Removing player id {}, unwatching {} chunks",
|
"Removing player id {}, unwatching {} chunks",
|
||||||
self.client.id,
|
self.gameprofile.name,
|
||||||
all_chunks.len()
|
all_chunks.len()
|
||||||
);
|
);
|
||||||
self.living_entity
|
self.living_entity
|
||||||
@ -168,7 +168,7 @@ impl Player {
|
|||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Removed player id {} ({} chunks remain cached)",
|
"Removed player id {} ({} chunks remain cached)",
|
||||||
self.client.id,
|
self.gameprofile.name,
|
||||||
self.living_entity.entity.world.get_cached_chunk_len().await
|
self.living_entity.entity.world.get_cached_chunk_len().await
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,7 +171,6 @@ async fn main() -> io::Result<()> {
|
|||||||
ticker.run(&server).await;
|
ticker.run(&server).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let mut player_count = 0;
|
|
||||||
loop {
|
loop {
|
||||||
// Asynchronously wait for an inbound socket.
|
// Asynchronously wait for an inbound socket.
|
||||||
let (connection, address) = listener.accept().await?;
|
let (connection, address) = listener.accept().await?;
|
||||||
@ -180,16 +179,12 @@ async fn main() -> io::Result<()> {
|
|||||||
log::warn!("failed to set TCP_NODELAY {e}");
|
log::warn!("failed to set TCP_NODELAY {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
player_count += 1;
|
|
||||||
let id = player_count;
|
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
"Accepted connection from: {} (id: {})",
|
"Accepted connection from: {} ",
|
||||||
scrub_address(&format!("{address}")),
|
scrub_address(&format!("{address}")),
|
||||||
id
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let client = Arc::new(Client::new(id, connection, addr));
|
let client = Arc::new(Client::new(connection, addr));
|
||||||
|
|
||||||
let server = server.clone();
|
let server = server.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
@ -207,9 +202,7 @@ async fn main() -> io::Result<()> {
|
|||||||
.make_player
|
.make_player
|
||||||
.load(std::sync::atomic::Ordering::Relaxed)
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
{
|
{
|
||||||
let id = client.id;
|
let (player, world) = server.add_player(client).await;
|
||||||
log::debug!("Creating player for id {}", id);
|
|
||||||
let (player, world) = server.add_player(id, client).await;
|
|
||||||
world.spawn_player(&BASIC_CONFIG, player.clone()).await;
|
world.spawn_player(&BASIC_CONFIG, player.clone()).await;
|
||||||
// poll Player
|
// poll Player
|
||||||
while !player
|
while !player
|
||||||
@ -226,6 +219,5 @@ async fn main() -> io::Result<()> {
|
|||||||
server.remove_player().await;
|
server.remove_player().await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
player_count -= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,7 +93,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_player(&self, id: usize, client: Arc<Client>) -> (Arc<Player>, Arc<World>) {
|
pub async fn add_player(&self, client: Arc<Client>) -> (Arc<Player>, Arc<World>) {
|
||||||
let entity_id = self.new_entity_id();
|
let entity_id = self.new_entity_id();
|
||||||
let gamemode = match BASIC_CONFIG.default_gamemode {
|
let gamemode = match BASIC_CONFIG.default_gamemode {
|
||||||
GameMode::Undefined => GameMode::Survival,
|
GameMode::Undefined => GameMode::Survival,
|
||||||
@ -104,7 +104,9 @@ impl Server {
|
|||||||
let world = &self.worlds[0];
|
let world = &self.worlds[0];
|
||||||
|
|
||||||
let player = Arc::new(Player::new(client, world.clone(), entity_id, gamemode).await);
|
let player = Arc::new(Player::new(client, world.clone(), entity_id, gamemode).await);
|
||||||
world.add_player(id, player.clone()).await;
|
world
|
||||||
|
.add_player(player.gameprofile.id, player.clone())
|
||||||
|
.await;
|
||||||
// TODO: Config if we want increase online
|
// TODO: Config if we want increase online
|
||||||
if let Some(config) = player.client.config.lock().await.as_ref() {
|
if let Some(config) = player.client.config.lock().await.as_ref() {
|
||||||
// TODO: Config so we can also just ignore this hehe
|
// TODO: Config so we can also just ignore this hehe
|
||||||
|
|||||||
@ -42,7 +42,7 @@ pub struct World {
|
|||||||
/// The underlying level, responsible for chunk management and terrain generation.
|
/// The underlying level, responsible for chunk management and terrain generation.
|
||||||
pub level: Arc<Mutex<Level>>,
|
pub level: Arc<Mutex<Level>>,
|
||||||
/// A map of active players within the world, keyed by their unique token.
|
/// A map of active players within the world, keyed by their unique token.
|
||||||
pub current_players: Arc<Mutex<HashMap<usize, Arc<Player>>>>,
|
pub current_players: Arc<Mutex<HashMap<uuid::Uuid, Arc<Player>>>>,
|
||||||
pub scoreboard: Mutex<Scoreboard>,
|
pub scoreboard: Mutex<Scoreboard>,
|
||||||
// TODO: entities
|
// TODO: entities
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ impl World {
|
|||||||
/// Sends the specified packet to every player currently logged in to the server, excluding the players listed in the `except` parameter.
|
/// Sends the specified packet to every player currently logged in to the server, excluding the players listed in the `except` parameter.
|
||||||
///
|
///
|
||||||
/// **Note:** This function acquires a lock on the `current_players` map, ensuring thread safety.
|
/// **Note:** This function acquires a lock on the `current_players` map, ensuring thread safety.
|
||||||
pub async fn broadcast_packet_expect<P>(&self, except: &[usize], packet: &P)
|
pub async fn broadcast_packet_expect<P>(&self, except: &[uuid::Uuid], packet: &P)
|
||||||
where
|
where
|
||||||
P: ClientPacket,
|
P: ClientPacket,
|
||||||
{
|
{
|
||||||
@ -100,11 +100,10 @@ impl World {
|
|||||||
let gamemode = player.gamemode.load();
|
let gamemode = player.gamemode.load();
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"spawning player {}, entity id {}",
|
"spawning player {}, entity id {}",
|
||||||
player.client.id,
|
player.gameprofile.name,
|
||||||
entity_id
|
entity_id
|
||||||
);
|
);
|
||||||
|
|
||||||
log::debug!("Sending login packet to {}", player.client.id);
|
|
||||||
// login packet for our new player
|
// login packet for our new player
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
@ -134,7 +133,7 @@ impl World {
|
|||||||
|
|
||||||
// player abilities
|
// player abilities
|
||||||
// TODO: this is for debug purpose, remove later
|
// TODO: this is for debug purpose, remove later
|
||||||
log::debug!("Sending player abilities to {}", player.client.id);
|
log::debug!("Sending player abilities to {}", player.gameprofile.name);
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
.send_packet(&CPlayerAbilities::new(0x02, 0.4, 0.1))
|
.send_packet(&CPlayerAbilities::new(0x02, 0.4, 0.1))
|
||||||
@ -145,7 +144,7 @@ impl World {
|
|||||||
let yaw = 10.0;
|
let yaw = 10.0;
|
||||||
let pitch = 10.0;
|
let pitch = 10.0;
|
||||||
|
|
||||||
log::debug!("Sending player teleport to {}", player.client.id);
|
log::debug!("Sending player teleport to {}", player.gameprofile.name);
|
||||||
player.teleport(position, yaw, pitch).await;
|
player.teleport(position, yaw, pitch).await;
|
||||||
|
|
||||||
let pos = player.living_entity.entity.pos.load();
|
let pos = player.living_entity.entity.pos.load();
|
||||||
@ -154,7 +153,7 @@ impl World {
|
|||||||
let gameprofile = &player.gameprofile;
|
let gameprofile = &player.gameprofile;
|
||||||
// first send info update to our new player, So he can see his Skin
|
// first send info update to our new player, So he can see his Skin
|
||||||
// also send his info to everyone else
|
// also send his info to everyone else
|
||||||
log::debug!("Broadcasting player info for {}", player.client.id);
|
log::debug!("Broadcasting player info for {}", player.gameprofile.name);
|
||||||
self.broadcast_packet_all(&CPlayerInfoUpdate::new(
|
self.broadcast_packet_all(&CPlayerInfoUpdate::new(
|
||||||
0x01 | 0x08,
|
0x01 | 0x08,
|
||||||
&[pumpkin_protocol::client::play::Player {
|
&[pumpkin_protocol::client::play::Player {
|
||||||
@ -176,7 +175,7 @@ impl World {
|
|||||||
let current_players = self.current_players.lock().await;
|
let current_players = self.current_players.lock().await;
|
||||||
for (_, playerr) in current_players
|
for (_, playerr) in current_players
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(c, _)| **c != player.client.id)
|
.filter(|(c, _)| **c != player.gameprofile.id)
|
||||||
{
|
{
|
||||||
let gameprofile = &playerr.gameprofile;
|
let gameprofile = &playerr.gameprofile;
|
||||||
entries.push(pumpkin_protocol::client::play::Player {
|
entries.push(pumpkin_protocol::client::play::Player {
|
||||||
@ -190,7 +189,7 @@ impl World {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
log::debug!("Sending player info to {}", player.client.id);
|
log::debug!("Sending player info to {}", player.gameprofile.name);
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
.send_packet(&CPlayerInfoUpdate::new(0x01 | 0x08, &entries))
|
.send_packet(&CPlayerInfoUpdate::new(0x01 | 0x08, &entries))
|
||||||
@ -199,10 +198,10 @@ impl World {
|
|||||||
|
|
||||||
let gameprofile = &player.gameprofile;
|
let gameprofile = &player.gameprofile;
|
||||||
|
|
||||||
log::debug!("Broadcasting player spawn for {}", player.client.id);
|
log::debug!("Broadcasting player spawn for {}", player.gameprofile.name);
|
||||||
// spawn player for every client
|
// spawn player for every client
|
||||||
self.broadcast_packet_expect(
|
self.broadcast_packet_expect(
|
||||||
&[player.client.id],
|
&[player.gameprofile.id],
|
||||||
// TODO: add velo
|
// TODO: add velo
|
||||||
&CSpawnEntity::new(
|
&CSpawnEntity::new(
|
||||||
entity_id.into(),
|
entity_id.into(),
|
||||||
@ -222,18 +221,18 @@ impl World {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
// spawn players for our client
|
// spawn players for our client
|
||||||
let token = player.client.id;
|
let id = player.gameprofile.id;
|
||||||
for (_, existing_player) in self
|
for (_, existing_player) in self
|
||||||
.current_players
|
.current_players
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|c| c.0 != &token)
|
.filter(|c| c.0 != &id)
|
||||||
{
|
{
|
||||||
let entity = &existing_player.living_entity.entity;
|
let entity = &existing_player.living_entity.entity;
|
||||||
let pos = entity.pos.load();
|
let pos = entity.pos.load();
|
||||||
let gameprofile = &existing_player.gameprofile;
|
let gameprofile = &existing_player.gameprofile;
|
||||||
log::debug!("Sending player entities to {}", player.client.id);
|
log::debug!("Sending player entities to {}", player.gameprofile.name);
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
.send_packet(&CSpawnEntity::new(
|
.send_packet(&CSpawnEntity::new(
|
||||||
@ -260,12 +259,12 @@ impl World {
|
|||||||
entity_id.into(),
|
entity_id.into(),
|
||||||
Metadata::new(17, VarInt(0), config.skin_parts),
|
Metadata::new(17, VarInt(0), config.skin_parts),
|
||||||
);
|
);
|
||||||
log::debug!("Broadcasting skin for {}", player.client.id);
|
log::debug!("Broadcasting skin for {}", player.gameprofile.name);
|
||||||
self.broadcast_packet_all(&packet).await;
|
self.broadcast_packet_all(&packet).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start waiting for level chunks, Sets the "Loading Terrain" screen
|
// Start waiting for level chunks, Sets the "Loading Terrain" screen
|
||||||
log::debug!("Sending waiting chunks to {}", player.client.id);
|
log::debug!("Sending waiting chunks to {}", player.gameprofile.name);
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
.send_packet(&CGameEvent::new(GameEvent::StartWaitingChunks, 0.0))
|
.send_packet(&CGameEvent::new(GameEvent::StartWaitingChunks, 0.0))
|
||||||
@ -292,10 +291,7 @@ impl World {
|
|||||||
|
|
||||||
fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>) {
|
fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>) {
|
||||||
if client.closed.load(std::sync::atomic::Ordering::Relaxed) {
|
if client.closed.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
log::info!(
|
log::info!("The connection has closed before world chunks were spawned",);
|
||||||
"The connection with {} has closed before world chunks were spawned",
|
|
||||||
client.id
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let inst = std::time::Instant::now();
|
let inst = std::time::Instant::now();
|
||||||
@ -351,19 +347,19 @@ impl World {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_player(&self, id: usize, player: Arc<Player>) {
|
pub async fn add_player(&self, uuid: uuid::Uuid, player: Arc<Player>) {
|
||||||
self.current_players.lock().await.insert(id, player);
|
self.current_players.lock().await.insert(uuid, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_player(&self, player: &Player) {
|
pub async fn remove_player(&self, player: &Player) {
|
||||||
self.current_players
|
self.current_players
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.remove(&player.client.id)
|
.remove(&player.gameprofile.id)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let uuid = player.gameprofile.id;
|
let uuid = player.gameprofile.id;
|
||||||
self.broadcast_packet_expect(
|
self.broadcast_packet_expect(
|
||||||
&[player.client.id],
|
&[player.gameprofile.id],
|
||||||
&CRemovePlayerInfo::new(1.into(), &[uuid]),
|
&CRemovePlayerInfo::new(1.into(), &[uuid]),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@ -28,7 +28,7 @@ pub async fn player_join(world: &World, player: Arc<Player>) {
|
|||||||
assert_eq!(new_watched.x, chunk_pos.x);
|
assert_eq!(new_watched.x, chunk_pos.x);
|
||||||
assert_eq!(new_watched.z, chunk_pos.z);
|
assert_eq!(new_watched.z, chunk_pos.z);
|
||||||
|
|
||||||
log::debug!("Sending center chunk to {}", player.client.id);
|
log::debug!("Sending center chunk to {}", player.gameprofile.name);
|
||||||
player
|
player
|
||||||
.client
|
.client
|
||||||
.send_packet(&CCenterChunk {
|
.send_packet(&CCenterChunk {
|
||||||
@ -40,7 +40,7 @@ pub async fn player_join(world: &World, player: Arc<Player>) {
|
|||||||
log::debug!(
|
log::debug!(
|
||||||
"Player {} ({}) joined with view distance: {}",
|
"Player {} ({}) joined with view distance: {}",
|
||||||
player.gameprofile.name,
|
player.gameprofile.name,
|
||||||
player.client.id,
|
player.gameprofile.name,
|
||||||
view_distance
|
view_distance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user