Skip to content

Commit

Permalink
Add WIP Resource Pack support
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Aug 9, 2024
1 parent 770d73f commit 76106de
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 22 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions pumpkin-protocol/src/client/config/c_add_resource_pack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use pumpkin_macros::packet;
use pumpkin_text::TextComponent;
use serde::Serialize;

#[derive(Serialize)]
#[packet(0x09)]
pub struct CConfigAddResourcePack {
uuid: uuid::Uuid,
url: String,
hash: String,
forced: bool,
prompt_message: Option<TextComponent>,
}

impl CConfigAddResourcePack {
pub fn new(
uuid: uuid::Uuid,
url: String,
hash: String,
forced: bool,
prompt_message: Option<TextComponent>,
) -> Self {
Self {
uuid,
url,
hash,
forced,
prompt_message,
}
}
}
2 changes: 2 additions & 0 deletions pumpkin-protocol/src/client/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
mod c_add_resource_pack;
mod c_config_disconnect;
mod c_cookie_request;
mod c_finish_config;
mod c_known_packs;
mod c_plugin_message;
mod c_registry_data;

pub use c_add_resource_pack::*;
pub use c_config_disconnect::*;
pub use c_cookie_request::*;
pub use c_finish_config::*;
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ log = "0.4"
mio = { version = "1.0.1", features = ["os-poll", "net"]}
crossbeam-channel = "0.5.13"

uuid = { version = "1.10", features = ["serde"]}
uuid = { version = "1.10", features = ["serde", "v3"]}

tokio.workspace = true
10 changes: 6 additions & 4 deletions pumpkin/src/client/authentication.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{collections::HashMap, net::IpAddr};
use std::{collections::HashMap, net::IpAddr, time::Duration};

use base64::{engine::general_purpose, Engine};
use num_bigint::BigInt;
use pumpkin_protocol::Property;
use reqwest::{StatusCode, Url};
use reqwest::{header::CONTENT_TYPE, StatusCode, Url};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use uuid::Uuid;
Expand Down Expand Up @@ -52,14 +52,16 @@ pub async fn authenticate(
ip: &IpAddr,
server: &mut Server,
) -> Result<GameProfile, AuthError> {
assert!(server.advanced_config.authentication.use_authentication);
assert!(server.advanced_config.authentication.enabled);
assert!(server.auth_client.is_some());
let address = if server
.advanced_config
.authentication
.prevent_proxy_connections
{
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={server_hash}&ip={ip}")
let test = format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={server_hash}&ip={ip}");
dbg!(&test);
test
} else {
format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={server_hash}")
};
Expand Down
22 changes: 21 additions & 1 deletion pumpkin/src/client/client_packet.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::str::FromStr;

use num_traits::FromPrimitive;
use pumpkin_protocol::{
client::{
config::{CFinishConfig, CKnownPacks, CRegistryData},
config::{CConfigAddResourcePack, CFinishConfig, CKnownPacks, CRegistryData},
login::{CEncryptionRequest, CLoginSuccess, CSetCompression},
status::{CPingResponse, CStatusResponse},
},
Expand All @@ -14,6 +16,7 @@ use pumpkin_protocol::{
ConnectionState, KnownPack, RawBytes,
};
use pumpkin_registry::Registry;
use pumpkin_text::TextComponent;
use rsa::Pkcs1v15Encrypt;
use sha1::{Digest, Sha1};

Expand Down Expand Up @@ -167,6 +170,23 @@ impl Client {
) {
self.connection_state = ConnectionState::Config;
server.send_brand(self);

let resource_config = &server.advanced_config.resource_pack;
if resource_config.enabled {
let prompt_message = if resource_config.prompt_message.is_empty() {
None
} else {
Some(TextComponent::from(resource_config.prompt_message.clone()))
};
self.send_packet(CConfigAddResourcePack::new(
uuid::Uuid::from_str(&resource_config.resource_pack_url).unwrap(),
resource_config.resource_pack_url.clone(),
resource_config.resource_pack_sha1.clone(),
resource_config.force,
prompt_message,
));
}

// known data packs
self.send_packet(CKnownPacks::new(&[KnownPack {
namespace: "minecraft",
Expand Down
4 changes: 2 additions & 2 deletions pumpkin/src/config/auth_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::client::authentication::ProfileAction;
#[derive(Deserialize, Serialize)]
pub struct Authentication {
/// Whether to use Mojang authentication.
pub use_authentication: bool,
pub enabled: bool,

/// Prevent proxy connections.
pub prevent_proxy_connections: bool,
Expand Down Expand Up @@ -84,7 +84,7 @@ impl Default for TextureTypes {
impl Default for Authentication {
fn default() -> Self {
Self {
use_authentication: true,
enabled: true,
prevent_proxy_connections: true,
player_profile: Default::default(),
textures: Default::default(),
Expand Down
28 changes: 15 additions & 13 deletions pumpkin/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::path::Path;

use auth_config::Authentication;
use resource_pack::ResourcePack;
use serde::{Deserialize, Serialize};

use crate::{entity::player::GameMode, server::Difficulty};

pub mod auth_config;
pub mod resource_pack;

/// Current Config version of the Base Config
const CURRENT_BASE_VERSION: &str = "1.0.0";
Expand All @@ -18,6 +20,7 @@ pub struct AdvancedConfiguration {
pub commands: Commands,
pub authentication: Authentication,
pub packet_compression: Compression,
pub resource_pack: ResourcePack,
}

#[derive(Deserialize, Serialize)]
Expand Down Expand Up @@ -63,6 +66,7 @@ impl Default for AdvancedConfiguration {
authentication: Authentication::default(),
commands: Commands::default(),
packet_compression: Compression::default(),
resource_pack: ResourcePack::default(),
}
}
}
Expand All @@ -83,10 +87,6 @@ pub struct BasicConfiguration {
pub view_distance: u8,
/// The maximum simulated view distance.
pub simulation_distance: u8,
/// The path to the resource pack.
pub resource_pack: String,
/// The SHA1 hash of the resource pack.
pub resource_pack_sha1: String,
/// The default game difficulty.
pub default_difficulty: Difficulty,
/// Whether the Nether dimension is enabled.
Expand All @@ -113,8 +113,6 @@ impl Default for BasicConfiguration {
max_players: 100000,
view_distance: 10,
simulation_distance: 10,
resource_pack: "".to_string(),
resource_pack_sha1: "".to_string(),
default_difficulty: Difficulty::Normal,
allow_nether: true,
hardcore: false,
Expand All @@ -130,21 +128,30 @@ impl AdvancedConfiguration {
pub fn load<P: AsRef<Path>>(path: P) -> AdvancedConfiguration {
if path.as_ref().exists() {
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
toml::from_str(toml.as_str()).expect("Couldn't parse, Proberbly old config")
let config: AdvancedConfiguration =
toml::from_str(toml.as_str()).expect("Couldn't parse features.toml, Proberbly old config, Replacing with a new one or just delete it");
config.validate();
config
} else {
let config = AdvancedConfiguration::default();
let toml = toml::to_string(&config).expect("Couldn't create toml!");
std::fs::write(path, toml).expect("Couldn't save configuration");
config.validate();
config
}
}
pub fn validate(&self) {
self.resource_pack.validate()
}
}

impl BasicConfiguration {
pub fn load<P: AsRef<Path>>(path: P) -> BasicConfiguration {
if path.as_ref().exists() {
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
toml::from_str(toml.as_str()).expect("Couldn't parse")
let config: BasicConfiguration = toml::from_str(toml.as_str()).expect("Couldn't parse configuration.toml, Proberbly old config, Replacing with a new one or just delete it");
config.validate();
config
} else {
let config = BasicConfiguration::default();
let toml = toml::to_string(&config).expect("Couldn't create toml!");
Expand All @@ -170,10 +177,5 @@ impl BasicConfiguration {
"When Online Mode is enabled, Encryption must be enabled"
)
}
assert_eq!(
!self.resource_pack.is_empty(),
!self.resource_pack_sha1.is_empty(),
"Resource Pack path or Sha1 hash is missing"
);
}
}
40 changes: 40 additions & 0 deletions pumpkin/src/config/resource_pack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
pub struct ResourcePack {
pub enabled: bool,
/// The path to the resource pack.
pub resource_pack_url: String,
/// The SHA1 hash (40) of the resource pack.
pub resource_pack_sha1: String,
/// Custom propmt Text component, Leave blank for none
pub prompt_message: String,
/// Will force the Player to accept the resource pack
pub force: bool,
}

impl ResourcePack {
pub fn validate(&self) {
assert_eq!(
!self.resource_pack_url.is_empty(),
!self.resource_pack_sha1.is_empty(),
"Resource Pack path or Sha1 hash is missing"
);
assert!(
self.resource_pack_sha1.len() <= 40,
"Resource pack sha1 hash is too long (max. 40)"
)
}
}

impl Default for ResourcePack {
fn default() -> Self {
Self {
enabled: false,
resource_pack_url: "".into(),
resource_pack_sha1: "".into(),
force: false,
prompt_message: "".into(),
}
}
}
8 changes: 7 additions & 1 deletion pumpkin/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{
io::Cursor,
rc::Rc,
sync::atomic::{AtomicI32, Ordering},
time::Duration,
};

use base64::{engine::general_purpose, Engine};
Expand Down Expand Up @@ -77,7 +78,12 @@ impl Server {
)
.into_boxed_slice();
let auth_client = if config.0.online_mode {
Some(reqwest::Client::new())
Some(
reqwest::Client::builder()
.timeout(Duration::from_millis(5000))
.build()
.expect("Failed to to make reqwest client"),
)
} else {
None
};
Expand Down

0 comments on commit 76106de

Please sign in to comment.