Commit Graph

2738 Commits

Author SHA1 Message Date
Alexander Medvedev
9eab7581fd feat: Implement Profile data component 2026-07-10 18:16:30 +02:00
Laptop59
b4e3670a86 feat(command): team color and hex color argument types (#2357)
* feat: implement the argument types for color

* fix: clippy warnings & format code
2026-07-10 16:00:32 +02:00
Missing_Love
3d03819411 feat(config): add broadcast-console-to-ops server property (#2285)
Add the `broadcast_console_to_ops` configuration option matching
vanilla's `broadcast-console-to-ops` server property. When set to
`false`, suppresses console and RCON command output from being
broadcast to online operators.

- Add `broadcast_console_to_ops` field to `CommandsConfig` (defaults
  to `true` for vanilla compatibility)
- Track the setting via an `AtomicBool` in the command module
- Replace hardcoded `true` in `should_broadcast_console_to_ops` for
  Console and RCON senders with the configurable value
- Initialize the setting during server startup from advanced config

Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
2026-07-10 13:29:05 +02:00
yhypno
7829f0bca0 fix: preserve stacked buckets when collecting fluids (#2371) 2026-07-10 11:15:46 +02:00
Alexander Medvedev
7ccb0c237f fix: https://github.com/Pumpkin-MC/Pumpkin/issues/2219 2026-07-09 22:02:15 +02:00
nobuildersnotools
8cf50cb393 perf(entity): swap std hashmap for fxhashmap in pathfind (#2360) 2026-07-09 21:13:26 +02:00
TheDarkSword
a4af4269fb fix: sky light propagation hanging on unloaded chunks (#2334)
* fix(lighting): stop sky light updates from looping on unloaded chunks

The sky light propagation could spin forever when a light update happened
next to a chunk that wasn't loaded. Writes to an unloaded chunk are dropped
silently and reads come back as 0, so the "this neighbor is darker than us"
check stayed true on every pass and the same position kept getting queued
again. In practice this hangs a tick thread when a block is broken near the
edge of the loaded area.

Skip neighbors whose chunk isn't loaded in both the increase and decrease
passes, matching how the border of loaded chunks already behaves: light
doesn't bleed into chunks that aren't there yet.

* Use Level::is_chunk_loaded for the unloaded-chunk guard
2026-07-09 20:59:38 +02:00
Alexander Medvedev
1af05a4530 ci: only sign on master 2026-07-09 20:46:22 +02:00
Alexander Medvedev
47fe060665 fix: rust 1.97 lints 2026-07-09 20:39:01 +02:00
Laptop59
b241bbf0bd fix: make SNBT operation bool() return true for all non-zero values (#2358) 2026-07-09 16:00:34 +02:00
Alexander Medvedev
1196d9226f ci; add Windows signing 2026-07-08 18:29:44 +02:00
Alexander Medvedev
339d9dde5b feat: add bedrock biome mappings 2026-07-08 17:30:55 +02:00
TheDarkSword
c82bf52aec perf(pumpkin): tick block entities per active chunk instead of scanning all (#2340)
Block entities lived in one flat DashMap keyed by BlockPos, and every world
tick rebuilt the tick list by iterating the entire map and filtering it down
to the active chunks. That is O(all loaded block entities): the more of the
world that has been explored (chests, signs, hoppers... all count), the
longer every tick spends walking block entities it is not going to tick, so
TPS slowly bleeds away on long-running worlds.

Key the map by chunk instead (chunk -> its block entities). Ticking now walks
only the handful of active chunks and their entries, inserts/removals/lookups
compute the chunk key up front, and unloading a chunk drops its whole bucket.
Behaviour is unchanged - the same block entities get ticked - it just stops
scanning the ones that are loaded but nowhere near a player.
2026-07-07 16:00:27 +02:00
TheDarkSword
984e0098e2 perf(pumpkin): only tick entities in active chunks (#2341)
The world tick iterated every entity in the world and ticked all of them,
regardless of where they were - so entities sitting in loaded-but-not-active
chunks kept running their AI, movement and player-collision checks every tick.
That is O(all loaded entities) and grows as a world is explored, bleeding TPS
on long-running servers.

Skip entities whose chunk isn't in the active (ticking) set - the same set
block-entity ticking and mob spawning already use, and matching vanilla, which
only ticks entities within the simulation distance. The check uses the live
position rather than the cached chunk_pos, since fast movers (minecarts,
projectiles) update pos directly and leave chunk_pos stale.

Players are ticked separately and aren't in this list, so they're unaffected.
2026-07-07 15:59:41 +02:00
BitForge
adbc8e2b6a fix: prevent capacity overflow crash (#2348)
* fix: prevent capacity overflow crash when flying with elytra or in creative mode

The NoiseBasedCountPlacementModifier::get_count() can return negative i32
values when foliage noise sampling produces negative results at certain
world coordinates. The previous code cast this negative i32 directly to
usize, causing an integer wrap to ~18 quintillion, which triggered a
capacity overflow panic in Vec allocation during chunk feature generation.

This aligns with vanilla Minecraft behavior which also clamps the count
to a minimum of 0 before using it.

Closes #2345

* Hi
2026-07-07 15:53:11 +02:00
Red
0de72cbf18 feat(plugin-api): Forced use of setters (#2333) 2026-07-07 15:26:30 +02:00
ZlordHUN
cc2b537371 fix: set client player before spawn to prevent invisible chunks on first join (#2307)
* Fix First Join Invisible Chunk

* downgrade warn! to debug! in send_chunks drop path
2026-07-07 14:20:18 +02:00
Alexander Medvedev
44fd621294 fix: bedrock block mappings 2026-07-06 21:49:42 +02:00
yunuservices
5d27ab34d3 feat(plugin-api) Add ServerLoadEvent (#2302)
* feat: add ServerLoadEvent

* fix: address ServerLoadEvent review feedback
2026-07-06 20:01:54 +02:00
dependabot[bot]
8c1064908b build(deps): bump crate-ci/typos from 1.47.2 to 1.48.0 (#2349)
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.47.2 to 1.48.0.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/v1.47.2...v1.48.0)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 09:02:38 +02:00
Alexander Medvedev
4ec2315aef chore: implement all missing raknet packets 2026-07-05 20:26:32 +02:00
kedor
560a0ed77d feat(config): add Configuration for advancement saving (#2259)
* implementing the advancement configuration for saving or not the advancements

* adding a test for not loading files when save is disabled

* cargo fmt

* fix merge

* Fix variable name for players directory
2026-07-05 16:36:36 +02:00
ChocoDev
da2401d07d feat: aquifer sample and top material in cave carver (#2242)
* sin/cos util

* 4 nieghbor check

* formating

* air helper

* carver wrapper

* fmt

* clippy

* clipp2

* remove local y

* out of bound guard

* fluid tick

* surface rule

* wire up

* math correct

* start fix

* bring back xoroshiro oops

* scheduler guard

* simplify test

* clean test

* comment

* crash fix

* clippy

* clippy

* i hate you codex

* sin cos

* im stupid f32
2026-07-05 15:55:43 +02:00
Alexander Medvedev
3aea5ee720 fix: ci 2026-07-04 15:14:55 +02:00
Alexander Medvedev
c60fa90ed8 feat(bedrock): Add Protocol encryption 2026-07-04 15:01:42 +02:00
Aalivexy
52838d945b fix: trigger PlayerChangeWorldEvent on cross-dimension respawn (#2228) (#2250)
Rebased onto current master after #2296 (PlayerRespawnEvent).

- Fire PlayerChangeWorldEvent (cancellable) before the cross-dimension
  transfer in World::respawn_player; a plugin may redirect new_world,
  override position/yaw/pitch, or cancel to keep the player in the
  current world.
- Use the safe transfer ordering (remove_player -> unload_watched_chunks
  -> change_world -> set_world -> publish) so no observer sees the player
  in a world whose chunk manager doesn't match, and update the entity's
  world reference (set_world) to fix the latent stale-world bug.
- When cancelled or the target world can't be resolved, fall back to the
  current world's spawn.
- The non-cancellable PlayerRespawnEvent (#2296) now fires after this
  event and observes the resolved world automatically; document the
  ordering and mutation-vs-cancellation semantics on both events.
2026-07-04 12:21:46 +02:00
Red
28d6450426 fix: Made (CUSTOM_)NAME_VISIBLE work across versions (#2332) 2026-07-04 12:14:29 +02:00
Niclas
0800ed8878 feat(plugin-api): add namespaced custom item data (#2324)
* feat(plugin-api): add namespaced custom item data

* modified: pumpkin-plugin-wit

* feat(plugin-api): add NBT custom item data

* fix(plugin-api): satisfy clippy for NBT tree conversion

* feat(plugin-api): add NBT custom item data

* test(plugin-api): use neutral custom data fixtures

---------

Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
2026-07-04 09:50:06 +02:00
Alexander Medvedev
5d117b3213 fix: ci in release 2026-07-03 19:26:17 +02:00
Alexander Medvedev
a9f69fea01 chore: enforce clippy lints in pumpkin-world 2026-07-03 18:51:47 +02:00
Niclas
920fc3ec50 fix: preserve infinite status effect durations (#2292) 2026-07-01 18:27:23 +02:00
PigTurtle
7bfc6a6737 refactor(data) BlockId and BlockStateId wrapper types (#2328)
* refactor: less manual BlockMetadata impls

* refactor: added BlockId type

BlockId is a wrapper for u16: it is valid for any u16 that is the id of a Block.
- Changed the Block.id field type to BlockId
- added named BlockId constants
- BlockMetadata::ids() now returns Box<[BlockId]>
- adjusted pumpkin-macros to use BlockId constants
- fixed some methods that were comparing blockstate ids or item ids (u16) against block ids (previously u16)

TODO: check if unsafe blocks can be removed; The compiler might understand that BlockId is always a valid index into mappings::TYPE_FROM_RAW_ID

* refactor: added BlockStateId type

A BlockStateId is a safe wrapper around the numerical index of a BlockState in pumpkin-data. They help avoiding validity checks (outside of IO and, currently, plugins), and make it easier for other contributors to reason about what they're comparing; BlockStateIds, BlockIds or Item ids (still u16).
pumpkin-data::BlockStateId replaces RawBlockState and BlockStateId from pumpkin-world.

- added the BlockStateId wrapper type
- made (almost; plugins) every function interacting with block states or block state ids use the wrapper type
- changed codegen logic to create/work with BlockStateIds
- made ChunkPalette parsing check BlockStateId validity (pumpkin-world::chunk::format::ChunkSectionBlockStates)

TODO: check if unsafe blocks can be removed; The compiler might understand that BlockStateId is always a valid index into mappings::BLOCK_ID_FROM_STATE_ID and mappings::STATE_FROM_STATE_ID

* refactor: imports
changed every use pumpkin_world::BlockStateId to pumpkin_data::BlockStateId

* refactor: Block- & BlockStateId

finishing touches;
- rebased on latest mater
- ensure there are no bound checks on Block(State)Id conversions, making them extremely cheap
  - this required unsafe std::hint::assert_unchecked annotations because the compiler is (occasionally) stupid
  - on debug builds the bound checks still exist because of ub_checks (see rust unstable book for the feature of the same name)
- added Safety notes to hopefully prevent anyone from enabling the creation of invalid Block(State)Ids in the future

- fixed a benchmark
2026-07-01 18:05:05 +02:00
dongzh1
ae1813735b fix(inventory): guard Swap slot click against negative slot index (#2313)
The `Swap` branch of `internal_on_slot_click` indexed
`self.get_behaviour().slots[slot_index as usize]` without first checking
`slot_index >= 0`, unlike every sibling branch (Pickup, QuickMove, Throw,
Clone, QuickCraft) which all guard with `if slot_index < 0 { return; }`.

`slot_index` originates from the client `SClickSlot` packet (`i16` slot
field, widened to `i32`). The upstream validation in `Player::on_slot_click`
relies on `ScreenHandler::is_slot_valid`, whose check
`slot == -1 || slot == -999 || slot < slots.len() as i32` returns `true`
for ANY negative slot (a negative value is always `< slots.len()`), so
negative indices are not filtered out before reaching the handler. A
crafted Swap packet with a negative slot (e.g. -5) and a hotbar button in
`0..9` (or 40) therefore evaluated `slots[(-5) as usize]`, an enormous
index, causing an out-of-bounds Vec panic and crashing the server.

Add the same `if slot_index < 0 { return; }` guard at the top of the Swap
branch, matching the sibling branches exactly. Minimal, low-risk: legitimate
Swap clicks always carry a non-negative container slot, so behaviour is
unchanged for valid input.
2026-07-01 13:43:54 +02:00
kedor
d8b7ae30a5 feat: add Seen advancement packet (#2326) 2026-07-01 13:21:45 +02:00
ZlordHUN
395c4aa36b feat(generation): implement ancient city jigsaw structures (#2329) 2026-07-01 09:11:47 +02:00
Mateus
e47061b44b fix: C_GLAZED_TERRACOTTAS ids (#2331)
Changed ids() in glazed_terracotta.rs from tag::Item to tag::Block
2026-07-01 09:07:49 +02:00
dongzh1
af712b714e fix(pumpkin-world): correct inverted liquid_block_count (#2316)
BlockPalette::liquid_block_count() returned the inverse of what it
should: the Homogeneous arm returned 0 when the section was liquid and
the full VOLUME (4096) when it was not, and the Heterogeneous arm summed
the counts of non-liquid blocks (filtering on !is_liquid).

Flip both arms to actually count liquid blocks, mirroring the correct
sibling non_air_block_count(): Homogeneous yields VOLUME when the single
block is liquid (0 otherwise) and Heterogeneous filters on is_liquid.

This value is sent to clients as the fluid count in chunk data
(MC 26.1+), so the inversion reported wrong fluid counts to players.
2026-06-30 19:23:17 +02:00
AnthonyDuong1
85c4ce0483 fix: creative fire ticks (#2308) 2026-06-30 19:20:24 +02:00
AnthonyDuong1
fbfc706f7b fix: air supply under water (#2317) 2026-06-30 19:18:01 +02:00
kedor
22c871ed9b fix(protocol): recipe book packet (#2318)
* fix recipe display to use itemStackTemplate parsing

* fix advancement packet
2026-06-30 19:13:16 +02:00
ZlordHUN
5eb7cc0e81 feat: Add Overworld Fossil Generation (#2319) 2026-06-30 19:08:44 +02:00
Alexander Medvedev
7ff990c468 fix: bedrock crafting 2026-06-29 21:20:40 +02:00
Alexander Medvedev
efa97ad174 fix: https://github.com/Pumpkin-MC/Pumpkin/issues/2283 2026-06-28 16:18:49 +02:00
Alexander Medvedev
8c5d6dc405 fix: bedrock SActorEvent packet 2026-06-28 13:26:32 +02:00
Niclas
28e8187f23 fix(plugin-api): expose data components to Rust plugins (#2306) 2026-06-28 09:35:52 +02:00
Alexander Medvedev
2f653f6336 feat: bedrock crafting 2026-06-27 22:16:21 +02:00
kedor
0eb7cb1a79 fix(advancement): Fix advancement tree and visibility (#2304)
* fix visibility evaluator

* fix a small issue with the placement of advancement
2026-06-27 20:42:35 +02:00
Alexander Medvedev
25048f5a6c fix: 2 bedrock packets 2026-06-27 17:44:55 +02:00
Alexander Medvedev
1dbfb75ecc fix: end spawning 2026-06-27 14:57:40 +02:00
Alexander Medvedev
03a90a40b1 chore: expand loot table 2026-06-27 10:35:46 +02:00