Skip to content

Commit

Permalink
Add: Bungeecord support
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Oct 16, 2024
1 parent e725d19 commit 1583207
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 42 deletions.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# These are supported funding model platforms

github: [ Snowiiii ]
custom: ["https://www.paypal.me/alexxmedvedev"]
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ and customizable experience. It prioritizes performance and player enjoyment whi

## What Pumpkin will not

- Be a drop-in replacement for Vanilla or other servers
- Be compatible with plugins or mods for other servers
- Function as a framework for building a server from scratch.

Expand Down Expand Up @@ -68,6 +67,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi
- [x] Chat
- [x] Commands
- Proxy
- [x] Bungeecord
- [ ] Velocity

Check out our [Github Project](https://github.com/users/Snowiiii/projects/12/views/3) to see current progress
Expand All @@ -90,7 +90,7 @@ Consider joining our [discord](https://discord.gg/wT8XjrjKkf) to stay up-to-date

## Funding

If you want to fund me and help the project, Check out my [GitHub sponsors](https://github.com/sponsors/Snowiiii)
If you want to fund me and help the project, Check out my [GitHub sponsors](https://github.com/sponsors/Snowiiii) or my [PayPal](https://www.paypal.me/alexxmedvedev)

## Thanks

Expand Down
1 change: 0 additions & 1 deletion docs/about/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ and customizable experience. It prioritizes performance and player enjoyment whi

## What Pumpkin will not

- Be a drop-in replacement for vanilla or other servers
- Be compatible with plugins or mods for other servers
- Function as a framework for building a server from scratch.

Expand Down
7 changes: 7 additions & 0 deletions docs/config/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ This secret is used to ensure that player info forwarded by Velocity comes from
secret=
```

### Bungeecord
`proxy.bungeecord`

```toml
enabled=false
```

## Authentication

`authentication`
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ features:
details: Pumpkin is written 100% in Rust, ensuring memory safety and unmatched performance.
- title: Feature complete
details: With all vanilla features supported, you will have no issues.
- title: Extensible
details: Using Extism you can extend Pumpkin to your needs. Play your way!
- title: Flexibility
details: Highly configurable, with the ability to disable unnecessary features.
---
36 changes: 18 additions & 18 deletions package-lock.json

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

15 changes: 15 additions & 0 deletions pumpkin-config/src/proxy.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
use serde::{Deserialize, Serialize};
use serde_inline_default::serde_inline_default;

#[serde_inline_default]
#[derive(Deserialize, Serialize, Default)]
#[serde(default)]
pub struct ProxyConfig {
#[serde_inline_default(false)]
pub enabled: bool,
pub velocity: VelocityConfig,
pub bungeecord: BungeeCordConfig,
}

#[serde_inline_default]
#[derive(Deserialize, Serialize, Default)]
#[serde(default)]
pub struct BungeeCordConfig {
#[serde_inline_default(false)]
pub enabled: bool,
}

#[serde_inline_default]
#[derive(Deserialize, Serialize)]
#[serde(default)]
pub struct VelocityConfig {
#[serde_inline_default(false)]
pub enabled: bool,
#[serde_inline_default("".to_string())]
pub secret: String,
}

Expand Down
6 changes: 6 additions & 0 deletions pumpkin/src/client/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use pumpkin_core::ProfileAction;
use pumpkin_protocol::Property;
use reqwest::{StatusCode, Url};
use serde::Deserialize;
use sha1::Digest;
use sha2::Sha256;
use thiserror::Error;
use uuid::Uuid;

Expand Down Expand Up @@ -119,6 +121,10 @@ pub fn is_texture_url_valid(url: Url, config: &TextureConfig) -> Result<(), Text
Ok(())
}

pub fn offline_uuid(username: &str) -> Result<Uuid, uuid::Error> {
Uuid::from_slice(&Sha256::digest(username)[..16])
}

#[derive(Error, Debug)]
pub enum AuthError {
#[error("Missing auth client")]
Expand Down
52 changes: 33 additions & 19 deletions pumpkin/src/client/client_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use uuid::Uuid;
use crate::{
client::authentication::{self, validate_textures, GameProfile},
entity::player::{ChatMode, Hand},
proxy::velocity::velocity_login,
proxy::{bungeecord::bungeecord_login, velocity::velocity_login},
server::{Server, CURRENT_MC_VERSION},
};

Expand All @@ -36,6 +36,7 @@ impl Client {
let version = handshake.protocol_version.0;
self.protocol_version
.store(version, std::sync::atomic::Ordering::Relaxed);
*self.server_address.lock() = handshake.server_address;

self.connection_state.store(handshake.next_state);
if self.connection_state.load() != ConnectionState::Status {
Expand Down Expand Up @@ -79,23 +80,32 @@ impl Client {
// default game profile, when no online mode
// TODO: make offline uuid
let mut gameprofile = self.gameprofile.lock();
*gameprofile = Some(GameProfile {
id: login_start.uuid,
name: login_start.name,
properties: vec![],
profile_actions: None,
});
let proxy = &ADVANCED_CONFIG.proxy;
if proxy.enabled {
if proxy.velocity.enabled {
velocity_login(self)
velocity_login(self);
} else if proxy.bungeecord.enabled {
match bungeecord_login(self, login_start.name) {
Ok((_ip, profile)) => {
// self.address.lock() = ip;
self.finish_login(&profile);
*gameprofile = Some(profile);
}
Err(error) => self.kick(&error.to_string()),
}
}
return;
}
} else {
*gameprofile = Some(GameProfile {
id: login_start.uuid,
name: login_start.name,
properties: vec![],
profile_actions: None,
});

// TODO: check config for encryption
let verify_token: [u8; 4] = rand::random();
self.send_packet(&server.encryption_request(&verify_token, BASIC_CONFIG.online_mode));
// TODO: check config for encryption
let verify_token: [u8; 4] = rand::random();
self.send_packet(&server.encryption_request(&verify_token, BASIC_CONFIG.online_mode));
}
}

pub async fn handle_encryption_response(
Expand All @@ -122,19 +132,23 @@ impl Client {
}
}

if let Some(profile) = gameprofile.as_ref() {
self.finish_login(profile);
} else {
self.kick("No Game profile");
}
}

fn finish_login(&self, profile: &GameProfile) {
// 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");
}
let packet = CLoginSuccess::new(&profile.id, &profile.name, &profile.properties, false);
self.send_packet(&packet);
}

async fn autenticate(
Expand Down
3 changes: 3 additions & 0 deletions pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ pub struct Client {
pub brand: Mutex<Option<String>>,
/// The minecraft protocol version used by the client.
pub protocol_version: AtomicI32,
/// The Address used to connect to the Server, Send in the Handshake
pub server_address: Mutex<String>,
/// The current connection state of the client (e.g., Handshaking, Status, Play).
pub connection_state: AtomicCell<ConnectionState>,
/// Whether encryption is enabled for the connection.
Expand Down Expand Up @@ -132,6 +134,7 @@ impl Client {
gameprofile: Mutex::new(None),
config: Mutex::new(None),
brand: Mutex::new(None),
server_address: Mutex::new("".to_string()),
id,
address: Mutex::new(address),
connection_state: AtomicCell::new(ConnectionState::HandShake),
Expand Down
65 changes: 65 additions & 0 deletions pumpkin/src/proxy/bungeecord.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::net::IpAddr;

use pumpkin_protocol::Property;
use thiserror::Error;

use crate::{
client::authentication::{offline_uuid, GameProfile},
Client,
};

#[derive(Error, Debug)]
pub enum BungeeCordError {
#[error("Failed to parse Address")]
FailedParseAddress,
#[error("Failed to parse UUID")]
FailedParseUUID,
#[error("Failed to parse Properties")]
FailedParseProperties,
#[error("Failed to make offline UUID")]
FailedMakeOfflineUUID,
}

pub fn bungeecord_login(
client: &Client,
username: String,
) -> Result<(IpAddr, GameProfile), BungeeCordError> {
let server_address = client.server_address.lock();
let data = server_address.split('\0').take(4).collect::<Vec<_>>();

// Ip of player, only given if ip_forward on bungee is true
let ip = match data.get(1) {
Some(ip) => ip
.parse()
.map_err(|_| BungeeCordError::FailedParseAddress)?,
None => client.address.lock().ip(),
};

// Uuid of player, only given if ip_forward on bungee is true
let id = match data.get(2) {
Some(uuid) => uuid.parse().map_err(|_| BungeeCordError::FailedParseUUID)?,
None => {
offline_uuid(username.as_str()).map_err(|_| BungeeCordError::FailedMakeOfflineUUID)?
}
};

// Read properties and get textures
// Properties of player's game profile, only given if ip_forward and online_mode
// on bungee both are true
let properties: Vec<Property> = match data.get(3) {
Some(properties) => {
serde_json::from_str(properties).map_err(|_| BungeeCordError::FailedParseProperties)?
}
None => vec![],
};

Ok((
ip,
GameProfile {
id,
name: username,
properties,
profile_actions: None,
},
))
}
3 changes: 3 additions & 0 deletions pumpkin/src/proxy/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
pub mod bungeecord;
pub mod velocity;

// TODO: Maybe make a trait for proxies

0 comments on commit 1583207

Please sign in to comment.