Minior Code cleanups
This commit is contained in:
parent
acc5aca0ff
commit
f970c4bc12
1
.github/workflows/rust.yml
vendored
1
.github/workflows/rust.yml
vendored
@ -70,6 +70,7 @@ jobs:
|
|||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: pumpkin-${{ matrix.os }}
|
name: pumpkin-${{ matrix.os }}
|
||||||
|
compression-level: 9
|
||||||
path: target/${{ matrix.target }}/release/pumpkin*
|
path: target/${{ matrix.target }}/release/pumpkin*
|
||||||
clippy_release:
|
clippy_release:
|
||||||
name: Run lints in release mode
|
name: Run lints in release mode
|
||||||
|
|||||||
@ -266,6 +266,9 @@ For Players:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Compression
|
||||||
|
Minecraft Packets **can** use the ZLib compression for decoding/encoding there is usally a threshold set when compression is applied, This most often affects Chunk Packets.
|
||||||
|
|
||||||
### Porting
|
### Porting
|
||||||
|
|
||||||
To port to a new Minecraft version, You can compare difference in Protocol on wiki.vg https://wiki.vg/index.php?title=Protocol&action=history
|
To port to a new Minecraft version, You can compare difference in Protocol on wiki.vg https://wiki.vg/index.php?title=Protocol&action=history
|
||||||
|
|||||||
21
fuzz/Cargo.toml
Normal file
21
fuzz/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
name = "pumpkin-fuzz"
|
||||||
|
version = "0.0.0"
|
||||||
|
publish = false
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
cargo-fuzz = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin = { path = "../"}
|
||||||
|
|
||||||
|
libfuzzer-sys = "0.4"
|
||||||
|
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz_target_1"
|
||||||
|
path = "fuzz_targets/fuzz_target_1.rs"
|
||||||
|
test = false
|
||||||
|
doc = false
|
||||||
|
bench = false
|
||||||
7
fuzz/fuzz_targets/client.rs
Normal file
7
fuzz/fuzz_targets/client.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
|
fuzz_target!(|data: &[u8]| {
|
||||||
|
// fuzzed code goes here
|
||||||
|
});
|
||||||
@ -22,12 +22,10 @@ impl Cylindrical {
|
|||||||
just_removed: impl FnMut(Vector2<i32>),
|
just_removed: impl FnMut(Vector2<i32>),
|
||||||
ignore: bool,
|
ignore: bool,
|
||||||
) {
|
) {
|
||||||
let min_x = old_cylindrical.get_left().min(new_cylindrical.get_left());
|
let min_x = old_cylindrical.left().min(new_cylindrical.left());
|
||||||
let max_x = old_cylindrical.get_right().max(new_cylindrical.get_right());
|
let max_x = old_cylindrical.right().max(new_cylindrical.right());
|
||||||
let min_z = old_cylindrical
|
let min_z = old_cylindrical.bottom().min(new_cylindrical.bottom());
|
||||||
.get_bottom()
|
let max_z = old_cylindrical.top().max(new_cylindrical.top());
|
||||||
.min(new_cylindrical.get_bottom());
|
|
||||||
let max_z = old_cylindrical.get_top().max(new_cylindrical.get_top());
|
|
||||||
|
|
||||||
for x in min_x..=max_x {
|
for x in min_x..=max_x {
|
||||||
for z in min_z..=max_z {
|
for z in min_z..=max_z {
|
||||||
@ -55,19 +53,19 @@ impl Cylindrical {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_left(&self) -> i32 {
|
fn left(&self) -> i32 {
|
||||||
self.center.x - self.view_distance - 1
|
self.center.x - self.view_distance - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bottom(&self) -> i32 {
|
fn bottom(&self) -> i32 {
|
||||||
self.center.z - self.view_distance - 1
|
self.center.z - self.view_distance - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_right(&self) -> i32 {
|
fn right(&self) -> i32 {
|
||||||
self.center.x + self.view_distance + 1
|
self.center.x + self.view_distance + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_top(&self) -> i32 {
|
fn top(&self) -> i32 {
|
||||||
self.center.z + self.view_distance + 1
|
self.center.z + self.view_distance + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::{collections::HashMap, net::IpAddr, sync::Arc};
|
use std::{collections::HashMap, net::IpAddr};
|
||||||
|
|
||||||
use base64::{engine::general_purpose, Engine};
|
use base64::{engine::general_purpose, Engine};
|
||||||
use pumpkin_config::{auth::TextureConfig, ADVANCED_CONFIG};
|
use pumpkin_config::{auth::TextureConfig, ADVANCED_CONFIG};
|
||||||
@ -9,8 +9,6 @@ use serde::Deserialize;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::server::Server;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Debug)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@ -55,10 +53,9 @@ pub async fn authenticate(
|
|||||||
username: &str,
|
username: &str,
|
||||||
server_hash: &str,
|
server_hash: &str,
|
||||||
ip: &IpAddr,
|
ip: &IpAddr,
|
||||||
server: &Arc<Server>,
|
auth_client: &reqwest::Client,
|
||||||
) -> Result<GameProfile, AuthError> {
|
) -> Result<GameProfile, AuthError> {
|
||||||
assert!(ADVANCED_CONFIG.authentication.enabled);
|
assert!(ADVANCED_CONFIG.authentication.enabled);
|
||||||
assert!(server.auth_client.is_some());
|
|
||||||
let address = if ADVANCED_CONFIG.authentication.prevent_proxy_connections {
|
let address = if ADVANCED_CONFIG.authentication.prevent_proxy_connections {
|
||||||
ADVANCED_CONFIG
|
ADVANCED_CONFIG
|
||||||
.authentication
|
.authentication
|
||||||
@ -73,10 +70,6 @@ pub async fn authenticate(
|
|||||||
.replace("{username}", username)
|
.replace("{username}", username)
|
||||||
.replace("{server_hash}", server_hash)
|
.replace("{server_hash}", server_hash)
|
||||||
};
|
};
|
||||||
let auth_client = server
|
|
||||||
.auth_client
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(AuthError::MissingAuthClient)?;
|
|
||||||
|
|
||||||
let response = auth_client
|
let response = auth_client
|
||||||
.get(address)
|
.get(address)
|
||||||
@ -92,7 +85,7 @@ pub async fn authenticate(
|
|||||||
Ok(profile)
|
Ok(profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpack_textures(property: &Property, config: &TextureConfig) -> Result<(), TextureError> {
|
pub fn validate_textures(property: &Property, config: &TextureConfig) -> Result<(), TextureError> {
|
||||||
let from64 = general_purpose::STANDARD
|
let from64 = general_purpose::STANDARD
|
||||||
.decode(&property.value)
|
.decode(&property.value)
|
||||||
.map_err(|e| TextureError::DecodeError(e.to_string()))?;
|
.map_err(|e| TextureError::DecodeError(e.to_string()))?;
|
||||||
@ -134,6 +127,12 @@ pub enum AuthError {
|
|||||||
FailedResponse,
|
FailedResponse,
|
||||||
#[error("Failed to verify username")]
|
#[error("Failed to verify username")]
|
||||||
UnverifiedUsername,
|
UnverifiedUsername,
|
||||||
|
#[error("You are banned from Authentication servers")]
|
||||||
|
Banned,
|
||||||
|
#[error("Texture Error {0}")]
|
||||||
|
TextureError(TextureError),
|
||||||
|
#[error("You have disallowed actions from Authentication servers")]
|
||||||
|
DisallowedAction,
|
||||||
#[error("Failed to parse JSON into Game Profile")]
|
#[error("Failed to parse JSON into Game Profile")]
|
||||||
FailedParse,
|
FailedParse,
|
||||||
#[error("Unknown Status Code")]
|
#[error("Unknown Status Code")]
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG};
|
use pumpkin_config::{ADVANCED_CONFIG, BASIC_CONFIG};
|
||||||
use pumpkin_core::text::TextComponent;
|
use pumpkin_core::text::TextComponent;
|
||||||
@ -20,20 +18,20 @@ use pumpkin_protocol::{
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
client::authentication::{self, GameProfile},
|
client::authentication::{self, validate_textures, GameProfile},
|
||||||
entity::player::{ChatMode, Hand},
|
entity::player::{ChatMode, Hand},
|
||||||
proxy::velocity::velocity_login,
|
proxy::velocity::velocity_login,
|
||||||
server::{Server, CURRENT_MC_VERSION},
|
server::{Server, CURRENT_MC_VERSION},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{authentication::unpack_textures, Client, PlayerConfig};
|
use super::{authentication::AuthError, Client, PlayerConfig};
|
||||||
|
|
||||||
/// Processes incoming Packets from the Client to the Server
|
/// Processes incoming Packets from the Client to the Server
|
||||||
/// Implements the `Client` Packets
|
/// Implements the `Client` Packets
|
||||||
/// NEVER TRUST THE CLIENT. HANDLE EVERY ERROR, UNWRAP/EXPECT
|
/// NEVER TRUST THE CLIENT. HANDLE EVERY ERROR, UNWRAP/EXPECT
|
||||||
/// TODO: REMOVE ALL UNWRAPS
|
/// TODO: REMOVE ALL UNWRAPS
|
||||||
impl Client {
|
impl Client {
|
||||||
pub fn handle_handshake(&self, _server: &Arc<Server>, handshake: SHandShake) {
|
pub fn handle_handshake(&self, handshake: SHandShake) {
|
||||||
dbg!("handshake");
|
dbg!("handshake");
|
||||||
let version = handshake.protocol_version.0;
|
let version = handshake.protocol_version.0;
|
||||||
self.protocol_version
|
self.protocol_version
|
||||||
@ -54,11 +52,11 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_status_request(&self, server: &Arc<Server>, _status_request: SStatusRequest) {
|
pub fn handle_status_request(&self, server: &Server, _status_request: SStatusRequest) {
|
||||||
self.send_packet(&server.get_status());
|
self.send_packet(&server.get_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_ping_request(&self, _server: &Arc<Server>, ping_request: SStatusPingRequest) {
|
pub fn handle_ping_request(&self, ping_request: SStatusPingRequest) {
|
||||||
dbg!("ping");
|
dbg!("ping");
|
||||||
self.send_packet(&CPingResponse::new(ping_request.payload));
|
self.send_packet(&CPingResponse::new(ping_request.payload));
|
||||||
self.close();
|
self.close();
|
||||||
@ -71,7 +69,7 @@ impl Client {
|
|||||||
.all(|c| c > 32_u8 as char && c < 127_u8 as char)
|
.all(|c| c > 32_u8 as char && c < 127_u8 as char)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_login_start(&self, server: &Arc<Server>, login_start: SLoginStart) {
|
pub fn handle_login_start(&self, server: &Server, login_start: SLoginStart) {
|
||||||
log::debug!("login start, State {:?}", self.connection_state);
|
log::debug!("login start, State {:?}", self.connection_state);
|
||||||
|
|
||||||
if !Self::is_valid_player_name(&login_start.name) {
|
if !Self::is_valid_player_name(&login_start.name) {
|
||||||
@ -102,7 +100,7 @@ impl Client {
|
|||||||
|
|
||||||
pub async fn handle_encryption_response(
|
pub async fn handle_encryption_response(
|
||||||
&self,
|
&self,
|
||||||
server: &Arc<Server>,
|
server: &Server,
|
||||||
encryption_response: SEncryptionResponse,
|
encryption_response: SEncryptionResponse,
|
||||||
) {
|
) {
|
||||||
let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();
|
let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();
|
||||||
@ -113,18 +111,43 @@ impl Client {
|
|||||||
let mut gameprofile = self.gameprofile.lock();
|
let mut gameprofile = self.gameprofile.lock();
|
||||||
|
|
||||||
if BASIC_CONFIG.online_mode {
|
if BASIC_CONFIG.online_mode {
|
||||||
let hash = server.digest_secret(&shared_secret);
|
match self
|
||||||
let ip = self.address.lock().ip();
|
.autenticate(server, &shared_secret, &gameprofile.as_ref().unwrap().name)
|
||||||
|
|
||||||
match authentication::authenticate(
|
|
||||||
&gameprofile.as_ref().unwrap().name,
|
|
||||||
&hash,
|
|
||||||
&ip,
|
|
||||||
server,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(profile) => {
|
Ok(profile) => *gameprofile = Some(profile),
|
||||||
|
Err(e) => {
|
||||||
|
self.kick(&e.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable compression
|
||||||
|
if ADVANCED_CONFIG.packet_compression.enabled {
|
||||||
|
let compression = ADVANCED_CONFIG.packet_compression.compression_info.clone();
|
||||||
|
self.send_packet(&CSetCompression::new(compression.threshold.into()));
|
||||||
|
self.set_compression(Some(compression));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(profile) = gameprofile.as_ref() {
|
||||||
|
let packet = CLoginSuccess::new(&profile.id, &profile.name, &profile.properties, false);
|
||||||
|
self.send_packet(&packet);
|
||||||
|
} else {
|
||||||
|
self.kick("game profile is none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn autenticate(
|
||||||
|
&self,
|
||||||
|
server: &Server,
|
||||||
|
shared_secret: &[u8],
|
||||||
|
username: &str,
|
||||||
|
) -> Result<GameProfile, AuthError> {
|
||||||
|
if let Some(auth_client) = &server.auth_client {
|
||||||
|
let hash = server.digest_secret(shared_secret);
|
||||||
|
let ip = self.address.lock().ip();
|
||||||
|
|
||||||
|
let profile = authentication::authenticate(username, &hash, &ip, auth_client).await?;
|
||||||
// Check if player should join
|
// Check if player should join
|
||||||
if let Some(actions) = &profile.profile_actions {
|
if let Some(actions) = &profile.profile_actions {
|
||||||
if !ADVANCED_CONFIG
|
if !ADVANCED_CONFIG
|
||||||
@ -147,41 +170,21 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*gameprofile = Some(profile);
|
// validate textures
|
||||||
|
for property in &profile.properties {
|
||||||
|
validate_textures(property, &ADVANCED_CONFIG.authentication.textures)
|
||||||
|
.map_err(AuthError::TextureError)?;
|
||||||
}
|
}
|
||||||
Err(e) => self.kick(&e.to_string()),
|
return Ok(profile);
|
||||||
}
|
}
|
||||||
}
|
Err(AuthError::MissingAuthClient)
|
||||||
for property in &gameprofile.as_ref().unwrap().properties {
|
|
||||||
unpack_textures(property, &ADVANCED_CONFIG.authentication.textures)
|
|
||||||
.unwrap_or_else(|e| self.kick(&e.to_string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable compression
|
pub fn handle_plugin_response(&self, _plugin_response: SLoginPluginResponse) {}
|
||||||
if ADVANCED_CONFIG.packet_compression.enabled {
|
|
||||||
let compression = ADVANCED_CONFIG.packet_compression.compression_info.clone();
|
|
||||||
self.send_packet(&CSetCompression::new(compression.threshold.into()));
|
|
||||||
self.set_compression(Some(compression));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(profile) = gameprofile.as_ref() {
|
|
||||||
let packet = CLoginSuccess::new(&profile.id, &profile.name, &profile.properties, false);
|
|
||||||
self.send_packet(&packet);
|
|
||||||
} else {
|
|
||||||
self.kick("game profile is none");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_plugin_response(
|
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
_plugin_response: SLoginPluginResponse,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_login_acknowledged(
|
pub fn handle_login_acknowledged(
|
||||||
&self,
|
&self,
|
||||||
server: &Arc<Server>,
|
server: &Server,
|
||||||
_login_acknowledged: SLoginAcknowledged,
|
_login_acknowledged: SLoginAcknowledged,
|
||||||
) {
|
) {
|
||||||
self.connection_state.store(ConnectionState::Config);
|
self.connection_state.store(ConnectionState::Config);
|
||||||
@ -215,11 +218,7 @@ impl Client {
|
|||||||
}]));
|
}]));
|
||||||
dbg!("login acknowledged");
|
dbg!("login acknowledged");
|
||||||
}
|
}
|
||||||
pub fn handle_client_information_config(
|
pub fn handle_client_information_config(&self, client_information: SClientInformationConfig) {
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
client_information: SClientInformationConfig,
|
|
||||||
) {
|
|
||||||
dbg!("got client settings");
|
dbg!("got client settings");
|
||||||
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()),
|
||||||
@ -240,7 +239,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_plugin_message(&self, _server: &Arc<Server>, plugin_message: SPluginMessage) {
|
pub fn handle_plugin_message(&self, plugin_message: SPluginMessage) {
|
||||||
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")
|
||||||
{
|
{
|
||||||
@ -252,7 +251,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_known_packs(&self, server: &Arc<Server>, _config_acknowledged: SKnownPacks) {
|
pub fn handle_known_packs(&self, server: &Server, _config_acknowledged: SKnownPacks) {
|
||||||
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,
|
||||||
@ -265,11 +264,7 @@ impl Client {
|
|||||||
self.send_packet(&CFinishConfig::new());
|
self.send_packet(&CFinishConfig::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_config_acknowledged(
|
pub async fn handle_config_acknowledged(&self, _config_acknowledged: SAcknowledgeFinishConfig) {
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
_config_acknowledged: SAcknowledgeFinishConfig,
|
|
||||||
) {
|
|
||||||
dbg!("config acknowledged");
|
dbg!("config acknowledged");
|
||||||
self.connection_state.store(ConnectionState::Play);
|
self.connection_state.store(ConnectionState::Play);
|
||||||
self.make_player
|
self.make_player
|
||||||
|
|||||||
@ -20,7 +20,7 @@ use pumpkin_world::item::ItemStack;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
pub fn open_container(&self, server: &Arc<Server>, minecraft_menu_id: &str) {
|
pub fn open_container(&self, server: &Server, minecraft_menu_id: &str) {
|
||||||
let inventory = self.inventory.lock();
|
let inventory = self.inventory.lock();
|
||||||
inventory
|
inventory
|
||||||
.state_id
|
.state_id
|
||||||
|
|||||||
@ -222,9 +222,7 @@ impl Client {
|
|||||||
packet: &mut RawPacket,
|
packet: &mut RawPacket,
|
||||||
) -> Result<(), DeserializerError> {
|
) -> Result<(), DeserializerError> {
|
||||||
match self.connection_state.load() {
|
match self.connection_state.load() {
|
||||||
pumpkin_protocol::ConnectionState::HandShake => {
|
pumpkin_protocol::ConnectionState::HandShake => self.handle_handshake_packet(packet),
|
||||||
self.handle_handshake_packet(server, packet)
|
|
||||||
}
|
|
||||||
pumpkin_protocol::ConnectionState::Status => self.handle_status_packet(server, packet),
|
pumpkin_protocol::ConnectionState::Status => self.handle_status_packet(server, packet),
|
||||||
// TODO: Check config if transfer is enabled
|
// TODO: Check config if transfer is enabled
|
||||||
pumpkin_protocol::ConnectionState::Login
|
pumpkin_protocol::ConnectionState::Login
|
||||||
@ -241,15 +239,11 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_handshake_packet(
|
fn handle_handshake_packet(&self, packet: &mut RawPacket) -> Result<(), DeserializerError> {
|
||||||
&self,
|
|
||||||
server: &Arc<Server>,
|
|
||||||
packet: &mut RawPacket,
|
|
||||||
) -> Result<(), DeserializerError> {
|
|
||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
match packet.id.0 {
|
match packet.id.0 {
|
||||||
SHandShake::PACKET_ID => {
|
SHandShake::PACKET_ID => {
|
||||||
self.handle_handshake(server, SHandShake::read(bytebuf)?);
|
self.handle_handshake(SHandShake::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -274,7 +268,7 @@ impl Client {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SStatusPingRequest::PACKET_ID => {
|
SStatusPingRequest::PACKET_ID => {
|
||||||
self.handle_ping_request(server, SStatusPingRequest::read(bytebuf)?);
|
self.handle_ping_request(SStatusPingRequest::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -304,7 +298,7 @@ impl Client {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SLoginPluginResponse::PACKET_ID => {
|
SLoginPluginResponse::PACKET_ID => {
|
||||||
self.handle_plugin_response(server, SLoginPluginResponse::read(bytebuf)?);
|
self.handle_plugin_response(SLoginPluginResponse::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SLoginAcknowledged::PACKET_ID => {
|
SLoginAcknowledged::PACKET_ID => {
|
||||||
@ -329,18 +323,15 @@ impl Client {
|
|||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
match packet.id.0 {
|
match packet.id.0 {
|
||||||
SClientInformationConfig::PACKET_ID => {
|
SClientInformationConfig::PACKET_ID => {
|
||||||
self.handle_client_information_config(
|
self.handle_client_information_config(SClientInformationConfig::read(bytebuf)?);
|
||||||
server,
|
|
||||||
SClientInformationConfig::read(bytebuf)?,
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPluginMessage::PACKET_ID => {
|
SPluginMessage::PACKET_ID => {
|
||||||
self.handle_plugin_message(server, SPluginMessage::read(bytebuf)?);
|
self.handle_plugin_message(SPluginMessage::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SAcknowledgeFinishConfig::PACKET_ID => {
|
SAcknowledgeFinishConfig::PACKET_ID => {
|
||||||
self.handle_config_acknowledged(server, SAcknowledgeFinishConfig::read(bytebuf)?)
|
self.handle_config_acknowledged(SAcknowledgeFinishConfig::read(bytebuf)?)
|
||||||
.await;
|
.await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::{f32::consts::PI, sync::Arc};
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::CommandSender,
|
commands::CommandSender,
|
||||||
@ -41,11 +41,7 @@ fn modulus(a: f32, b: f32) -> f32 {
|
|||||||
/// Handles all Play Packets send by a real Player
|
/// Handles all Play Packets send by a real Player
|
||||||
/// NEVER TRUST THE CLIENT. HANDLE EVERY ERROR, UNWRAP/EXPECT ARE FORBIDDEN
|
/// NEVER TRUST THE CLIENT. HANDLE EVERY ERROR, UNWRAP/EXPECT ARE FORBIDDEN
|
||||||
impl Player {
|
impl Player {
|
||||||
pub fn handle_confirm_teleport(
|
pub fn handle_confirm_teleport(&self, confirm_teleport: SConfirmTeleport) {
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
confirm_teleport: SConfirmTeleport,
|
|
||||||
) {
|
|
||||||
let mut awaiting_teleport = self.awaiting_teleport.lock();
|
let mut awaiting_teleport = self.awaiting_teleport.lock();
|
||||||
if let Some((id, position)) = awaiting_teleport.as_ref() {
|
if let Some((id, position)) = awaiting_teleport.as_ref() {
|
||||||
if id == &confirm_teleport.teleport_id {
|
if id == &confirm_teleport.teleport_id {
|
||||||
@ -73,7 +69,7 @@ impl Player {
|
|||||||
pos.clamp(-2.0E7, 2.0E7)
|
pos.clamp(-2.0E7, 2.0E7)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_position(&self, _server: &Arc<Server>, position: SPlayerPosition) {
|
pub async fn handle_position(&self, position: SPlayerPosition) {
|
||||||
if position.x.is_nan() || position.feet_y.is_nan() || position.z.is_nan() {
|
if position.x.is_nan() || position.feet_y.is_nan() || position.z.is_nan() {
|
||||||
self.kick(TextComponent::text("Invalid movement"));
|
self.kick(TextComponent::text("Invalid movement"));
|
||||||
return;
|
return;
|
||||||
@ -121,11 +117,7 @@ impl Player {
|
|||||||
player_chunker::update_position(entity, self).await;
|
player_chunker::update_position(entity, self).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_position_rotation(
|
pub async fn handle_position_rotation(&self, position_rotation: SPlayerPositionRotation) {
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
position_rotation: SPlayerPositionRotation,
|
|
||||||
) {
|
|
||||||
if position_rotation.x.is_nan()
|
if position_rotation.x.is_nan()
|
||||||
|| position_rotation.feet_y.is_nan()
|
|| position_rotation.feet_y.is_nan()
|
||||||
|| position_rotation.z.is_nan()
|
|| position_rotation.z.is_nan()
|
||||||
@ -197,7 +189,7 @@ impl Player {
|
|||||||
player_chunker::update_position(entity, self).await;
|
player_chunker::update_position(entity, self).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_rotation(&self, _server: &Arc<Server>, rotation: SPlayerRotation) {
|
pub async fn handle_rotation(&self, rotation: SPlayerRotation) {
|
||||||
if !rotation.yaw.is_finite() || !rotation.pitch.is_finite() {
|
if !rotation.yaw.is_finite() || !rotation.pitch.is_finite() {
|
||||||
self.kick(TextComponent::text("Invalid rotation"));
|
self.kick(TextComponent::text("Invalid rotation"));
|
||||||
return;
|
return;
|
||||||
@ -224,7 +216,7 @@ impl Player {
|
|||||||
world.broadcast_packet_expect(&[self.client.token], &packet);
|
world.broadcast_packet_expect(&[self.client.token], &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_chat_command(&self, server: &Arc<Server>, command: SChatCommand) {
|
pub fn handle_chat_command(&self, server: &Server, command: SChatCommand) {
|
||||||
let dispatcher = server.command_dispatcher.clone();
|
let dispatcher = server.command_dispatcher.clone();
|
||||||
dispatcher.handle_command(&mut CommandSender::Player(self), server, &command.command);
|
dispatcher.handle_command(&mut CommandSender::Player(self), server, &command.command);
|
||||||
if ADVANCED_CONFIG.commands.log_console {
|
if ADVANCED_CONFIG.commands.log_console {
|
||||||
@ -236,14 +228,14 @@ impl Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_player_ground(&self, _server: &Arc<Server>, ground: SSetPlayerGround) {
|
pub fn handle_player_ground(&self, ground: SSetPlayerGround) {
|
||||||
self.living_entity
|
self.living_entity
|
||||||
.entity
|
.entity
|
||||||
.on_ground
|
.on_ground
|
||||||
.store(ground.on_ground, std::sync::atomic::Ordering::Relaxed);
|
.store(ground.on_ground, std::sync::atomic::Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_player_command(&self, _server: &Arc<Server>, command: SPlayerCommand) {
|
pub async fn handle_player_command(&self, command: SPlayerCommand) {
|
||||||
if command.entity_id != self.entity_id().into() {
|
if command.entity_id != self.entity_id().into() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -291,7 +283,7 @@ impl Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_swing_arm(&self, _server: &Arc<Server>, swing_arm: SSwingArm) {
|
pub async fn handle_swing_arm(&self, swing_arm: SSwingArm) {
|
||||||
match Hand::from_i32(swing_arm.hand.0) {
|
match Hand::from_i32(swing_arm.hand.0) {
|
||||||
Some(hand) => {
|
Some(hand) => {
|
||||||
let animation = match hand {
|
let animation = match hand {
|
||||||
@ -311,7 +303,7 @@ impl Player {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_chat_message(&self, _server: &Arc<Server>, chat_message: SChatMessage) {
|
pub async fn handle_chat_message(&self, chat_message: SChatMessage) {
|
||||||
dbg!("got message");
|
dbg!("got message");
|
||||||
|
|
||||||
let message = chat_message.message;
|
let message = chat_message.message;
|
||||||
@ -351,11 +343,7 @@ impl Player {
|
|||||||
) */
|
) */
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_client_information_play(
|
pub fn handle_client_information_play(&self, client_information: SClientInformationPlay) {
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
client_information: SClientInformationPlay,
|
|
||||||
) {
|
|
||||||
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()),
|
||||||
@ -375,7 +363,7 @@ impl Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_interact(&self, _: &Arc<Server>, interact: SInteract) {
|
pub async fn handle_interact(&self, _: &Server, interact: SInteract) {
|
||||||
let sneaking = interact.sneaking;
|
let sneaking = interact.sneaking;
|
||||||
let entity = &self.living_entity.entity;
|
let entity = &self.living_entity.entity;
|
||||||
if entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) != sneaking {
|
if entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) != sneaking {
|
||||||
@ -443,7 +431,7 @@ impl Player {
|
|||||||
None => self.kick(TextComponent::text("Invalid action type")),
|
None => self.kick(TextComponent::text("Invalid action type")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn handle_player_action(&self, _server: &Arc<Server>, player_action: SPlayerAction) {
|
pub async fn handle_player_action(&self, player_action: SPlayerAction) {
|
||||||
match Status::from_i32(player_action.status.0) {
|
match Status::from_i32(player_action.status.0) {
|
||||||
Some(status) => match status {
|
Some(status) => match status {
|
||||||
Status::StartedDigging => {
|
Status::StartedDigging => {
|
||||||
@ -507,12 +495,12 @@ impl Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_play_ping_request(&self, _server: &Arc<Server>, request: SPlayPingRequest) {
|
pub fn handle_play_ping_request(&self, request: SPlayPingRequest) {
|
||||||
self.client
|
self.client
|
||||||
.send_packet(&CPingResponse::new(request.payload));
|
.send_packet(&CPingResponse::new(request.payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_use_item_on(&self, _server: &Arc<Server>, use_item_on: SUseItemOn) {
|
pub async fn handle_use_item_on(&self, use_item_on: SUseItemOn) {
|
||||||
let location = use_item_on.location;
|
let location = use_item_on.location;
|
||||||
|
|
||||||
if !self.can_interact_with_block_at(&location, 1.0) {
|
if !self.can_interact_with_block_at(&location, 1.0) {
|
||||||
@ -547,12 +535,12 @@ impl Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_use_item(&self, _server: &Arc<Server>, _use_item: SUseItem) {
|
pub fn handle_use_item(&self, _use_item: SUseItem) {
|
||||||
// TODO: handle packet correctly
|
// TODO: handle packet correctly
|
||||||
log::error!("An item was used(SUseItem), but the packet is not implemented yet");
|
log::error!("An item was used(SUseItem), but the packet is not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_set_held_item(&self, _server: &Arc<Server>, held: SSetHeldItem) {
|
pub fn handle_set_held_item(&self, held: SSetHeldItem) {
|
||||||
let slot = held.slot;
|
let slot = held.slot;
|
||||||
if !(0..=8).contains(&slot) {
|
if !(0..=8).contains(&slot) {
|
||||||
self.kick(TextComponent::text("Invalid held slot"))
|
self.kick(TextComponent::text("Invalid held slot"))
|
||||||
@ -560,11 +548,7 @@ impl Player {
|
|||||||
self.inventory.lock().set_selected(slot as usize);
|
self.inventory.lock().set_selected(slot as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_set_creative_slot(
|
pub fn handle_set_creative_slot(&self, packet: SSetCreativeSlot) -> Result<(), InventoryError> {
|
||||||
&self,
|
|
||||||
_server: &Arc<Server>,
|
|
||||||
packet: SSetCreativeSlot,
|
|
||||||
) -> Result<(), InventoryError> {
|
|
||||||
if self.gamemode.load() != GameMode::Creative {
|
if self.gamemode.load() != GameMode::Creative {
|
||||||
return Err(InventoryError::PermissionError);
|
return Err(InventoryError::PermissionError);
|
||||||
}
|
}
|
||||||
@ -576,7 +560,7 @@ impl Player {
|
|||||||
// TODO:
|
// TODO:
|
||||||
// This function will in the future be used to keep track of if the client is in a valid state.
|
// This function will in the future be used to keep track of if the client is in a valid state.
|
||||||
// But this is not possible yet
|
// But this is not possible yet
|
||||||
pub fn handle_close_container(&self, server: &Arc<Server>, packet: SCloseContainer) {
|
pub fn handle_close_container(&self, server: &Server, packet: SCloseContainer) {
|
||||||
// window_id 0 represents both 9x1 Generic AND inventory here
|
// window_id 0 represents both 9x1 Generic AND inventory here
|
||||||
self.inventory
|
self.inventory
|
||||||
.lock()
|
.lock()
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crate::commands::dispatcher::InvalidTreeError;
|
use crate::commands::dispatcher::InvalidTreeError;
|
||||||
use crate::commands::dispatcher::InvalidTreeError::InvalidConsumptionError;
|
use crate::commands::dispatcher::InvalidTreeError::InvalidConsumptionError;
|
||||||
use crate::commands::tree::{ConsumedArgs, RawArgs};
|
use crate::commands::tree::{ConsumedArgs, RawArgs};
|
||||||
@ -32,7 +30,7 @@ pub fn consume_arg_player(src: &CommandSender, args: &mut RawArgs) -> Option<Str
|
|||||||
/// todo: implement (so far only own name + @s/@p is implemented)
|
/// todo: implement (so far only own name + @s/@p is implemented)
|
||||||
pub fn parse_arg_player<'a>(
|
pub fn parse_arg_player<'a>(
|
||||||
src: &'a mut CommandSender,
|
src: &'a mut CommandSender,
|
||||||
_server: &Arc<Server>,
|
_server: &Server,
|
||||||
arg_name: &str,
|
arg_name: &str,
|
||||||
consumed_args: &ConsumedArgs,
|
consumed_args: &ConsumedArgs,
|
||||||
) -> Result<&'a crate::entity::player::Player, InvalidTreeError> {
|
) -> Result<&'a crate::entity::player::Player, InvalidTreeError> {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ use crate::commands::tree::{Command, CommandTree, ConsumedArgs, NodeType, RawArg
|
|||||||
use crate::commands::CommandSender;
|
use crate::commands::CommandSender;
|
||||||
use crate::server::Server;
|
use crate::server::Server;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum InvalidTreeError {
|
pub(crate) enum InvalidTreeError {
|
||||||
@ -27,7 +26,7 @@ pub struct CommandDispatcher<'a> {
|
|||||||
|
|
||||||
/// Stores registered [CommandTree]s and dispatches commands to them.
|
/// Stores registered [CommandTree]s and dispatches commands to them.
|
||||||
impl<'a> CommandDispatcher<'a> {
|
impl<'a> CommandDispatcher<'a> {
|
||||||
pub fn handle_command(&self, sender: &mut CommandSender, server: &Arc<Server>, cmd: &str) {
|
pub fn handle_command(&self, sender: &mut CommandSender, server: &Server, cmd: &str) {
|
||||||
if let Err(err) = self.dispatch(sender, server, cmd) {
|
if let Err(err) = self.dispatch(sender, server, cmd) {
|
||||||
sender.send_message(
|
sender.send_message(
|
||||||
TextComponent::text(&err).color_named(pumpkin_core::text::color::NamedColor::Red),
|
TextComponent::text(&err).color_named(pumpkin_core::text::color::NamedColor::Red),
|
||||||
@ -39,7 +38,7 @@ impl<'a> CommandDispatcher<'a> {
|
|||||||
pub(crate) fn dispatch(
|
pub(crate) fn dispatch(
|
||||||
&'a self,
|
&'a self,
|
||||||
src: &mut CommandSender,
|
src: &mut CommandSender,
|
||||||
server: &Arc<Server>,
|
server: &Server,
|
||||||
cmd: &str,
|
cmd: &str,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let mut parts = cmd.split_ascii_whitespace();
|
let mut parts = cmd.split_ascii_whitespace();
|
||||||
@ -87,7 +86,7 @@ impl<'a> CommandDispatcher<'a> {
|
|||||||
|
|
||||||
fn try_is_fitting_path(
|
fn try_is_fitting_path(
|
||||||
src: &mut CommandSender,
|
src: &mut CommandSender,
|
||||||
server: &Arc<Server>,
|
server: &Server,
|
||||||
path: Vec<usize>,
|
path: Vec<usize>,
|
||||||
tree: &CommandTree,
|
tree: &CommandTree,
|
||||||
mut raw_args: RawArgs,
|
mut raw_args: RawArgs,
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use dispatcher::InvalidTreeError;
|
use dispatcher::InvalidTreeError;
|
||||||
use pumpkin_core::text::TextComponent;
|
use pumpkin_core::text::TextComponent;
|
||||||
use tree::ConsumedArgs;
|
use tree::ConsumedArgs;
|
||||||
@ -81,5 +79,5 @@ pub fn default_dispatcher<'a>() -> CommandDispatcher<'a> {
|
|||||||
dispatcher
|
dispatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunFunctionType = (dyn Fn(&mut CommandSender, &Arc<Server>, &ConsumedArgs) -> Result<(), InvalidTreeError>
|
type RunFunctionType =
|
||||||
+ Sync);
|
(dyn Fn(&mut CommandSender, &Server, &ConsumedArgs) -> Result<(), InvalidTreeError> + Sync);
|
||||||
|
|||||||
@ -294,7 +294,7 @@ impl Player {
|
|||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
match packet.id.0 {
|
match packet.id.0 {
|
||||||
SConfirmTeleport::PACKET_ID => {
|
SConfirmTeleport::PACKET_ID => {
|
||||||
self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf)?);
|
self.handle_confirm_teleport(SConfirmTeleport::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SChatCommand::PACKET_ID => {
|
SChatCommand::PACKET_ID => {
|
||||||
@ -302,41 +302,37 @@ impl Player {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPlayerPosition::PACKET_ID => {
|
SPlayerPosition::PACKET_ID => {
|
||||||
self.handle_position(server, SPlayerPosition::read(bytebuf)?)
|
self.handle_position(SPlayerPosition::read(bytebuf)?).await;
|
||||||
.await;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPlayerPositionRotation::PACKET_ID => {
|
SPlayerPositionRotation::PACKET_ID => {
|
||||||
self.handle_position_rotation(server, SPlayerPositionRotation::read(bytebuf)?)
|
self.handle_position_rotation(SPlayerPositionRotation::read(bytebuf)?)
|
||||||
.await;
|
.await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPlayerRotation::PACKET_ID => {
|
SPlayerRotation::PACKET_ID => {
|
||||||
self.handle_rotation(server, SPlayerRotation::read(bytebuf)?)
|
self.handle_rotation(SPlayerRotation::read(bytebuf)?).await;
|
||||||
.await;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SSetPlayerGround::PACKET_ID => {
|
SSetPlayerGround::PACKET_ID => {
|
||||||
self.handle_player_ground(server, SSetPlayerGround::read(bytebuf)?);
|
self.handle_player_ground(SSetPlayerGround::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPlayerCommand::PACKET_ID => {
|
SPlayerCommand::PACKET_ID => {
|
||||||
self.handle_player_command(server, SPlayerCommand::read(bytebuf)?)
|
self.handle_player_command(SPlayerCommand::read(bytebuf)?)
|
||||||
.await;
|
.await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SSwingArm::PACKET_ID => {
|
SSwingArm::PACKET_ID => {
|
||||||
self.handle_swing_arm(server, SSwingArm::read(bytebuf)?)
|
self.handle_swing_arm(SSwingArm::read(bytebuf)?).await;
|
||||||
.await;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SChatMessage::PACKET_ID => {
|
SChatMessage::PACKET_ID => {
|
||||||
self.handle_chat_message(server, SChatMessage::read(bytebuf)?)
|
self.handle_chat_message(SChatMessage::read(bytebuf)?).await;
|
||||||
.await;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SClientInformationPlay::PACKET_ID => {
|
SClientInformationPlay::PACKET_ID => {
|
||||||
self.handle_client_information_play(server, SClientInformationPlay::read(bytebuf)?);
|
self.handle_client_information_play(SClientInformationPlay::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SInteract::PACKET_ID => {
|
SInteract::PACKET_ID => {
|
||||||
@ -345,30 +341,29 @@ impl Player {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPlayerAction::PACKET_ID => {
|
SPlayerAction::PACKET_ID => {
|
||||||
self.handle_player_action(server, SPlayerAction::read(bytebuf)?)
|
self.handle_player_action(SPlayerAction::read(bytebuf)?)
|
||||||
.await;
|
.await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SUseItemOn::PACKET_ID => {
|
SUseItemOn::PACKET_ID => {
|
||||||
self.handle_use_item_on(server, SUseItemOn::read(bytebuf)?)
|
self.handle_use_item_on(SUseItemOn::read(bytebuf)?).await;
|
||||||
.await;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SUseItem::PACKET_ID => {
|
SUseItem::PACKET_ID => {
|
||||||
self.handle_use_item(server, SUseItem::read(bytebuf)?);
|
self.handle_use_item(SUseItem::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SSetHeldItem::PACKET_ID => {
|
SSetHeldItem::PACKET_ID => {
|
||||||
self.handle_set_held_item(server, SSetHeldItem::read(bytebuf)?);
|
self.handle_set_held_item(SSetHeldItem::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SSetCreativeSlot::PACKET_ID => {
|
SSetCreativeSlot::PACKET_ID => {
|
||||||
self.handle_set_creative_slot(server, SSetCreativeSlot::read(bytebuf)?)
|
self.handle_set_creative_slot(SSetCreativeSlot::read(bytebuf)?)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SPlayPingRequest::PACKET_ID => {
|
SPlayPingRequest::PACKET_ID => {
|
||||||
self.handle_play_ping_request(server, SPlayPingRequest::read(bytebuf)?);
|
self.handle_play_ping_request(SPlayPingRequest::read(bytebuf)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SClickContainer::PACKET_ID => {
|
SClickContainer::PACKET_ID => {
|
||||||
|
|||||||
@ -36,7 +36,6 @@ pub mod entity;
|
|||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
pub mod rcon;
|
pub mod rcon;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod util;
|
|
||||||
pub mod world;
|
pub mod world;
|
||||||
|
|
||||||
fn init_logger() {
|
fn init_logger() {
|
||||||
@ -154,7 +153,7 @@ fn main() -> io::Result<()> {
|
|||||||
if rcon.enabled {
|
if rcon.enabled {
|
||||||
let server = server.clone();
|
let server = server.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
RCONServer::new(&rcon, server).await.unwrap();
|
RCONServer::new(&rcon, &server).await.unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
@ -167,7 +166,7 @@ fn main() -> io::Result<()> {
|
|||||||
|
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
match event.token() {
|
match event.token() {
|
||||||
SERVER => loop {
|
s if s == SERVER => loop {
|
||||||
// Received an event for the TCP server socket, which
|
// Received an event for the TCP server socket, which
|
||||||
// indicates we can accept an connection.
|
// indicates we can accept an connection.
|
||||||
let (mut connection, address) = match listener.accept() {
|
let (mut connection, address) = match listener.accept() {
|
||||||
@ -236,7 +235,7 @@ fn main() -> io::Result<()> {
|
|||||||
},
|
},
|
||||||
// Maybe received an event for a TCP connection.
|
// Maybe received an event for a TCP connection.
|
||||||
token => {
|
token => {
|
||||||
// Poll Players
|
// poll Player
|
||||||
if let Some(player) = players.get_mut(&token) {
|
if let Some(player) = players.get_mut(&token) {
|
||||||
player.client.poll(event).await;
|
player.client.poll(event).await;
|
||||||
let closed = player
|
let closed = player
|
||||||
@ -269,7 +268,6 @@ fn main() -> io::Result<()> {
|
|||||||
.load(std::sync::atomic::Ordering::Relaxed),
|
.load(std::sync::atomic::Ordering::Relaxed),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// Sporadic events happen, we can safely ignore them.
|
|
||||||
(false, false)
|
(false, false)
|
||||||
};
|
};
|
||||||
if done || make_player {
|
if done || make_player {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ use std::{
|
|||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mio::{
|
use mio::{
|
||||||
@ -32,7 +31,7 @@ const SERVER: Token = Token(0);
|
|||||||
pub struct RCONServer;
|
pub struct RCONServer;
|
||||||
|
|
||||||
impl RCONServer {
|
impl RCONServer {
|
||||||
pub async fn new(config: &RCONConfig, server: Arc<Server>) -> Result<Self, io::Error> {
|
pub async fn new(config: &RCONConfig, server: &Server) -> Result<Self, io::Error> {
|
||||||
assert!(config.enabled, "RCON is not enabled");
|
assert!(config.enabled, "RCON is not enabled");
|
||||||
let mut poll = Poll::new().unwrap();
|
let mut poll = Poll::new().unwrap();
|
||||||
let mut listener = TcpListener::bind(config.address).unwrap();
|
let mut listener = TcpListener::bind(config.address).unwrap();
|
||||||
@ -91,7 +90,7 @@ impl RCONServer {
|
|||||||
|
|
||||||
token => {
|
token => {
|
||||||
let done = if let Some(client) = connections.get_mut(&token) {
|
let done = if let Some(client) = connections.get_mut(&token) {
|
||||||
client.handle(&server, &password).await
|
client.handle(server, &password).await
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
@ -139,7 +138,7 @@ impl RCONClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle(&mut self, server: &Arc<Server>, password: &str) -> bool {
|
pub async fn handle(&mut self, server: &Server, password: &str) -> bool {
|
||||||
if !self.closed {
|
if !self.closed {
|
||||||
loop {
|
loop {
|
||||||
match self.read_bytes() {
|
match self.read_bytes() {
|
||||||
@ -162,7 +161,7 @@ impl RCONClient {
|
|||||||
self.closed
|
self.closed
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn poll(&mut self, server: &Arc<Server>, password: &str) -> Result<(), PacketError> {
|
async fn poll(&mut self, server: &Server, password: &str) -> Result<(), PacketError> {
|
||||||
loop {
|
loop {
|
||||||
let packet = match self.receive_packet().await? {
|
let packet = match self.receive_packet().await? {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
|
|||||||
@ -83,7 +83,7 @@ impl CachedStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_icon(path: &str) -> String {
|
fn load_icon<P: AsRef<Path>>(path: P) -> String {
|
||||||
let icon = png::Decoder::new(File::open(path).expect("Failed to load icon"));
|
let icon = png::Decoder::new(File::open(path).expect("Failed to load icon"));
|
||||||
let mut reader = icon.read_info().unwrap();
|
let mut reader = icon.read_info().unwrap();
|
||||||
let info = reader.info();
|
let info = reader.info();
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use pumpkin_protocol::client::login::CEncryptionRequest;
|
use pumpkin_protocol::client::login::CEncryptionRequest;
|
||||||
|
use rand::rngs::OsRng;
|
||||||
use rsa::{traits::PublicKeyParts as _, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
|
use rsa::{traits::PublicKeyParts as _, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
@ -30,7 +31,8 @@ impl KeyStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_keys() -> (RsaPublicKey, RsaPrivateKey) {
|
fn generate_keys() -> (RsaPublicKey, RsaPrivateKey) {
|
||||||
let mut rng = rand::thread_rng();
|
// Found out that OsRng is faster than rand::thread_rng here
|
||||||
|
let mut rng = OsRng;
|
||||||
|
|
||||||
let priv_key = RsaPrivateKey::new(&mut rng, 1024).expect("failed to generate a key");
|
let priv_key = RsaPrivateKey::new(&mut rng, 1024).expect("failed to generate a key");
|
||||||
let pub_key = RsaPublicKey::from(&priv_key);
|
let pub_key = RsaPublicKey::from(&priv_key);
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user