docs: Overhaul

This commit is contained in:
Snowiiii 2024-10-12 17:39:43 +02:00
parent 5d86ba5d63
commit d8220bf49b
18 changed files with 2484 additions and 243 deletions

View File

@ -39,9 +39,8 @@ And in release:
cargo run --no-default-features --release
```
### Project Structure
Before contributing, it would be helpful to get to know the project structure, for further information, visit [STRUCTURE.md](STRUCTURE.md)
### Docs
The Documentation of Pumpkin can be found at https://snowiiii.github.io/Pumpkin/
### Additional Information

View File

@ -9,7 +9,7 @@
</div>
Pumpkin is a Minecraft server built entirely in Rust, offering a fast, efficient,
[Pumpkin](https://snowiiii.github.io/Pumpkin/) 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)
@ -73,55 +73,22 @@ and customizable experience. It prioritizes performance and player enjoyment whi
Check out our [Github Project](https://github.com/users/Snowiiii/projects/12/views/3) to see current progress
## How to run
There are currently no release builds, because there was no release :D.
To get Pumpkin running you first have to clone it:
```shell
git clone https://github.com/Snowiiii/Pumpkin.git
cd Pumpkin
```
You also may have to [install rust](https://www.rust-lang.org/tools/install) when you don't already have.
You can place a vanilla world into the Pumpkin/ directory when you want. Just name the World to `world`
Then run:
> [!NOTE]
> This can take a while. Because we enabled heavy optimizations for release builds
>
> To apply further optimizations specfic to your CPU and use your CPU features. You should set the target-cpu=native
> Rust flag.
```shell
cargo run --release
```
### Docker
Experimental Docker support is available.
The image is currently not published anywhere, but you can use the following command to build it:
```shell
docker build . -t pumpkin
```
To run it use the following command:
```shell
docker run --rm -p 25565:25565 -v "./world:/pumpkin/world" pumpkin
```
See https://snowiiii.github.io/Pumpkin/about/quick-start.html
## Contributions
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md)
## Docs
The Documentation of Pumpkin can be found at https://snowiiii.github.io/Pumpkin/
## Communication
Consider joining our [discord](https://discord.gg/wT8XjrjKkf) to stay up-to-date on events, updates, and connect with other members.
## Funding
If you want to fund my and help the project, Check out my [GitHub sponsors](https://github.com/sponsors/Snowiiii)
## Thanks
A big thanks to [wiki.vg](https://wiki.vg/) for providing valuable information used in the development of this project.

View File

@ -1,17 +0,0 @@
# Project Structure
## Overview
Pumpkin is split into multiple crates, thus having a set project structure between contributors is essential.
## Pumpkin-Core
The core crate has some special rules that only apply to it:
- It may not depend on any other pumpkin crate
- There may not be any files directly under src/, except for the mod.rs file (this is to help with organisation)
## Other crate rules
- [`pumpkin-protocol`](/pumpkin-protocol/) - contains definitions for packet types **and** their serialization (be it through serde, or manually implementing `ClientPacket`/`ServerPacket`), only the `pumpkin` crate may depend on this
- `pumpkin-macros` - similarly to `pumpkin-core`, it may not depend on any other pumpkin crate

View File

@ -9,26 +9,36 @@ export default defineConfig({
base: "/Pumpkin/",
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
search: {
provider: "local",
},
sidebar: [
{
text: "About",
items: [
{ text: "Introduction", link: "/about/introduction" },
{ text: "Quick Start", link: "/about/quick-start" },
],
},
{
text: "Developers",
items: [
{
text: "Contributing",
link: "https://github.com/Snowiiii/Pumpkin/blob/master/CONTRIBUTING.md",
},
{ text: "Introduction", link: "/developer/introduction" },
{ text: "Networking", link: "/developer/networking" },
{ text: "Authentication", link: "/developer/authentication" },
],
},
{
text: "Plugins",
text: "Configuration",
items: [
{ text: "About Plugins", link: "/plugins/about" },
{
text: "Getting Started in Rust",
link: "/plugins/getting-started-rs",
},
{ text: "Introduction", link: "/config/introduction" },
{ text: "Basic", link: "/config/basic" },
{ text: "Advanced", link: "/config/advanced" },
],
},
],
@ -39,6 +49,22 @@ export default defineConfig({
],
logo: "/assets/icon.png",
footer: {
message: "Released under the MIT License.",
copyright: "Copyright © 2024-present Aleksandr Medvedev",
},
editLink: {
pattern: "https://github.com/Snowiiii/Pumpkin/blob/master/docs/:path",
text: "Edit this page on GitHub",
},
lastUpdated: {
text: "Updated at",
formatOptions: {
dateStyle: "medium",
timeStyle: "medium",
},
},
outline: "deep"
},
head: [["link", { rel: "icon", href: "/assets/favicon.ico" }]],
});

388
docs/config/advanced.md Normal file
View File

@ -0,0 +1,388 @@
### Advanced Configuration
### Proxy
`proxy`
Wether Proxy Configuration is enabled
```toml
enabled=false
```
#### Velocity
`proxy.velocity`
Wether [Velocity](https://papermc.io/software/velocity) Proxy is enabled
> [!IMPORTANT]
> Velocity support is currently WIP
```toml
enabled=false
```
##### Velocity Secret
This secret is used to ensure that player info forwarded by Velocity comes from your proxy and not from someone pretending to run Velocity
```toml
secret=
```
### Authentication
`authentication`
Wether Authentication is enabled
```toml
enabled=false
```
#### Prevent Proxy Connections
Prevent proxy connections
```toml
prevent_proxy_connections=false
```
#### Player Profile
`authentication.player_profile`
##### Allow Banned Players
Allow players flagged by Mojang (banned, forced name change)
```toml
allow_banned_players=false
```
##### Allowed Actions
Depends on the value above
```toml
allowed_actions=["FORCED_NAME_CHANGE", "USING_BANNED_SKIN"]
```
```toml
FORCED_NAME_CHANGE
USING_BANNED_SKIN
```
#### Textures
`authentication.textures`
Whether to filter/validate player textures (e.g. Skins/Capes)
```toml
enabled=true
```
##### Allowed URL Schemes
Allowed URL Schemes for Textures
```toml
allowed_url_schemes=["http", "https"]
```
##### Allowed URL Domains
Allowed URL domains for Textures
```toml
allowed_url_domains=[".minecraft.net", ".mojang.com"]
```
#### Texture Types
`authentication.textures.types`
##### Skin
Use player skins
```toml
skin=true
```
##### Cape
Use player capes
```toml
cape=true
```
##### Elytra
Use player elytras
(i didn't know myself that there are custom elytras)
```toml
elytra=true
```
### Compression
`packet_compression`
Wether Packet Compression is enabled
```toml
enable=true
```
#### Compression Info
##### Threshold
The compression threshold used when compression is enabled
```toml
threshold=256
```
##### Level
The Compression Level
> [!IMPORTANT]
> A value between 0..9
>
> 1 = Optimize for the best speed of encoding.
>
> 9 = Optimize for the size of data being encoded.
```toml
level=4
```
### Resource Pack
`resource_pack`
Wether a Resource Pack is enabled
```toml
enable=false
```
#### Resource Pack URL
The download URL of the resource pack
```toml
resource_pack_url=
```
#### Resource Pack SHA1
The SHA1 hash (40) of the resource pack
```toml
resource_pack_sha1=
```
#### Prompt Message
Custom prompt Text component, Leave blank for none
```toml
prompt_message=
```
#### Force
Will force the Player to accept the resource pack
```toml
force=false
```
### Commands
`commands`
#### Use Console
Are commands from the Console accepted
```toml
use_console=true
```
#### Log Console
Should be commands from players be logged in console
```toml
log_console=true
```
### RCON Config
`rcon`
Wether RCON is enabled
```toml
enable=false
```
#### Address
The network address and port where the RCON server will listen for connections
```toml
address=false
```
#### Password
The password required for RCON authentication
```toml
password=
```
#### Maximum Connections
The maximum number of concurrent RCON connections allowed
If 0 there is no limit
```toml
max_connections=0
```
#### RCON Logging
`rcon.logging`
##### Logged Successfully
Whether successful RCON logins should be logged
```toml
log_logged_successfully=true
```
##### Wrong Password
Whether failed RCON login attempts with incorrect passwords should be logged
```toml
log_wrong_password=true
```
##### Commands
Whether all RCON commands, regardless of success or failure, should be logged
```toml
log_commands=true
```
##### Disconnect
Whether RCON client quit should be logged
```toml
log_quit=true
```
### PVP
`pvp`
Whether PVP is enabled
```toml
enable=true
```
#### Hurt Animation
Do we want to have the Red hurt animation & fov bobbing
```toml
hurt_animation=true
```
#### Protect Creative
Should players in creative be protected against PVP
```toml
protect_creative=true
```
#### Knockback
Has PVP Knockback (Velocity)
```toml
knockback=true
```
#### Swing
Should player swing when attacking
```toml
swing=true
```
### Logging
`logging`
Whether Logging is enabled
```toml
enable=true
```
#### Level
At which level should be logged
```toml
level=Info
```
```toml
Off
Error
Warn
Info
Debug
Trace
```
#### Env
Enables the user to choose log level by setting `RUST_LOG=<level>` environment variable
```toml
env=false
```
#### Threads
Should threads be printed in the message
```toml
threads=true
```
#### Color
Should color be enabled for logging messages
```toml
color=true
```
#### Timestamp
Should the timestamp be printed in the message
```toml
timestamp=true
```

117
docs/config/basic.md Normal file
View File

@ -0,0 +1,117 @@
### Basic Configuration
Representing `configuration.toml`
### Server Address
The address to bind the server to
```toml
server_address=0.0.0.0
```
### Seed
The seed for world generation
```toml
seed=
```
### Max players
The maximum number of players allowed on the server
```toml
max_players=10000
```
### View distance
The maximum view distance for players
```toml
view_distance=10
```
### Simulation distance
The maximum simulation distance for players
```toml
simulation_distance=10
```
### Default difficulty
The default game difficulty
```toml
default_difficulty=Normal
```
```toml
Peaceful
Easy
Normal
Hard
```
### Allow nether
Whether the Nether dimension is enabled
```toml
allow_nether=true
```
### Hardcore
Whether the server is in hardcore mode.
```toml
hardcore=true
```
### Online Mode
Whether online mode is enabled. Requires valid Minecraft accounts
```toml
online_mode=true
```
### Encryption
Whether packet encryption is enabled
> [!IMPORTANT]
> Required when online mode is enabled
```toml
encryption=true
```
### Motd
The server's description displayed on the status screen.
```toml
motd=true
```
### Default gamemode
The default game mode for players
```toml
default_gamemode=Survival
```
```toml
Undefined
Survival
Creative
Adventure
Spectator
```

View File

@ -1,6 +1,12 @@
### Pumpkin Configuration
### Configuration
Pumpkin offers a robust configuration system that allows users to customize various aspects of the server's behavior without relying on external plugins. This provides flexibility and control over the server's operation.
### Basic / Advanced
Pumpkin's Configuration is split into a basic Configuration made for quick changes and important changes and a more Advanced Configuration
- `configuration.toml`: simple and can be compared to the vanilla `server.properties`.
- `features.toml`: designed to have all features of pumpkin at one place, making it a large configuration
#### Key Features:
- Extensive Customization: Configure server settings, player behavior, world generation, and more.
- Performance Optimization: Optimize server performance through configuration tweaks.

View File

@ -0,0 +1,29 @@
### Authentication
### Why Authentication
Minecraft is the most Popular game out there, And is is very easy to play it without paying for it. In Fact you don't pay for the Game, You pay for an Minecraft Account.
People who don't bough the Game but play online are using [Cracked Accounts](#cracked-accounts)
#### Cracked Accounts
- Don't cost any Money
- Everyone can set their own Nickname
- Have no UUID
- Have no Skin/Cape
- Not Secure
The Problem is that everyone can name themself how they want, Allowing to Join the Server as a Staff Member for example and having extended permissions,
Cracked accounts are also often used for Botting and [Denial of Service](https://de.wikipedia.org/wiki/Denial_of_Service) Attacks.
### Cracked Server
By default the `online_mode` is enabled in the configuration, This enables Authentication disallowing [Cracked Accounts](#cracked-accounts). When you are willing to allow Cracked Accounts, you can dissable `online_mode`
in the `configuration.toml`
### How Authentication works
To ensure a player has a premium accounts:
1. A client with a premium account sends a login request to the Mojang session server.
2. Mojang's servers verify the client's credentials and add the player to the their Servers
3. Now our server will send a Request to the Session servers and check if the Player has joined the Session Server .

View File

@ -0,0 +1,8 @@
### Introduction
Welcome to the Pumpkin Documentation!
Whether you're an internal Pumpkin developer or working on a Pumpkin plugin, this documentation is your resource for everything Pumpkin.
> [!IMPORTANT]
> While Pumpkin currently doesn't have plugin support, this documentation provides valuable insights into the platform's architecture and functionality, which can be helpful for understanding how to create potential future plugins.

View File

@ -0,0 +1,272 @@
### Networking
Most of the Networking code in Pumpkin, can be found at [Pumpkin-Protocol](https://github.com/Snowiiii/Pumpkin/tree/master/pumpkin-protocol)
Serverbound: Client->Server
Clientbound: Server->Client
### Structure
Packets in the Pumpkin protocol are organized by functionality and state.
`server`: Contains definitions for serverbound packets.
`client`: Contains definitions for clientbound packets.
### States
**Handshake**: Always the first packet being send from the Client. This begins also determins the next state, usally to indicate if the player thans perform a Status Request, Join the Server or wants to be transfered.
**Status**: Indicates the Client wants to see a Status response (MOTD).
**Login**: The Login sequence. Indicates the Client wants to join to the Server
**Config**: A sequence of Configuration packets beining mostly send from the Server to the Client. (Features, Resource Pack, Server Links...)
**Play**: The final state which indicate the Player is now ready to Join in also used to handle all other Gameplay packets.
### Minecraft Protocol
You can find all Minecraft Java packets at https://wiki.vg/Protocol. There you also can see in which [State](#States) they are.
You also can see all the information the Packets has which we can either Write or Read depending if its Serverbound or Clientbound
### Adding a Clientbound Packet
1. Adding a Packet is easy. First you have to dereive serde Serialize for packets.
```rust
#[derive(Serialize)]
```
2. Next you have set the packet id using the packet macro
```rust
#[packet(0x1D)]
```
3. Now you can create the Struct.
> [!IMPORTANT]
> Please start the Packet name with "C" for Clientbound.
> Also please add the State to the packet if its a Packet sended in multiple States, For example there are 3 Disconnect Packets.
>
> - CLoginDisconnect
> - CConfigDisconnect
> - CPlayDisconnect
Create fields within your packet structure to represent the data that will be sent to the client.
> [!IMPORTANT]
> Use descriptive field names and appropriate data types.
Example:
```rust
pub struct CPlayDisconnect {
reason: TextComponent,
more fields...
}
```
4. Also don't forgot to impl a new function for Clientbound Packets so we can actaully send then by putting in the values
Example:
```rust
impl CPlayDisconnect {
pub fn new(reason: TextComponent) -> Self {
Self { reason }
}
}
```
5. At the End everything should come together,
```rust
#[derive(Serialize)]
#[packet(0x1D)]
pub struct CPlayDisconnect {
reason: TextComponent,
}
impl CPlayDisconnect {
pub fn new(reason: TextComponent) -> Self {
Self { reason }
}
}
```
6. You can also Serialize the Packet manually, Which can be usefull if the Packet is more complex
```diff
-#[derive(Serialize)]
+ impl ClientPacket for CPlayDisconnect {
+ fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) {
+ bytebuf.put_slice(&self.reason.encode());
+ }
```
7. You can now send the Packet. See [Sending Packets](#sending-packets)
### Adding a Serverbound Packet
1. Adding a Packet is easy. First you have to dereive serde Deserialize for packets.
```rust
#[derive(Deserialize)]
```
2. Next you have set the packet id using the packet macro
```rust
#[packet(0x1A)]
```
3. Now you can create the Struct.
> [!IMPORTANT]
> Please start the Packet name with "S" for Serverbound.
> Also please add the State to the packet if its a Packet sended in multiple States.
Create fields within your packet structure to represent the data that will be sent to the client.
> [!IMPORTANT]
> Use descriptive field names and appropriate data types.
Example:
```rust
pub struct SPlayerPosition {
pub x: f64,
pub feet_y: f64,
pub z: f64,
pub ground: bool,
}
```
4. At the End everything should come together,
```rust
#[derive(Deserialize)]
#[packet(0x1A)]
pub struct SPlayerPosition {
pub x: f64,
pub feet_y: f64,
pub z: f64,
pub ground: bool,
}
```
5. You can also Deserialize the Packet manually, Which can be usefull if the Packet is more complex
```diff
-#[derive(Deserialize)]
+ impl ServerPacket for SPlayerPosition {
+ fn read(bytebuf: &mut ByteBuffer) -> Result<Self, DeserializerError> {
+ Ok(Self {
+ x: bytebuf.get_f64()?,
+ feet_y: bytebuf.get_f64()?,
+ z: bytebuf.get_f64()?,
+ ground: bytebuf.get_bool()?,
+ })
+ }
```
6. You can listen for the Packet. See [Receive Packets](#receiving-packets)
### Client
Pumpkin has stores Client and Players seperatly, Everything what is not reached the Play State is a Simple Client. Here are the Differences
**Client**
- Can only be in Status/Login/Transfer/Config State
- Is not a living entity
- Has small resource consumption
**Player**
- Can only be in Play State
- Is a living entity in a world
- Has more data, Consumes more resources
#### Sending Packets
Example:
```rust
// Works only in Status State
client.send_packet(&CStatusResponse::new("{ description: "A Description"}"));
```
#### Receiving Packets
For Clients:
`src/client/mod.rs`
```diff
// Put the Packet into the right State
fn handle_mystate_packet(
&self,
server: &Arc<Server>,
packet: &mut RawPacket,
) -> Result<(), DeserializerError> {
let bytebuf = &mut packet.bytebuf;
match packet.id.0 {
SHandShake::PACKET_ID => {
self.handle_handshake(server, SHandShake::read(bytebuf)?);
Ok(())
}
+ MyPacket::PACKET_ID => {
+ self.handle_mypacket(server, MyPacket::read(bytebuf)?);
+ Ok(())
+ }
_ => {
log::error!(
"Failed to handle packet id {} while in ... state",
packet.id.0
);
Ok(())
}
}
}
```
For Players:
`src/entity/player.rs`
```diff
// Players only have Play State
fn handle_play_packet(
&self,
server: &Arc<Server>,
packet: &mut RawPacket,
) -> Result<(), DeserializerError> {
let bytebuf = &mut packet.bytebuf;
match packet.id.0 {
SHandShake::PACKET_ID => {
self.handle_handshake(server, SHandShake::read(bytebuf)?);
Ok(())
}
+ MyPacket::PACKET_ID => {
+ self.handle_mypacket(server, MyPacket::read(bytebuf)?);
+ Ok(())
+ }
_ => {
log::error!(
"Failed to handle packet id {} while in ... state",
packet.id.0
);
Ok(())
}
}
}
```
### 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
Also change the `CURRENT_MC_PROTOCOL` in `src/lib.rs`

View File

@ -1,15 +0,0 @@
# Plugins
Pumpkin uses [Extism](https://extism.org/) for loading plugins.
This means that you can write your plugins in any language that can compile to Extism WASM.
These languages include:
- Rust
- JavaScript / TypeScript
- Golang
- C#
- F#
- C
- Haskell
- Zig
- AssemblyScript

View File

@ -1,4 +0,0 @@
# Getting Started in Rust
Rust in one of the supported plugin languages.
This page has not been written yet.

1765
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
"docs:preview": "vitepress preview docs"
},
"devDependencies": {
"vitepress": "^1.3.4",
"vue": "^3.4.38"
"vitepress": "^1.4.0",
"vue": "^3.5.12"
}
}

View File

@ -5,7 +5,7 @@ use serde_inline_default::serde_inline_default;
#[derive(Deserialize, Serialize)]
/// Packet compression
pub struct CompressionConfig {
/// Is compression enabled ?
/// Wether compression is enabled
#[serde_inline_default(true)]
pub enabled: bool,
#[serde(flatten)]

View File

@ -1,6 +1,10 @@
### Pumpkin Protocol
Contains all Serverbound(Client->Server) and Clientbound(Server->Client) Packets.
### Features
- [x] ZLib Compression
- [x] AES/CFB8 Encryiption
Packets in the Pumpkin protocol are organized by functionality and state.
`server`: Contains definitions for serverbound packets.

View File

@ -14,7 +14,7 @@ pub struct SPluginMessage {
impl ServerPacket for SPluginMessage {
fn read(bytebuf: &mut ByteBuffer) -> Result<Self, DeserializerError> {
Ok(Self {
channel: bytebuf.get_string().unwrap(),
channel: bytebuf.get_string()?,
data: bytebuf.get_slice().to_vec(),
})
}