Skip to content

Commit

Permalink
Merge branch 'master' into block_actions
Browse files Browse the repository at this point in the history
  • Loading branch information
OfficialKris committed Dec 27, 2024
2 parents fbe8a93 + 6a5add8 commit dbd821c
Show file tree
Hide file tree
Showing 49 changed files with 882 additions and 158 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

</div>

[Pumpkin](https://snowiiii.github.io/Pumpkin/) is a Minecraft server built entirely in Rust, offering a fast, efficient,
[Pumpkin](https://snowiiii.github.io/Pumpkin-Website/) is a Minecraft server built entirely in Rust, offering a fast, efficient,
and customizable experience. It prioritizes performance and player enjoyment while adhering to the core mechanics of the game.

![image](https://github.com/user-attachments/assets/7e2e865e-b150-4675-a2d5-b52f9900378e)
Expand Down Expand Up @@ -79,6 +79,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi
- [x] Particles
- [x] Chat
- [x] Commands
- [x] OP Permission
- Proxy
- [x] Bungeecord
- [x] Velocity
Expand All @@ -87,15 +88,15 @@ Check out our [Github Project](https://github.com/users/Snowiiii/projects/12/vie

## How to run

See our [Quick Start](https://snowiiii.github.io/Pumpkin/about/quick-start.html) Guide to get Pumpkin running
See our [Quick Start](https://snowiiii.github.io/Pumpkin-Website/about/quick-start.html) Guide to get Pumpkin running

## Contributions

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md)

## Docs

The Documentation of Pumpkin can be found at https://snowiiii.github.io/Pumpkin/
The Documentation of Pumpkin can be found at https://snowiiii.github.io/Pumpkin-Website/

## Communication

Expand Down
4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ services:
pumpkin:
build: .
ports:
- 25565:25565
- "25565:25565"
volumes:
- ./data:/pumpkin
stdin_open: true
tty: true
1 change: 1 addition & 0 deletions pumpkin-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ edition.workspace = true
pumpkin-core = { path = "../pumpkin-core" }
serde.workspace = true
log.workspace = true
uuid.workspace = true

toml = "0.8"
6 changes: 5 additions & 1 deletion pumpkin-config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use log::warn;
use logging::LoggingConfig;
use pumpkin_core::{Difficulty, GameMode};
use pumpkin_core::{Difficulty, GameMode, PermissionLvl};
use query::QueryConfig;
use serde::{de::DeserializeOwned, Deserialize, Serialize};

Expand Down Expand Up @@ -29,6 +29,7 @@ pub use server_links::ServerLinksConfig;
mod commands;
pub mod compression;
mod lan_broadcast;
pub mod op;
mod pvp;
mod rcon;
mod server_links;
Expand Down Expand Up @@ -79,6 +80,8 @@ pub struct BasicConfiguration {
pub simulation_distance: NonZeroU8,
/// The default game difficulty.
pub default_difficulty: Difficulty,
/// The op level assign by the /op command
pub op_permission_level: PermissionLvl,
/// Whether the Nether dimension is enabled.
pub allow_nether: bool,
/// Whether the server is in hardcore mode.
Expand Down Expand Up @@ -109,6 +112,7 @@ impl Default for BasicConfiguration {
view_distance: NonZeroU8::new(10).unwrap(),
simulation_distance: NonZeroU8::new(10).unwrap(),
default_difficulty: Difficulty::Normal,
op_permission_level: PermissionLvl::Four,
allow_nether: true,
hardcore: false,
online_mode: true,
Expand Down
27 changes: 27 additions & 0 deletions pumpkin-config/src/op.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use pumpkin_core::permission::PermissionLvl;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Serialize, Deserialize, Clone, Default)]
pub struct Op {
pub uuid: Uuid,
pub name: String,
pub level: PermissionLvl,
pub bypasses_player_limit: bool,
}

impl Op {
pub fn new(
uuid: Uuid,
name: String,
level: PermissionLvl,
bypasses_player_limit: bool,
) -> Self {
Self {
uuid,
name,
level,
bypasses_player_limit,
}
}
}
2 changes: 2 additions & 0 deletions pumpkin-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub mod gamemode;
pub mod math;
pub mod permission;
pub mod random;
pub mod text;

pub use gamemode::GameMode;
pub use permission::PermissionLvl;

use serde::{Deserialize, Serialize};

Expand Down
2 changes: 1 addition & 1 deletion pumpkin-core/src/math/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::math::vector2::Vector2;
use num_traits::Euclid;
use serde::{Deserialize, Serialize};

#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq, Eq)]
/// Aka Block Position
pub struct WorldPosition(pub Vector3<i32>);

Expand Down
56 changes: 56 additions & 0 deletions pumpkin-core/src/permission.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use num_derive::{FromPrimitive, ToPrimitive};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// Represents the player's permission level
///
/// Permission levels determine the player's access to commands and server operations.
/// Each numeric level corresponds to a specific role:
/// - `Zero`: `normal`: Player can use basic commands.
/// - `One`: `moderator`: Player can bypass spawn protection.
/// - `Two`: `gamemaster`: Player or executor can use more commands and player can use command blocks.
/// - `Three`: `admin`: Player or executor can use commands related to multiplayer management.
/// - `Four`: `owner`: Player or executor can use all of the commands, including commands related to server management.
#[derive(FromPrimitive, ToPrimitive, Clone, Copy, Default, PartialEq, Eq)]
#[repr(i8)]
pub enum PermissionLvl {
#[default]
Zero = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4,
}

impl PartialOrd for PermissionLvl {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
(*self as u8).partial_cmp(&(*other as u8))
}
}

impl Serialize for PermissionLvl {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
serializer.serialize_u8(*self as u8)
}
}

impl<'de> Deserialize<'de> for PermissionLvl {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = u8::deserialize(deserializer)?;
match value {
0 => Ok(PermissionLvl::Zero),
2 => Ok(PermissionLvl::Two),
3 => Ok(PermissionLvl::Three),
4 => Ok(PermissionLvl::Four),
_ => Err(serde::de::Error::custom(format!(
"Invalid value for OpLevel: {}",
value
))),
}
}
}
2 changes: 2 additions & 0 deletions pumpkin-core/src/text/click.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use serde::{Deserialize, Serialize};
pub enum ClickEvent<'a> {
/// Opens a URL
OpenUrl(Cow<'a, str>),
/// Opens a File
OpenFile(Cow<'a, str>),
/// Works in signs, but only on the root text component
RunCommand(Cow<'a, str>),
/// Replaces the contents of the chat box with the text, not necessarily a
Expand Down
2 changes: 1 addition & 1 deletion pumpkin-entity/src/entity_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// TODO
// TODO make this dynamic
#[derive(Clone)]
#[repr(i32)]
pub enum EntityType {
Expand Down
7 changes: 7 additions & 0 deletions pumpkin-inventory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ pub trait Container: Sync + Send {

fn all_slots_ref(&self) -> Vec<Option<&ItemStack>>;

fn clear_all_slots(&mut self) {
let all_slots = self.all_slots();
for stack in all_slots {
*stack = None;
}
}

fn all_combinable_slots(&self) -> Vec<Option<&ItemStack>> {
self.all_slots_ref()
}
Expand Down
22 changes: 22 additions & 0 deletions pumpkin-inventory/src/open_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use pumpkin_world::block::block_registry::Block;
use pumpkin_world::item::ItemStack;
use std::sync::Arc;
use tokio::sync::Mutex;

pub struct OpenContainer {
// TODO: unique id should be here
// TODO: should this be uuid?
players: Vec<i32>,
container: Arc<Mutex<Box<dyn Container>>>,
location: Option<WorldPosition>,
Expand Down Expand Up @@ -54,6 +56,22 @@ impl OpenContainer {
}
}

pub fn is_location(&self, try_position: WorldPosition) -> bool {
if let Some(location) = self.location {
location == try_position
} else {
false
}
}

pub async fn clear_all_slots(&self) {
self.container.lock().await.clear_all_slots();
}

pub fn clear_all_players(&mut self) {
self.players = vec![];
}

pub fn all_player_ids(&self) -> Vec<i32> {
self.players.clone()
}
Expand All @@ -62,6 +80,10 @@ impl OpenContainer {
self.location
}

pub async fn set_location(&mut self, location: Option<WorldPosition>) {
self.location = location;
}

pub fn get_block(&self) -> Option<Block> {
self.block.clone()
}
Expand Down
12 changes: 6 additions & 6 deletions pumpkin-nbt/src/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl<'de, T: Buf> Deserializer<'de, T> {
}
}

/// Deserializes struct using Serde Deserializer from unnamed (network) NBT
/// Deserializes struct using Serde Deserializer from normal NBT
pub fn from_bytes<'a, T>(s: &'a mut impl Buf) -> Result<T>
where
T: Deserialize<'a>,
Expand All @@ -32,20 +32,20 @@ where
T::deserialize(&mut deserializer)
}

pub fn from_cursor<'a, T>(cursor: &'a mut Cursor<&[u8]>) -> Result<T>
/// Deserializes struct using Serde Deserializer from normal NBT
pub fn from_bytes_unnamed<'a, T>(s: &'a mut impl Buf) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::new(cursor, true);
let mut deserializer = Deserializer::new(s, false);
T::deserialize(&mut deserializer)
}

/// Deserializes struct using Serde Deserializer from normal NBT
pub fn from_bytes_unnamed<'a, T>(s: &'a mut impl Buf) -> Result<T>
pub fn from_cursor<'a, T>(cursor: &'a mut Cursor<&[u8]>) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::new(s, false);
let mut deserializer = Deserializer::new(cursor, true);
T::deserialize(&mut deserializer)
}

Expand Down
59 changes: 59 additions & 0 deletions pumpkin-nbt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,62 @@ macro_rules! impl_array {
impl_array!(IntArray, "int");
impl_array!(LongArray, "long");
impl_array!(BytesArray, "byte");

#[cfg(test)]
mod test {
use serde::{Deserialize, Serialize};

use crate::BytesArray;
use crate::IntArray;
use crate::LongArray;
use crate::{deserializer::from_bytes_unnamed, serializer::to_bytes_unnamed};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Test {
byte: i8,
short: i16,
int: i32,
long: i64,
float: f32,
string: String,
}

#[test]
fn test_simple_ser_de_unamed() {
let test = Test {
byte: 123,
short: 1342,
int: 4313,
long: 34,
float: 1.00,
string: "Hello test".to_string(),
};
let mut bytes = to_bytes_unnamed(&test).unwrap();
let recreated_struct: Test = from_bytes_unnamed(&mut bytes).unwrap();

assert_eq!(test, recreated_struct);
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TestArray {
#[serde(with = "BytesArray")]
byte_array: Vec<u8>,
#[serde(with = "IntArray")]
int_array: Vec<i32>,
#[serde(with = "LongArray")]
long_array: Vec<i64>,
}

#[test]
fn test_simple_ser_de_array() {
let test = TestArray {
byte_array: vec![0, 3, 2],
int_array: vec![13, 1321, 2],
long_array: vec![1, 0, 200301, 1],
};
let mut bytes = to_bytes_unnamed(&test).unwrap();
let recreated_struct: TestArray = from_bytes_unnamed(&mut bytes).unwrap();

assert_eq!(test, recreated_struct);
}
}
2 changes: 1 addition & 1 deletion pumpkin-protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ aes = "0.8.4"
cfb8 = "0.8.1"

# decryption
libdeflater = "1.22.0"
libdeflater = "1.23.0"
2 changes: 2 additions & 0 deletions pumpkin-world/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ dashmap = "6.1.0"
flate2 = "1.0"
lz4 = "1.28.0"

file-guard = "0.2.0"

enum_dispatch = "0.3.13"

fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
Expand Down
Loading

0 comments on commit dbd821c

Please sign in to comment.