Compare commits

...

28 Commits

Author SHA1 Message Date
Helvetica Volubi fc3415e667 [ci skip] update information of QQ and DC 2026-07-22 00:55:27 +08:00
Helvetica Volubi 57dce9cc99 [ci skip] fix docs 2026-07-20 03:15:18 +08:00
Helvetica Volubi f4aea025c1 [ci skip] some info update 2026-07-12 21:35:51 +08:00
Helvetica Volubi 847fec5cb0 [ci skip] fix ci for update 2026-07-12 16:22:59 +08:00
Helvetica Volubi 576d2322ee [ci skip] ci updates 2026-07-11 01:21:56 +08:00
Helvetica Volubi 917b2cf3d9 fix: some fix for bot action
fix stop command could stop all the same type of action when a stop action called

fix some typo in command reply
2026-07-11 01:03:57 +08:00
Helvetica Volubi 6309c478be [ci skip] because of tmp move to new org, rebrand 2026-07-10 00:06:51 +08:00
Helvetica Volubi 012ea4f5b5 fix bot & replay api 2026-07-07 00:52:11 +08:00
Helvetica Volubi 377c81f26f fix bot command register 2026-07-06 20:24:48 +08:00
Helvetica Volubi 91e00f34ff Update Luminol to fix some bugs 2026-07-06 01:25:07 +08:00
Helvetica Volubi ac51af2fbc Update Luminol
Replace MenthaMC Maven repo with Bacteriawa

Update Maven repository URL from https://repo.menthamc.org/... to https://repo.bacteriawa.com/... across project files. Changes include README.md and README_EN.md (repository id changed to "repository" and URL updated), build.gradle.kts (rename menthaMavenPublicUrl to bacteriawaMavenPublicUrl and switch repository used for dependencies and publishing, update publishing repo name), luminol-server/build.gradle.kts.patch (use bacteriawaMavenPublicUrl), and settings.gradle.kts (add new Maven URL). This centralizes the project to use the Bacteriawa Maven host for dependency resolution and publishing.

Origin Commit: https://github.com/LuminolMC/Luminol/commit/ba28403ff6d15da3cf8b1af9828bbd1f997a7b9e

Co-authored-by: Bacteriawa <a3167717663@hotmail.com>
2026-07-05 22:07:45 +08:00
Helvetica Volubi 6df2e43b80 Update Luminol 2026-07-03 06:03:06 +08:00
Helvetica Volubi a62cc74f09 [ci skip]push repo 2026-07-02 20:01:53 +08:00
Helvetica Volubi f703bda607 Merge 26.1.2 changes to 26.2 branch 2026-07-02 19:40:42 +08:00
Helvetica Volubi 8a7b605fa6 feat: old leader zombie health logic
close https://github.com/LuminolMC/Lophine/issues/157
2026-07-02 19:40:42 +08:00
xiaoxijun 9f2f53001a #154 (#155)
* Add PCA sync protocol support

Introduce PCA sync protocol and integrate it into Carpet/Leaves.

- Added org/leavesmc/leaves/protocol/PcaSyncProtocol.java: full implementation of the PCA sync protocol (handlers for sync requests, watcher maps, update payloads, player/block watch management, scheduling, and config-driven behavior).
- Added fun/bm/lophine/config/modules/function/protocol/PcaSyncProtocolConfig.java and enum PcaPlayerEntityType.java to drive enabling and player-entity sync policy.
- Integrated protocol into Carpet: register new carpet rules (pcaSyncProtocol, pcaSyncPlayerEntity) in CarpetCompatSync and added batching to avoid excessive updates when rules change.
- Enhanced CarpetServerProtocol to track active players, batch rule updates, and send server rule data safely on the server thread.
- Added a Minecraft patch (0046-PCA-sync-protocol.patch) to trigger syncs from setChanged() in containers, chest boats, minecarts and BlockEntity updates so watched clients receive entity/block-entity updates.

This enables PCA clients to watch and receive synchronized block-entity and entity state on demand, while keeping updates gated by config and player permissions and improving rule-update performance via batching.

* Add Vanilla-like experience config and updates

Introduce a new VanillaLikeExperienceConfig module and a patch (0047) that gates multiple Paper/Luminol behavior changes behind this toggle to restore more vanilla-like technical behavior when enabled. The patch injects conditional checks across many server classes (entity merging, phantoms, pistons, hoppers, TNT handling, explosions, portal/piston protections, item merging, teleportation, spawn counting, etc.). Also adjust PCA sync protocol references in the existing 0046 patch to use the updated fun.bm.lophine package path. Includes the new fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.java file.

* Restore vanilla ender pearl loading on Folia

Add patch (features/0048) that restores vanilla ender-pearl loading behavior on Folia. Reintroduces ender-pearl tracking and persistence: ServerPlayer now uses a thread-safe enderPearls set and saves pearl tags, ThrownEnderpearl maintains a lastSavedEnderPearlTag (updated on construction, owner changes, spawn and restore) and updates/clears it on tick/removal, and EnderpearlItem updates the saved tag when spawning a pearl. PlayerList and BotList now schedule pearl removal via the Bukkit taskScheduler when players/bots quit. The changes preserve Paper's legacyEnderPearlBehavior checks where applicable and add logging and safer tag handling to avoid saving invalid snapshots.

* Restore vanilla ender pearl loading

Restore vanilla ender-pearl loading behavior on Folia by preserving the last saved NBT for thrown pearls. ThrownEnderpearl.java: add a volatile CompoundTag lastSavedEnderPearlTag, provide a defensive-copying getter getLastSavedEnderPearlTag(), adjust @Nullable annotation placement, and update logger/comment. Minor index/format updates in ServerPlayer.java, PlayerList.java and EnderpearlItem.java.

* remove extra import

* Add Precise mob cap and adjust ender pearl patch

Introduce a Precise mob cap feature and integrate it into Paper/Folia world/region lifecycle. Adds new patch features/0049-Precise-mob-cap.patch which modifies RegionizedWorldData, ServerChunkCache and ServerLevel to support an incremental, event-driven mob counting system that can supersede the existing GlobalEntitiesCounter. Adds PreciseMobCapConfig (toggle and behavior flags) and PreciseMobCapCounter (unique id management, area map registration, per-level global counters, spawnable-chunk tracking, spawn state creation, and cleanup on unload). Also updates the existing 0048 ender-pearl loading patch file (minor import/index adjustments). The Precise mob cap counts only relevant mobs (configurable to match vanilla or Paper-optimized behavior), hooks into entity tracking start/end, and requires per-player-mob-spawns=false to be set in Paper world defaults when enabled.

* remove extra import

* pre merge config

* transform config

* merge config

* rebuild patches

* fix a bug in new counter

* simplify code

---------

Co-authored-by: Helvetica Volubi <suisuroru@blue-millennium.fun>
Co-authored-by: Helvetica Volubi <88063803+Suisuroru@users.noreply.github.com>
2026-07-02 19:40:42 +08:00
Helvetica Volubi f98781b7cc [ci skip]allow to push repo
we will trigger ci later
2026-07-02 17:55:45 +08:00
Helvetica Volubi 3251e0d8e0 Update Luminol 2026-07-01 23:27:02 +08:00
Helvetica Volubi 03dddb546d try update to 26.2 2026-06-29 21:38:11 +08:00
Helvetica Volubi 37c22202ab [ci skip] oops 2026-06-28 04:18:47 +08:00
Helvetica Volubi 2e67f978ec Update Luminol 2026-06-28 03:16:11 +08:00
Helvetica Volubi ed2f464914 fixup build 2026-06-25 18:12:18 +08:00
Helvetica Volubi 1cd09226f6 fixes #152 2026-06-25 17:49:55 +08:00
Helvetica Volubi 8cd8f4fbad Update Luminol 2026-06-25 17:48:52 +08:00
Bacteriawa e90c758a01 Lophine: add configs and update-suppression guards
Add Lophine-specific configuration support (global and carpet configs) and a temporary config transform step during init. Introduce config-controlled command registrations (function, scoreboard, trigger, tick) and enable tick-rate/command tweaks and an entity raytracing tracker flag. Fix datapack command save/listing behavior. Integrate Leaves update-suppression handling broadly: catch and convert update-suppression exceptions across packet handling, ticking, neighbor updates, block state updates and more; add configurable shulker CCE behavior and redstone upward-update compatibility. Provide an option to reintroduce an InstantNeighborUpdater (instant block updater) and other small compatibility/rebrand adjustments.
2026-06-23 01:35:57 +08:00
Helvetica Volubi e508462093 Update Luminol 2026-06-23 00:37:42 +08:00
dependabot[bot] b9c68a9b84 [ci skip]Bump actions/checkout from 6 to 7 (#153)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 16:36:49 +08:00
Helvetica Volubi 74d0b5ca5f Update Luminol & remove a unused config 2026-06-19 23:28:39 +08:00
107 changed files with 3004 additions and 1722 deletions
+1 -1
View File
@@ -11,4 +11,4 @@ issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
custom: https://afdian.com/a/Luminol
custom: [https://afdian.com/a/bm0721, https://afdian.com/a/Luminol] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+4 -4
View File
@@ -32,7 +32,7 @@ jobs:
BUILD_NUMBER: ${{ github.run_number }}
steps:
- name: Checkout Git Repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Set Up JDK
uses: actions/setup-java@v5
@@ -47,7 +47,7 @@ jobs:
run: chmod +x gradlew
- name: Configure Git User Details
run: git config --global user.email "ci@luminolmc.com" && git config --global user.name "LuminolMC CI"
run: git config --global user.email "ci@lophinecraft.com" && git config --global user.name "LophineCraftCI"
- name: Apply All Patches
run: ./gradlew --refresh-dependencies applyAllPatches
@@ -124,7 +124,7 @@ jobs:
tag: ${{ env.tag }}
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}${{ env.release_count }}
body: |
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [![download](https://img.shields.io/github/downloads/LuminolMC/${{ env.project_id }}/${{ env.tag }}/total?color=red&style=flat-square)](https://github.com/LuminolMC/${{ env.project_id }}/releases/download/${{ env.tag }}/${{ env.jar }})
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [![download](https://img.shields.io/github/downloads/LophineCraft/${{ env.project_id }}/${{ env.tag }}/total?color=red&style=flat-square)](https://github.com/LophineCraft/${{ env.project_id }}/releases/download/${{ env.tag }}/${{ env.jar }})
This release is automatically compiled by GitHub Actions
### Branch Info
> ${{ github.ref_name }}
@@ -143,7 +143,7 @@ jobs:
tag: ${{ env.tag }}
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}${{ env.release_count }}
body: |
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [![download](https://img.shields.io/github/downloads/LuminolMC/${{ env.project_id }}/${{ env.tag }}/total?color=red&style=flat-square)](https://github.com/LuminolMC/${{ env.project_id }}/releases/download/${{ env.tag }}/${{ env.jar }})
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [![download](https://img.shields.io/github/downloads/LophineCraft/${{ env.project_id }}/${{ env.tag }}/total?color=red&style=flat-square)](https://github.com/LophineCraft/${{ env.project_id }}/releases/download/${{ env.tag }}/${{ env.jar }})
This release is automatically compiled by GitHub Actions
### Comments
> ${{ inputs.comments }}
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
pull-requests: write
checks: write
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit
fetch-depth: 0 # a full history is required for pull request analysis
+16 -46
View File
@@ -5,15 +5,15 @@
*Lophine 是一个基于Luminol的分支,具有许多有用的优化和可配置的原版特性,目标是在Folia上实现更多生电的内容(请注意,完整生电请使用Fabric)*
![Created At](https://img.shields.io/github/created-at/LuminolMC/Lophine?style=for-the-badge&color=blue)
[![License](https://img.shields.io/github/license/LuminolMC/Lophine?style=for-the-badge&color=green)](LICENSE.md)
[![Issues](https://img.shields.io/github/issues/LuminolMC/Lophine?style=for-the-badge&color=orange)](https://github.com/LuminolMC/Lophine/issues)
![Created At](https://img.shields.io/github/created-at/LophineCraft/Lophine?style=for-the-badge&color=blue)
[![License](https://img.shields.io/github/license/LophineCraft/Lophine?style=for-the-badge&color=green)](LICENSE.md)
[![Issues](https://img.shields.io/github/issues/LophineCraft/Lophine?style=for-the-badge&color=orange)](https://github.com/LophineCraft/Lophine/issues)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LuminolMC/Lophine?style=for-the-badge&color=purple)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LuminolMC/Lophine?style=for-the-badge&color=yellow)
![GitHub all releases](https://img.shields.io/github/downloads/LuminolMC/Lophine/total?style=for-the-badge&color=red)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LophineCraft/Lophine?style=for-the-badge&color=purple)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LophineCraft/Lophine?style=for-the-badge&color=yellow)
![GitHub all releases](https://img.shields.io/github/downloads/LophineCraft/Lophine/total?style=for-the-badge&color=red)
![Repo contributors](https://img.shields.io/github/contributors/LuminolMC/Lophine?style=for-the-badge&color=brightgreen)
![Repo contributors](https://img.shields.io/github/contributors/LophineCraft/Lophine?style=for-the-badge&color=brightgreen)
[English](./README_EN.md) | **中文**
</div>
@@ -32,7 +32,7 @@
## 📥 下载
### 稳定版本
所有发布版本都可以在 [Releases](https://github.com/LuminolMC/Lophine/releases) 页面找到。
所有发布版本都可以在 [Releases](https://github.com/LophineCraft/Lophine/releases) 页面找到。
### 开发版本
如果您想体验最新功能,可以通过以下步骤自行构建。
@@ -41,7 +41,7 @@
```bash
# 克隆项目
git clone https://github.com/LuminolMC/Lophine.git
git clone https://github.com/LophineCraft/Lophine.git
cd Lophine
# 应用补丁并构建 Paperclip JAR
@@ -57,7 +57,7 @@ cd Lophine
```kotlin
repositories {
maven {
url = "https://repo.menthamc.org/repository/maven-public/"
url = "https://repo.bacteriawa.com/repository/maven-public/"
}
}
@@ -71,8 +71,8 @@ dependencies {
```xml
<repositories>
<repository>
<id>menthamc</id>
<url>https://repo.menthamc.org/repository/maven-public/</url>
<id>repository</id>
<url>https://repo.bacteriawa.com/repository/maven-public/</url>
</repository>
</repositories>
@@ -91,15 +91,13 @@ dependencies {
### 加入我们的社区
- **QQ群**: [1015048616](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=QML5kIVsniPi1PlZvnjHQT_02EHsZ5Jc&authKey=%2FTCJsZC7JFQ9sxAroPCKuYnlV57Z5fyqp36ewXZk3Sn4iJ9p4MB1JKdc%2FFcX3HOM&noverify=0&group_code=1015048616)
- **QQ频道**: [点击加入](https://pd.qq.com/s/eq9krf9j)
- **Telegram**: [点击加入](https://t.me/LuminolMinecraft)
- **Discord**: [点击加入](https://discord.gg/Qd7m3V6eDx)
- **QQ群**: [1020403749](https://qm.qq.com/cgi-bin/qm/qr?k=y_MA9UaN7PM9e9J1LIs9Eea3LK8C0h6J&jump_from=webapi&authKey=ap5f8MlbeezXYtnmpnT5ZOFljDuOyV6OAb2PIcViQ+Ilr60Ycq63FDDTsJOZDYtj)
- **Discord**: [点击加入](https://discord.gg/UXSgPZczcy)
### 获取帮助
- 📋 [提交 Issue](https://github.com/LuminolMC/Lophine/issues)
- 💬 [GitHub Discussions](https://github.com/LuminolMC/Lophine/discussions)
- 📋 [提交 Issue](https://github.com/LophineCraft/Lophine/issues)
- 💬 [GitHub Discussions](https://github.com/LophineCraft/Lophine/discussions)
- 📖 [项目文档](./docs/)
## 🐛 问题反馈
@@ -124,34 +122,6 @@ dependencies {
![bStats](https://bstats.org/signatures/server-implementation/Lophine.svg "bStats")
## 🎉 特别感谢
### 项目赞助商
<div align="center">
<b>感谢 <a href="https://github.com/LegacyLands">LegacyLands</a> 对本项目的赞助</b>
<br>
<i>如果你想开发跨 Folia/非 Folia 平台的插件,<a href="https://github.com/LegacyLands/legacy-lands-library/">legacy-lands-library</a> 将会是个不错的选择</i>
<br><br>
<img src="public/image/legacy-lands-logo.png" alt="LegacyLands Logo" width="200">
</div>
---
## ⭐ 请给我们一个 Star
> 你的每一个免费的 ⭐Star 就是我们每一个前进的动力。
### Star 历史
<a href="https://star-history.com/#LuminolMC/Luminol&LuminolMC/LightingLuminol&LuminolMC/Lophine&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol%2CLuminolMC/Lophine&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol%2CLuminolMC/Lophine&type=Date" />
<img alt="Star历史表" src="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol%2CLuminolMC/Lophine&type=Date" />
</picture>
</a>
<div align="center">
<b>如果这个项目对您有帮助,请不要忘记给我们一个 ⭐Star!</b>
</div>
+16 -46
View File
@@ -5,15 +5,15 @@
*Lophine is a Luminol fork with many useful optimizations and configurable vanilla features, aims to provide more function for survival-usable circuit on folia (Please note that Fabric should be used for complete survival-usable)*
![Created At](https://img.shields.io/github/created-at/LuminolMC/Lophine?style=for-the-badge&color=blue)
[![License](https://img.shields.io/github/license/LuminolMC/Lophine?style=for-the-badge&color=green)](LICENSE.md)
[![Issues](https://img.shields.io/github/issues/LuminolMC/Lophine?style=for-the-badge&color=orange)](https://github.com/LuminolMC/Lophine/issues)
![Created At](https://img.shields.io/github/created-at/LophineCraft/Lophine?style=for-the-badge&color=blue)
[![License](https://img.shields.io/github/license/LophineCraft/Lophine?style=for-the-badge&color=green)](LICENSE.md)
[![Issues](https://img.shields.io/github/issues/LophineCraft/Lophine?style=for-the-badge&color=orange)](https://github.com/LophineCraft/Lophine/issues)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LuminolMC/Lophine?style=for-the-badge&color=purple)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LuminolMC/Lophine?style=for-the-badge&color=yellow)
![GitHub all releases](https://img.shields.io/github/downloads/LuminolMC/Lophine/total?style=for-the-badge&color=red)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LophineCraft/Lophine?style=for-the-badge&color=purple)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LophineCraft/Lophine?style=for-the-badge&color=yellow)
![GitHub all releases](https://img.shields.io/github/downloads/LophineCraft/Lophine/total?style=for-the-badge&color=red)
![Repo contributors](https://img.shields.io/github/contributors/LuminolMC/Lophine?style=for-the-badge&color=brightgreen)
![Repo contributors](https://img.shields.io/github/contributors/LophineCraft/Lophine?style=for-the-badge&color=brightgreen)
**English** | [中文](./README.md)
</div>
@@ -32,7 +32,7 @@
## 📥 Download
### Stable Releases
All release versions can be found on the [Releases](https://github.com/LuminolMC/Lophine/releases) page.
All release versions can be found on the [Releases](https://github.com/LophineCraft/Lophine/releases) page.
### Development Builds
If you want to experience the latest features, you can build it yourself following the steps below.
@@ -41,7 +41,7 @@ If you want to experience the latest features, you can build it yourself followi
```bash
# Clone the project
git clone https://github.com/LuminolMC/Lophine.git
git clone https://github.com/LophineCraft/Lophine.git
cd Lophine
# Apply patches and build Paperclip JAR
@@ -57,7 +57,7 @@ After building, you can find the generated JAR file in the `lophine-server/build
```kotlin
repositories {
maven {
url = "https://repo.menthamc.org/repository/maven-public/"
url = "https://repo.bacteriawa.com/repository/maven-public/"
}
}
@@ -71,8 +71,8 @@ dependencies {
```xml
<repositories>
<repository>
<id>menthamc</id>
<url>https://repo.menthamc.org/repository/maven-public/</url>
<id>repository</id>
<url>https://repo.bacteriawa.com/repository/maven-public/</url>
</repository>
</repositories>
@@ -92,15 +92,13 @@ dependencies {
### Join Our Community
- **QQ Group**: [1015048616](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=QML5kIVsniPi1PlZvnjHQT_02EHsZ5Jc&authKey=%2FTCJsZC7JFQ9sxAroPCKuYnlV57Z5fyqp36ewXZk3Sn4iJ9p4MB1JKdc%2FFcX3HOM&noverify=0&group_code=1015048616)
- **QQ Channel**: [Join Here](https://pd.qq.com/s/eq9krf9j)
- **Telegram**: [Join Here](https://t.me/LuminolMinecraft)
- **Discord**: [Join Here](https://discord.gg/Qd7m3V6eDx)
- **QQ Group**: [1020403749](https://qm.qq.com/cgi-bin/qm/qr?k=y_MA9UaN7PM9e9J1LIs9Eea3LK8C0h6J&jump_from=webapi&authKey=ap5f8MlbeezXYtnmpnT5ZOFljDuOyV6OAb2PIcViQ+Ilr60Ycq63FDDTsJOZDYtj)
- **Discord**: [Join Here](https://discord.gg/UXSgPZczcy)
### Get Help
- 📋 [Submit Issues](https://github.com/LuminolMC/Lophine/issues)
- 💬 [GitHub Discussions](https://github.com/LuminolMC/Lophine/discussions)
- 📋 [Submit Issues](https://github.com/LophineCraft/Lophine/issues)
- 💬 [GitHub Discussions](https://github.com/LophineCraft/Lophine/discussions)
- 📖 [Project Documentation](./docs/)
## 🐛 Bug Reports
@@ -125,34 +123,6 @@ We welcome community contributions! For detailed contribution guidelines, please
![bStats](https://bstats.org/signatures/server-implementation/Lophine.svg "bStats")
## 🎉 Special Thanks
### Project Sponsors
<div align="center">
<b>Thanks to <a href="https://github.com/LegacyLands">LegacyLands</a> for sponsoring this project</b>
<br>
<i>If you want to develop cross-Folia/non-Folia platform plugins, <a href="https://github.com/LegacyLands/legacy-lands-library/">legacy-lands-library</a> would be a great choice</i>
<br><br>
<img src="public/image/legacy-lands-logo.png" alt="LegacyLands Logo" width="200">
</div>
---
## ⭐ Give Us a Star!
> Every free ⭐Star you give is the motivation for our every step forward.
### Star History
<a href="https://star-history.com/#LuminolMC/Luminol&LuminolMC/LightingLuminol&LuminolMC/Lophine&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol%2CLuminolMC/Lophine&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol%2CLuminolMC/Lophine&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol%2CLuminolMC/Lophine&type=Date" />
</picture>
</a>
<div align="center">
<b>If this project helps you, please don't forget to give us a ⭐Star!</b>
</div>
+5 -5
View File
@@ -9,7 +9,7 @@ plugins {
paperweight {
filterPatches = false
upstreams.register("luminol") {
repo = github("LuminolMC", "Luminol")
repo = github("LuminolCustomArchive", "Luminol")
ref = providers.gradleProperty("luminolRef")
println("Upstream commit ref: " + ref.get())
@@ -44,7 +44,7 @@ paperweight {
}
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
val menthaMavenPublicUrl = "https://repo.menthamc.org/repository/maven-public/";
val bacteriawaMavenPublicUrl = "https://repo.bacteriawa.com/repository/maven-public/";
subprojects {
apply(plugin = "java-library")
@@ -59,7 +59,7 @@ subprojects {
repositories {
mavenCentral()
maven(paperMavenPublicUrl)
maven(menthaMavenPublicUrl)
maven(bacteriawaMavenPublicUrl)
}
dependencies {
@@ -91,8 +91,8 @@ subprojects {
extensions.configure<PublishingExtension> {
repositories {
maven("https://repo.menthamc.org/repository/maven-snapshots/") {
name = "MenthaMC"
maven("https://repo.bacteriawa.com/repository/maven-releases/") {
name = "Bacteriawa"
credentials(PasswordCredentials::class) {
username = System.getenv("PRIVATE_MAVEN_REPO_USERNAME")
password = System.getenv("PRIVATE_MAVEN_REPO_PASSWORD")
+4 -4
View File
@@ -1,15 +1,15 @@
group=fun.bm.lophine
mcVersion=26.1.2
apiVersion=26.1.2
mcVersion=26.2
apiVersion=26.2
channel=STABLE
clipVersion=3.0.18
weightVersion=2.0.15
# true for release, false for skip release, pre for pre-release
release=true
release=pre
# true for push to repo, false for skip push repo, auto for detect by release value
pushRepo=auto
luminolRef=6dbf8f3ee48c8fcb791be55706a33a8f29c5a042
luminolRef=bd964477d5dfea9a2349541c1a75c5afbebe48db
org.gradle.configuration-cache=true
org.gradle.caching=true
+1 -1
View File
@@ -1,6 +1,6 @@
--- a/luminol-api/build.gradle.kts
+++ b/luminol-api/build.gradle.kts
@@ -104,20 +_,24 @@
@@ -107,20 +_,24 @@
srcDir(generatedDir)
srcDir(file("../paper-api/src/main/java"))
srcDir(file("../folia-api/src/main/java"))
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 8e96326c55510642df01ef15e1a3edb1e81176cb..592a3c59bf5edbc65c7c0472e2382593b7b22086 100644
index 0ac1e049fad85de8365380b03e60d915ee643f16..a747fbe107dcc134558ca8ecfbe30e81245a5742 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -3048,4 +3048,15 @@ public final class Bukkit {
@@ -3052,4 +3052,15 @@ public final class Bukkit {
return server.getFeatureManager();
}
// Leaves end - Feature API
@@ -28,10 +28,10 @@ index 8e96326c55510642df01ef15e1a3edb1e81176cb..592a3c59bf5edbc65c7c0472e2382593
+ // Leaves end - Bot API
}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 473b0e02c003d5317ef798c320e5c845124f4e12..978e015e91408503b4ec84ec5b3c5193255ba7db 100644
index 48e53223ba7edeca5256244480441a56a6657075..f4f64538d13f3dba5a1cd8f0d24d1fd2e8b75749 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2813,4 +2813,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@@ -2826,4 +2826,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
double @Nullable [] getRegionTPS(@NotNull World world, int chunkX, int chunkZ);
// Folia end - region TPS API
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 592a3c59bf5edbc65c7c0472e2382593b7b22086..838ad878528267b57b69d2938aee0eb6326948eb 100644
index a747fbe107dcc134558ca8ecfbe30e81245a5742..b09a90f8187a15ddaa15f231f46f51f2b1d2c1ed 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -3059,4 +3059,10 @@ public final class Bukkit {
@@ -3063,4 +3063,10 @@ public final class Bukkit {
return server.getBotManager();
}
// Leaves end - Bot API
@@ -23,10 +23,10 @@ index 592a3c59bf5edbc65c7c0472e2382593b7b22086..838ad878528267b57b69d2938aee0eb6
+ // Leaves end - Photographer API
}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 978e015e91408503b4ec84ec5b3c5193255ba7db..d054926f6082bba7d0b59e610e5d725ff5f9ffa4 100644
index f4f64538d13f3dba5a1cd8f0d24d1fd2e8b75749..2f4cc1115170557389f577f995f1bfaed1ec2f71 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2822,4 +2822,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@@ -2835,4 +2835,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
@NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager();
// Leaves end - Bot API
@@ -5,14 +5,14 @@ Subject: [PATCH] Rebrand to Lophine
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
index a2f5a99ee45a0810fd338ccf6f71df3a077ca62b..05e1aa84586284ac0389e7023f975bfb08438535 100644
index 3b700b214ac6818cd75c34b207aa1436f52231e7..315c137cb9dbac51a8ac0d63f0ae0127e57c6c9f 100644
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
@@ -24,6 +24,7 @@ public class ConfigManager {
@@ -25,6 +25,7 @@ public class ConfigManager {
public static void initConfigs() {
registerConfig("luminol", ConfigsInstance.of("luminol", "me.earthme.luminol.config.modules"));
+ registerConfig("lophine", ConfigsInstance.of("lophine", "fun.bm.lophine.config.modules")); // add lophine global config
registerConfig("luminol", builder.of("luminol", "me.earthme.luminol.config.modules"));
+ registerConfig("lophine", builder.of("lophine", "fun.bm.lophine.config.modules")); // add lophine global config
preLoad();
}
@@ -5,10 +5,10 @@ Subject: [PATCH] Leaves: Fakeplayer
diff --git a/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java b/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java
index 0a20c6f03625391201e5ced167707e54ed27daa1..dc983bcb8d2e90ad27a693dfcd6debb4b2c2b86b 100644
index a4c188f71564fc77a9fa22b4cae032e1919d06f2..019266803f1452cb1e76350da8edae10a77020ac 100644
--- a/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java
+++ b/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java
@@ -46,6 +46,12 @@ public class FoliaServerWaypointManager implements WaypointManager<@NotNull Wayp
@@ -54,6 +54,12 @@ public class FoliaServerWaypointManager extends ServerWaypointManager {
return;
}
@@ -21,16 +21,15 @@ index 0a20c6f03625391201e5ced167707e54ed27daa1..dc983bcb8d2e90ad27a693dfcd6debb4
this.waypoints.add(waypoint);
for (ServerPlayer toCreateFor : this.trackingPlayers) {
@@ -101,6 +107,12 @@ public class FoliaServerWaypointManager implements WaypointManager<@NotNull Wayp
scheduleIfOffTarget(player, () -> {
this.trackingPlayers.add(player);
@@ -110,6 +116,11 @@ public class FoliaServerWaypointManager extends ServerWaypointManager {
this.trackingPlayers.add(player);
scheduleIfOffTarget(player, () -> {
+ // Leaves start - fakeplayer
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
+ return;
+ }
+ // Leaves end - fakeplayer
+
for (WaypointTransmitter transmitter : this.waypoints) {
this.createConnection(player, transmitter);
}
@@ -5,20 +5,22 @@ Subject: [PATCH] Carpet features
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
index 05e1aa84586284ac0389e7023f975bfb08438535..da9ff49be1c7a12ea93d665c37e828afd24d7070 100644
index 315c137cb9dbac51a8ac0d63f0ae0127e57c6c9f..2a2d6aff636ad960638b357d224a631c89d23d33 100644
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
@@ -25,6 +25,13 @@ public class ConfigManager {
@@ -26,6 +26,15 @@ public class ConfigManager {
public static void initConfigs() {
registerConfig("luminol", ConfigsInstance.of("luminol", "me.earthme.luminol.config.modules"));
registerConfig("lophine", ConfigsInstance.of("lophine", "fun.bm.lophine.config.modules")); // add lophine global config
+ registerConfig("lophine_carpet", ConfigsInstance.of(
registerConfig("luminol", builder.of("luminol", "me.earthme.luminol.config.modules"));
registerConfig("lophine", builder.of("lophine", "fun.bm.lophine.config.modules")); // add lophine global config
+ // Lophine start - add carpet config
+ registerConfig("lophine_carpet", builder.of(
+ new java.io.File("lophine_config"),
+ "lophine_carpet",
+ "lophine_carpet_config.toml",
+ "lophinecarpetconfig",
+ "fun.bm.lophine.carpet.config.modules"
+ )); // add lophine carpet config
+ ));
+ // Lophine end - add carpet config
preLoad();
}
@@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Mon, 15 Jun 2026 01:33:32 +0800
Subject: [PATCH] TEMP: Temporarily transform config between different config
system
Should be removed in Minecraft 26.2 Update
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
index da9ff49be1c7a12ea93d665c37e828afd24d7070..dc6e6d38ebe0c4f7f481da571ab116015fd08cd2 100644
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
@@ -62,6 +62,10 @@ public class ConfigManager {
CompletableFuture.allOf(futures).join();
CommandRegister.register(); // register command after config loaded to enable some command didn't depend on config files
initialized = true;
+
+ reApplyStagedConfigs();
+ saveConfigs();
+ configfiles.values().forEach((config) -> config.reload(true, false));
}
public static void registerRunnableBeforeFinalLoad(Runnable runnable) {
@@ -5,7 +5,7 @@ Subject: [PATCH] Server I18n
diff --git a/net/minecraft/locale/Language.java b/net/minecraft/locale/Language.java
index 49c7f8194be8222e329fc3215a6aa6db0b221b11..c6c968d28e0d14a4c50e66bdd5176a000944b707 100644
index 47cd33bce908744e64356b585853d6a8ecf82443..bb4011d3c6a1d2a5aa66e68fe719cd5eea2c0dd2 100644
--- a/net/minecraft/locale/Language.java
+++ b/net/minecraft/locale/Language.java
@@ -37,6 +37,7 @@ public abstract class Language {
@@ -24,12 +24,12 @@ index 49c7f8194be8222e329fc3215a6aa6db0b221b11..c6c968d28e0d14a4c50e66bdd5176a00
+ public static void parseTranslations(final BiConsumer<String, String> output, final String path) { // Lophine - private -> public
try (InputStream stream = Language.class.getResourceAsStream(path)) {
loadFromJson(stream, output);
} catch (JsonParseException | IOException var7) {
} catch (IOException | JsonParseException e) {
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
index 143ad4e342b184aa02b6fbbe81508e244eebc7a2..89be42b8519522398920eb424c894fd2ab8c9666 100644
index 2a75f8fbd2e5f41ca138740319d34683915e3b5b..0cc56b19d68f34994c9dbae578609eca7b7343cb 100644
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -155,6 +155,8 @@ public class Main {
@@ -158,6 +158,8 @@ public class Main {
return;
}
@@ -39,10 +39,10 @@ index 143ad4e342b184aa02b6fbbe81508e244eebc7a2..89be42b8519522398920eb424c894fd2
String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck();
if (awtException != null) {
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 3707b03b6d7ebdf47a38f4feff5b738eb41f38e1..1bc1e9a77dca7acfe5f989f6439f185d0d2e20a6 100644
index 81934fb56744dbbb3fdd100e8ec83cb634034d04..2dae0f4249eade60ac55c9fa289dd146dc3675e1 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -283,6 +283,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -239,6 +239,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
// Paper end - initialize global and world-defaults configuration
me.earthme.luminol.config.ConfigManager.loadConfigFiles(); // Luminol - load config file
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix datapack command save function
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 83178b9a0b017c8945c0f41981838f40263c9a12..ef898f5b60219be00471f9ea227103dfcea5b202 100644
index fb5f9176916931b23ebf4a5b7ecdfc5285ffbc2b..ecdcf0db97341d2cb460f86f451cecd5c40dbfee 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -2472,6 +2472,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2450,6 +2450,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return this.reloadResources(packsToEnable, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
}
@@ -26,19 +26,19 @@ index 83178b9a0b017c8945c0f41981838f40263c9a12..ef898f5b60219be00471f9ea227103df
final Collection<String> packsToEnable, final io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause cause
) {
diff --git a/net/minecraft/server/commands/DataPackCommand.java b/net/minecraft/server/commands/DataPackCommand.java
index 0c7c829270d3cd3dd05a3dc7dfe82ee01d5c6bd8..04fa1c5bb1c0b025a56941aae7d2151d1087e257 100644
index 80d9bc3d680c30dae15064e0e8c3d1379ccd52e6..2bc9cf924d40d5d11935f73cf6d35442b0b0ba06 100644
--- a/net/minecraft/server/commands/DataPackCommand.java
+++ b/net/minecraft/server/commands/DataPackCommand.java
@@ -98,7 +98,7 @@ public class DataPackCommand {
@@ -99,7 +99,7 @@ public class DataPackCommand {
dispatcher.register(
Commands.literal("datapack")
.requires(Commands.hasPermission(Commands.LEVEL_GAMEMASTERS))
- /*.then( // Luminol - Add back read-only datapack command
+ .then(
+ .then( // Lophine - Fix datapack command save function
Commands.literal("enable")
.then(
Commands.argument("name", StringArgumentType.string())
@@ -145,11 +145,11 @@ public class DataPackCommand {
@@ -146,11 +146,11 @@ public class DataPackCommand {
.suggests(SELECTED_PACKS)
.executes(c -> disablePack(c.getSource(), getPack(c, "name", false)))
)
@@ -52,12 +52,12 @@ index 0c7c829270d3cd3dd05a3dc7dfe82ee01d5c6bd8..04fa1c5bb1c0b025a56941aae7d2151d
.then(Commands.literal("enabled").executes(c -> listEnabledPacks(c.getSource())))
)
.then(
@@ -235,7 +235,7 @@ public class DataPackCommand {
@@ -238,7 +238,7 @@ public class DataPackCommand {
}
private static int listPacks(final CommandSourceStack source) {
- return listEnabledPacks(source) ;// + listAvailablePacks(source); // Luminol - Add back read-only datapack command
+ return listEnabledPacks(source) + listAvailablePacks(source);
+ return listEnabledPacks(source) + listAvailablePacks(source); // Lophine - Fix datapack command save function
}
private static int listAvailablePacks(final CommandSourceStack source) {
@@ -8,7 +8,7 @@ As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/dc46f46d28dcdcaf33bb
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/dc46f46d28dcdcaf33bb533f9571a107db98c1d7/LICENSE)
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 63b81f30b8d813a7986ae72842fdc2d3097fa103..527c495bb4f6007aee760b99cc0e9aa589931f4b 100644
index 2939aa1ecd68504424198dd7c90c71c6c1aa4c80..8b7e4814b00d6f6c9f25cce5186905f165b97c2f 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -961,6 +961,10 @@ public abstract class PlayerList {
@@ -23,10 +23,10 @@ index 63b81f30b8d813a7986ae72842fdc2d3097fa103..527c495bb4f6007aee760b99cc0e9aa5
// Paper start - whitelist verify event / login event
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index c157aa170d5879206810f4852a96120396b69db7..b9cc33198efceb75dfef333c018b1296944451cb 100644
index a447b9fbb579591c62b3d8f8e2527796feefc4a0..9fdc8134fdde2cdd7724a459a29e51f4ad943403 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -174,6 +174,7 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -175,6 +175,7 @@ public abstract class Player extends Avatar implements ContainerUser {
public float hurtDir;
public boolean affectsSpawning = true; // Paper - Affects Spawning API
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
@@ -94,15 +94,15 @@ index 4df3a32faf85595372f4b250482d852c985ea3ab..101b3711bfb98888837ebed323561cac
this.activeChest = activeChest;
}
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
index 24a2c411da0ebbb7f97d621bb76ff686621f9aae..a9f511a549681a76a962855c26b9af5980f36df7 100644
index f1a5b9670dd04b800a8d755f32364458a16d924a..bfc34508937befc0f7610176ebe625563f7a4fe0 100644
--- a/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
@@ -88,7 +88,15 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
// Paper start - Fix InventoryOpenEvent cancellation - moved up;
container.setActiveChest(enderChest); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
if (level instanceof ServerLevel serverLevel && player.openMenu(
- new SimpleMenuProvider((containerId, inventory, p) -> ChestMenu.threeRows(containerId, inventory, container), CONTAINER_TITLE)
+ new SimpleMenuProvider(
@@ -90,7 +90,15 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
// Paper start - Fix InventoryOpenEvent cancellation - moved up;
container.setActiveChest(enderChest); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
if (level instanceof ServerLevel serverLevel && player.openMenu(
- new SimpleMenuProvider((containerId, inventory, p) -> ChestMenu.threeRows(containerId, inventory, container), CONTAINER_TITLE)
+ new SimpleMenuProvider(
+ (containerId, inventory, p) -> switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows) {
+ case 6 -> ChestMenu.sixRows(containerId, inventory, container);
+ case 5 -> ChestMenu.fiveRows(containerId, inventory, container);
@@ -111,14 +111,14 @@ index 24a2c411da0ebbb7f97d621bb76ff686621f9aae..a9f511a549681a76a962855c26b9af59
+ case 1 -> ChestMenu.oneRow(containerId, inventory, container);
+ default -> ChestMenu.threeRows(containerId, inventory, container);
+ }, CONTAINER_TITLE) // Purpur - Barrels and enderchests 6 rows
).isPresent()) {
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
player.awardStat(Stats.OPEN_ENDERCHEST);
).isPresent()) {
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
player.awardStat(Stats.OPEN_ENDERCHEST);
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
index 61e39a18c0fba22699750e5c0187d19a0433b9a2..98c48426fcbb4aeba479e87ab27b03e17b50d7f5 100644
index 00aa2d0269f636f6e4c12c1be98cf901e9be8558..e8c83037700a179a43b0dc3882a67622a2e95640 100644
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -60,7 +60,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -59,7 +59,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
}
// CraftBukkit end
private static final Component DEFAULT_NAME = Component.translatable("container.barrel");
@@ -135,9 +135,9 @@ index 61e39a18c0fba22699750e5c0187d19a0433b9a2..98c48426fcbb4aeba479e87ab27b03e1
+ // Purpur end - Barrels and enderchests 6 rows
+
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
{
Objects.requireNonNull(BarrelBlockEntity.this);
@@ -123,7 +133,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
// Paper start - delay open/close callbacks
@Override
@@ -118,7 +128,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
@Override
public int getContainerSize() {
@@ -155,7 +155,7 @@ index 61e39a18c0fba22699750e5c0187d19a0433b9a2..98c48426fcbb4aeba479e87ab27b03e1
}
@Override
@@ -144,7 +163,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -139,7 +158,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
@Override
protected AbstractContainerMenu createMenu(final int containerId, final Inventory inventory) {
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to disable some check for operators
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index b2dc29f75259eca66f5dfe4456845b6dd70b0baf..15470867ed0f668fd3ba9c1fa24f84b3de8cb756 100644
index ebede474ca98c82131215913865b9f7bb4d57313..fe6e1aea364620f82de44b942da0d3846c7d17b5 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -399,7 +399,7 @@ public class ServerGamePacketListenerImpl
@@ -402,7 +402,7 @@ public class ServerGamePacketListenerImpl
this.tickCount++;
this.knownMovePacketCount = this.receivedMovePacketCount;
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
@@ -17,7 +17,7 @@ index b2dc29f75259eca66f5dfe4456845b6dd70b0baf..15470867ed0f668fd3ba9c1fa24f84b3
// LOGGER.warn("{} was kicked for floating too long!", this.player.getPlainTextName()); // Paper - Logging moved to net.minecraft.server.network.ServerCommonPacketListenerImpl.disconnect()
this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingPlayer, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_PLAYER); // Paper - use configurable kick message & kick event cause
return true;
@@ -418,7 +418,7 @@ public class ServerGamePacketListenerImpl
@@ -421,7 +421,7 @@ public class ServerGamePacketListenerImpl
this.vehicleLastGoodY = this.lastVehicle.getY();
this.vehicleLastGoodZ = this.lastVehicle.getZ();
if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) {
@@ -26,7 +26,7 @@ index b2dc29f75259eca66f5dfe4456845b6dd70b0baf..15470867ed0f668fd3ba9c1fa24f84b3
// LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getPlainTextName()); // Paper - Logging moved to net.minecraft.server.network.ServerCommonPacketListenerImpl.disconnect()
this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_VEHICLE); // Paper - use configurable kick message & kick event cause
return true;
@@ -671,7 +671,7 @@ public class ServerGamePacketListenerImpl
@@ -674,7 +674,7 @@ public class ServerGamePacketListenerImpl
zDist = targetZ - vehicle.getZ();
movedDist = xDist * xDist + yDist * yDist + zDist * zDist;
boolean fail = false;
@@ -35,7 +35,7 @@ index b2dc29f75259eca66f5dfe4456845b6dd70b0baf..15470867ed0f668fd3ba9c1fa24f84b3
fail = true;
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", vehicle.getPlainTextName(), this.player.getPlainTextName(), Math.sqrt(movedDist));
}
@@ -1603,7 +1603,7 @@ public class ServerGamePacketListenerImpl
@@ -1606,7 +1606,7 @@ public class ServerGamePacketListenerImpl
// Paper start - Add fail move event
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY,
targetX, targetY, targetZ, targetYRot, targetXRot, true);
@@ -44,7 +44,7 @@ index b2dc29f75259eca66f5dfe4456845b6dd70b0baf..15470867ed0f668fd3ba9c1fa24f84b3
if (event.getLogWarning()) {
LOGGER.warn("{} moved too quickly! {},{},{}", this.player.getPlainTextName(), xDist, yDist, zDist);
}
@@ -1682,7 +1682,7 @@ public class ServerGamePacketListenerImpl
@@ -1672,7 +1672,7 @@ public class ServerGamePacketListenerImpl
// Paper start - Add fail move event
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY,
targetX, targetY, targetZ, targetYRot, targetXRot, true);
@@ -5,28 +5,28 @@ Subject: [PATCH] Add config to enable cross region damage trace
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 6cedc129f31289eaf4e3580219fc1988c0f3c5a1..5f1fad59a26e3fe29f9000a92be5d6c4422dcd01 100644
index b4d8cc8b520266abe1921b5e990c34fce3f1d982..93c76c2faf75bf4901ecaba1e04d957d5ddddfca 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1464,6 +1464,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1448,6 +1448,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.awardStat(Stats.ENTITY_KILLED_BY.get(killer.getType()));
killer.awardKillScore(this, source);
this.createWitherRose(killer);
+ // Luminol Start - Cross Region Damage trace
+ // Lophine Start - Cross Region Damage trace
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
+ final LivingEntity entitylivingnew = this.getKillCreditOrigin();
+ if (entitylivingnew != null) {
+ this.damageTransferToAsync(entitylivingnew, source);
+ }
+ // Luminol End - Cross Region Damage trace
+ // Lophine End - Cross Region Damage trace
}
this.level().broadcastEntityEvent(this, EntityEvent.DEATH);
@@ -1487,6 +1494,24 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1462,6 +1469,24 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.connection.markClientUnloadedAfterDeath();
}
// Leaves end - exp fix
+ // Luminol Start - Cross Region Damage trace
+ // Lophine Start - Cross Region Damage trace
+ private void damageTransferToAsync(LivingEntity entity, DamageSource cause) {
+ // Operations running on current entity
+ this.awardStat(Stats.ENTITY_KILLED_BY.get(entity.getType()));
@@ -42,34 +42,34 @@ index 6cedc129f31289eaf4e3580219fc1988c0f3c5a1..5f1fad59a26e3fe29f9000a92be5d6c4
+ }
+ }, null, 1L);
+ }
+ // Luminol End - Cross Region Damage trace
+ // Lophine End - Cross Region Damage trace
+
private void tellNeutralMobsThatIDied() {
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
this.level()
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 17483ffff6cb2a9e86db7079e7c3a9a800654c62..29919b8f3c05c8ffaf66f86e441778eeefb293b1 100644
index fcaeb471dada57e9ba4d224693cefbff2fa631be..5762eed9e99d918bee02d77c0ddd70be0aa0e2ec 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -1961,6 +1961,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
final LivingEntity killer = this.getKillCredit();
@@ -1855,6 +1855,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
Runnable afterEvent = () -> { // Paper
if (killer != null) {
killer.awardKillScore(this, source);
+ // Luminol Start - Cross Region Damage trace
+ // Lophine Start - Cross Region Damage trace
+ } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
+ final LivingEntity killernew = this.getKillCreditOrigin();
+ if (killernew != null) {
+ this.damageTransferToAsync(killernew, source);
+ }
+ // Luminol End - Cross Region Damage trace
+ // Lophine End - Cross Region Damage trace
}
}); // Paper end
this.postDeathDropItems(deathEvent); // Paper
@@ -1971,6 +1978,19 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
return deathEvent; // Paper
if (this.isSleeping()) {
@@ -1943,6 +1950,19 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
this.postDeathEventTasks.add(() -> this.dropExperience(level, source.getEntity())); // Paper
}
+ // Luminol Start - Cross Region Damage trace
+ // Lophine Start - Cross Region Damage trace
+ private void damageTransferToAsync(LivingEntity entity, DamageSource damageSource) {
+ entity.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> {
+ try {
@@ -80,16 +80,16 @@ index 17483ffff6cb2a9e86db7079e7c3a9a800654c62..29919b8f3c05c8ffaf66f86e441778ee
+ }
+ }, null, 1L );
+ }
+ // Luminol End - Cross Region Damage trace
+ // Lophine End - Cross Region Damage trace
+
protected void dropEquipment(final ServerLevel level) {
}
protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
@@ -2629,6 +2649,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
@@ -2609,6 +2629,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
}
}
+ // Luminol Start - Cross Region Damage trace
+ // Lophine Start - Cross Region Damage trace
+ @Nullable
+ public LivingEntity getKillCreditOrigin() {
+ if (this.lastHurtByPlayer != null) {
@@ -99,7 +99,7 @@ index 17483ffff6cb2a9e86db7079e7c3a9a800654c62..29919b8f3c05c8ffaf66f86e441778ee
+ }
+ return null;
+ }
+ // Luminol End - Cross Region Damage trace
+ // Lophine End - Cross Region Damage trace
+
public final float getMaxHealth() {
return (float)this.getAttributeValue(Attributes.MAX_HEALTH);
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to enable save-all command
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
index 11cacb26ce260373476dad764014ba1852477831..981f63b75584dbcb4bb0d5672e8c8bb140c52f9d 100644
index 276349d778c2e6f0b1081eec4851bad5d25db237..79ef1e69ec364beec69b37c6850c038cdba73b4c 100644
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
@@ -364,6 +364,8 @@ public final class RegionizedServer {
@@ -265,6 +265,8 @@ public final class RegionizedServer {
// tick player ping sample
this.tickPlayerSample();
@@ -18,7 +18,7 @@ index 11cacb26ce260373476dad764014ba1852477831..981f63b75584dbcb4bb0d5672e8c8bb1
for (final ServerLevel world : this.worlds) {
this.globalTick(world, tickCount);
diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
index 02c004bc7f9a0203523ce4b27cd766d6bdc478c0..3d86e21198f2888422330b6f7c27712f40a6aabc 100644
index 97c514673a454b752ab86b944fd143725ca8090d..ba91d40d6d91588a4b39abfefcb17a362bfc5490 100644
--- a/io/papermc/paper/threadedregions/TickRegions.java
+++ b/io/papermc/paper/threadedregions/TickRegions.java
@@ -190,6 +190,8 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
@@ -31,7 +31,7 @@ index 02c004bc7f9a0203523ce4b27cd766d6bdc478c0..3d86e21198f2888422330b6f7c27712f
private final Reference2ReferenceOpenHashMap<RegionizedData<?>, Object> regionizedData = new Reference2ReferenceOpenHashMap<>();
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 89f61f5715942d2b521e04b9fdc8b1b379c0c957..2c2487e1c1c65438119a13bd705a9e44697955ed 100644
index 9800ae1d3c49800b0c7342d43d696109b5b72cf4..f9a8c79640ed6ca381e4482eaeab6b23db59419f 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -299,7 +299,11 @@ public class Commands {
@@ -48,10 +48,10 @@ index 89f61f5715942d2b521e04b9fdc8b1b379c0c957..2c2487e1c1c65438119a13bd705a9e44
SaveOnCommand.register(this.dispatcher);
SetPlayerIdleTimeoutCommand.register(this.dispatcher);
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index ef898f5b60219be00471f9ea227103dfcea5b202..4991b8a925d9431d80f42a4480d76d6602a85347 100644
index ecdcf0db97341d2cb460f86f451cecd5c40dbfee..437abeb7b2d021b38b438d0e046f05809e196930 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1683,6 +1683,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1652,6 +1652,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia start - region threading
public void tickServer(final long startTime, final long scheduledEnd, final long targetBuffer,
final io.papermc.paper.threadedregions.TickRegions.TickRegionData region) {
@@ -64,10 +64,10 @@ index ef898f5b60219be00471f9ea227103dfcea5b202..4991b8a925d9431d80f42a4480d76d66
// Folia end - region threading
org.spigotmc.WatchdogThread.tick(); // Spigot
diff --git a/net/minecraft/server/commands/SaveAllCommand.java b/net/minecraft/server/commands/SaveAllCommand.java
index bc6d01996dde0870f6ebbda14176352777938a0c..8314d239435debf7aff947b7dd3bab83e3c80dc6 100644
index 299991905c24a7018f8ac60d0c16e56fa43cd710..39c1b67e457c26a7e8d87be21658bbe6e802440c 100644
--- a/net/minecraft/server/commands/SaveAllCommand.java
+++ b/net/minecraft/server/commands/SaveAllCommand.java
@@ -21,7 +21,9 @@ public class SaveAllCommand {
@@ -22,14 +22,21 @@ public class SaveAllCommand {
}
private static int saveAll(final CommandSourceStack source, final boolean flush) throws CommandSyntaxException {
@@ -78,13 +78,12 @@ index bc6d01996dde0870f6ebbda14176352777938a0c..8314d239435debf7aff947b7dd3bab83
MinecraftServer server = source.getServer();
boolean success = server.saveEverything(true, flush, true);
if (!success) {
@@ -29,6 +31,12 @@ public class SaveAllCommand {
} else {
source.sendSuccess(() -> Component.translatable("commands.save.success"), true);
return 1;
- }
+ }*/
+ return 1;
throw ERROR_FAILED.create();
}
- source.sendSuccess(() -> Component.translatable("commands.save.success"), true);
+ source.sendSuccess(() -> Component.translatable("commands.save.success"), true);*/
return Command.SINGLE_SUCCESS;
}
+
+ public static SimpleCommandExceptionType getErrorFailed() {
@@ -5,17 +5,19 @@ Subject: [PATCH] Add config to enable function command
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 2c2487e1c1c65438119a13bd705a9e44697955ed..6d27350cdb2e699fcc541bc96a5af06a09e0dfd5 100644
index f9a8c79640ed6ca381e4482eaeab6b23db59419f..1b2d3e2c23e8e03ae25e85a60b6ef0528e627f61 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -217,7 +217,9 @@ public class Commands {
@@ -217,7 +217,11 @@ public class Commands {
FillCommand.register(this.dispatcher, context);
FillBiomeCommand.register(this.dispatcher, context);
ForceLoadCommand.register(this.dispatcher);
- //FunctionCommand.register(this.dispatcher); // Folia - region threading - TODO
+ // Lophine start - Add config to enable function command
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.function) {
+ FunctionCommand.register(this.dispatcher); // Folia - region threading - TODO
+ }
+ // Lophine end - Add config to enable function command
GameModeCommand.register(this.dispatcher);
GameRuleCommand.register(this.dispatcher, context);
GiveCommand.register(this.dispatcher, context);
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to enable scoreboard command
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 6d27350cdb2e699fcc541bc96a5af06a09e0dfd5..01784d3feaa0dce02f0c26b9a635877b735e6abf 100644
index 1b2d3e2c23e8e03ae25e85a60b6ef0528e627f61..916b5c8d524ffd7ccb953fe0f1cf020a1ea8dafb 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -244,7 +244,11 @@ public class Commands {
@@ -246,7 +246,11 @@ public class Commands {
RotateCommand.register(this.dispatcher);
SayCommand.register(this.dispatcher);
//ScheduleCommand.register(this.dispatcher); // Folia - region threading
@@ -17,7 +17,7 @@ index 6d27350cdb2e699fcc541bc96a5af06a09e0dfd5..01784d3feaa0dce02f0c26b9a635877b
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.scoreboard) {
+ ScoreboardCommand.register(this.dispatcher, context); // Folia - region threading
+ }
+ // Lophine start - Add a config to enable scoreboard command
+ // Lophine end - Add a config to enable scoreboard command
SeedCommand.register(this.dispatcher, commandSelection != Commands.CommandSelection.INTEGRATED);
VersionCommand.register(this.dispatcher, commandSelection != Commands.CommandSelection.INTEGRATED);
SetBlockCommand.register(this.dispatcher, context);
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to enable trigger command
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 01784d3feaa0dce02f0c26b9a635877b735e6abf..bb5059a77741bf1d9e73bd8c7f0da6681ec63f67 100644
index 916b5c8d524ffd7ccb953fe0f1cf020a1ea8dafb..03f3fe221b14f0317947d74e25049bcce2ebeb66 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -272,7 +272,11 @@ public class Commands {
@@ -274,7 +274,11 @@ public class Commands {
// Luminol end - Add a config to enable tick command
TimeCommand.register(this.dispatcher, context);
TitleCommand.register(this.dispatcher, context);
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to enable raytracing tracker
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 0c0775bbb0c0ba0c37d1b884bb106b5250e94750..0dfb25ad032429a2aea7aa441dd5fd1848a6c617 100644
index 849ad46b2941ebba91b428846b3b20d11ee5e1c9..6cd549849bd7fb5d72431f729229d1e967cf0d98 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -1350,7 +1350,7 @@ public class ChunkMap extends SimpleRegionStorage implements ChunkHolder.PlayerP
@@ -18,10 +18,10 @@ index 0c0775bbb0c0ba0c37d1b884bb106b5250e94750..0dfb25ad032429a2aea7aa441dd5fd18
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
if (rangeY != -1) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 552fd994ee30deb6e9f4228b17a2883cf26b164c..6f7e5d62901733df08c6beafbda2e54bc1c5f917 100644
index 65e2229f73a6f74c2271c9326aeb46feab51f818..b7cc122d45ecaf922ca1aca8ff5f1632965ad357 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -167,7 +167,7 @@ public abstract class Entity
@@ -164,7 +164,7 @@ public abstract class Entity
ItemOwner,
SlotProvider,
DebugValueSource,
@@ -30,10 +30,11 @@ index 552fd994ee30deb6e9f4228b17a2883cf26b164c..6f7e5d62901733df08c6beafbda2e54b
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
static boolean isLevelAtLeast(ValueInput input, int level) {
@@ -6432,4 +6432,46 @@ public abstract class Entity
// Paper end - Expose entity id counter
@@ -6505,4 +6505,48 @@ public abstract class Entity
// Paper end
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
+ // Lophine start - Add config to enable raytracing tracker
+
+ private long lasttime = 0;
+ private boolean culled = false;
@@ -76,26 +77,29 @@ index 552fd994ee30deb6e9f4228b17a2883cf26b164c..6f7e5d62901733df08c6beafbda2e54b
+ return this.outOfCamera;
+ }
+
+ // Lophine end - Add config to enable raytracing tracker
}
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
index cb0a52dc3795e1cf54069bcbe82abf7877a658b8..1440946665f41ebf534d701515f982bbbf4c9686 100644
index 6efaa78faca15c7a48bdffb24480d1bac29f3ba8..8a328a41673a3d720f0b1a5de8ce049e360fac1b 100644
--- a/net/minecraft/world/entity/EntityType.java
+++ b/net/minecraft/world/entity/EntityType.java
@@ -1252,6 +1252,9 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T>,
@@ -84,6 +84,11 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T>,
public final int passengerTickTimerId;
public final int passengerInactiveTickTimerId;
// Folia end - profiler
+ // Lophine start - Add config to enable raytracing tracker
+ // Luminol - Raytracing entity tracker
+ public boolean skipRaytracningCheck = false;
+ // Luminol end
+ // Lophine end - Add config to enable raytracing tracker
public EntityType(
final EntityType.EntityFactory<T> factory,
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index b9cc33198efceb75dfef333c018b1296944451cb..f6f6d21f3393a3ab79a84212b0d66d83d0e817f1 100644
index 9fdc8134fdde2cdd7724a459a29e51f4ad943403..c6fa9dff800b1491b1e0fc5d7e1dc16b99b8c7db 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -185,6 +185,25 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -186,6 +186,25 @@ public abstract class Player extends Avatar implements ContainerUser {
return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity();
}
// CraftBukkit end
@@ -120,8 +124,8 @@ index b9cc33198efceb75dfef333c018b1296944451cb..f6f6d21f3393a3ab79a84212b0d66d83
+ // Luminol end
public Player(final Level level, final GameProfile gameProfile) {
super(EntityType.PLAYER, level);
@@ -240,6 +259,26 @@ public abstract class Player extends Avatar implements ContainerUser {
super(EntityTypes.PLAYER, level);
@@ -245,6 +264,26 @@ public abstract class Player extends Avatar implements ContainerUser {
@Override
public void tick() {
@@ -148,7 +152,7 @@ index b9cc33198efceb75dfef333c018b1296944451cb..f6f6d21f3393a3ab79a84212b0d66d83
this.noPhysics = this.isSpectator();
if (this.isSpectator() || this.isPassenger()) {
this.setOnGround(false);
@@ -1352,6 +1391,7 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -1378,6 +1417,7 @@ public abstract class Player extends Avatar implements ContainerUser {
if (this.hasContainerOpen()) {
this.doCloseContainer();
}
@@ -5,10 +5,10 @@ Subject: [PATCH] Add tick rate support
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
index 981f63b75584dbcb4bb0d5672e8c8bb140c52f9d..6e8ee04967afa410ce9dccff34bf9a43201694fd 100644
index 79ef1e69ec364beec69b37c6850c038cdba73b4c..6fb3c88463ff69bddb7d8dcde0e5339567d3e1c6 100644
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
@@ -371,6 +371,14 @@ public final class RegionizedServer {
@@ -272,6 +272,14 @@ public final class RegionizedServer {
this.globalTick(world, tickCount);
}
@@ -24,7 +24,7 @@ index 981f63b75584dbcb4bb0d5672e8c8bb140c52f9d..6e8ee04967afa410ce9dccff34bf9a43
this.tickConnections();
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
index f60b3b40c7dc5820abc726abc8d094ed873edf6c..917d6965e91527fc79d545c041765f78a357eac2 100644
index 5f4f80c1d4003254fd840f71d86908603b57bfa2..57a35d7a801621fc461e896eb2bba533d9d5bc1b 100644
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
@@ -40,8 +40,8 @@ public final class TickRegionScheduler {
@@ -38,7 +38,7 @@ index f60b3b40c7dc5820abc726abc8d094ed873edf6c..917d6965e91527fc79d545c041765f78
// Folia start - watchdog
public static final FoliaWatchdogThread WATCHDOG_THREAD = new FoliaWatchdogThread();
static {
@@ -528,8 +528,24 @@ public final class TickRegionScheduler {
@@ -509,8 +509,24 @@ public final class TickRegionScheduler {
final long cpuStart = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L;
final long tickStart = System.nanoTime();
@@ -61,12 +61,12 @@ index f60b3b40c7dc5820abc726abc8d094ed873edf6c..917d6965e91527fc79d545c041765f78
+ // use max(), don't assume that tickStart >= scheduledStart
+ tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
+ }
+ // Lophine end - Add tick command support
+ // Lophine end - Add a config to enable tick command
if (!this.tryMarkTicking()) {
if (!this.cancelled.get()) {
diff --git a/net/minecraft/server/ServerTickRateManager.java b/net/minecraft/server/ServerTickRateManager.java
index 8d0f810100a4eac65831913feeb9a9eeb0e6006a..ca35415e152dc63cb9f4ae8da8b06766600922fd 100644
index eeb2f88723b37bb3cada04bf3098dd46f0ed7316..8432d0ce22ddc9c9bfa98901e403697f40e53c99 100644
--- a/net/minecraft/server/ServerTickRateManager.java
+++ b/net/minecraft/server/ServerTickRateManager.java
@@ -110,7 +110,7 @@ public class ServerTickRateManager extends TickRateManager {
@@ -92,10 +92,10 @@ index 8d0f810100a4eac65831913feeb9a9eeb0e6006a..ca35415e152dc63cb9f4ae8da8b06766
this.sprintTimeSpend = this.sprintTimeSpend + (System.nanoTime() - this.sprintTickStartTime);
}
diff --git a/net/minecraft/server/commands/TickCommand.java b/net/minecraft/server/commands/TickCommand.java
index cae943bae4701f74b46a49d68da83ae797841590..d8f5f1b2f75a4e23556fb016ad47f2cefe1309ce 100644
index 64b685b219b930a1bb7f85db9947f4d1ca9df093..4421658e4061299dea2ff72a77506214cc9045d8 100644
--- a/net/minecraft/server/commands/TickCommand.java
+++ b/net/minecraft/server/commands/TickCommand.java
@@ -14,7 +14,7 @@ import net.minecraft.server.ServerTickRateManager;
@@ -15,7 +15,7 @@ import net.minecraft.server.ServerTickRateManager;
import net.minecraft.util.TimeUtil;
public class TickCommand {
@@ -104,12 +104,12 @@ index cae943bae4701f74b46a49d68da83ae797841590..d8f5f1b2f75a4e23556fb016ad47f2ce
private static final String DEFAULT_TICKRATE = String.valueOf(20);
public static void register(final CommandDispatcher<CommandSourceStack> dispatcher) {
@@ -22,14 +22,14 @@ public class TickCommand {
@@ -23,14 +23,14 @@ public class TickCommand {
Commands.literal("tick")
.requires(Commands.hasPermission(Commands.LEVEL_ADMINS))
.then(Commands.literal("query").executes(c -> tickQuery(c.getSource())))
-/* .then(
+ .then(
+ .then( // Lophine - Add tick rate support
Commands.literal("rate")
.then(
Commands.argument("rate", FloatArgumentType.floatArg(1.0F, 10000.0F))
@@ -9,10 +9,10 @@ individual items may never reach their destination.
This configuration option is added to fix this behavior.
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
index aed1641b4e09384d40da1ac6e66c1641ca34b063..44b06b1585e7630fa17d8dfb01f737b14efebcbc 100644
index 6f5d3ebb7adc567e5106a3c76fccdbee93f51c27..b1d5d59718e5748b164f0885d4152e795c5d572d 100644
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -287,7 +287,7 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
@@ -289,7 +289,7 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
ItemStack thisItemStack = this.getItem();
ItemStack otherItemStack = other.getItem();
if (Objects.equals(this.target, other.target) && areMergable(thisItemStack, otherItemStack)) {
@@ -5,15 +5,15 @@ Subject: [PATCH] Old zombie reinforcement
diff --git a/net/minecraft/world/entity/monster/zombie/Zombie.java b/net/minecraft/world/entity/monster/zombie/Zombie.java
index 0008aa0ca02fc4ea67b795b3f0a0e9656233ce89..2734ffc103ee4760d3521609fdd090ab99df675b 100644
index aa0a34e3bae3c0d81bc87577570340d1efc46c2b..c913cd25cf7a0eb625bc02845bf4af4f7c1a96ab 100644
--- a/net/minecraft/world/entity/monster/zombie/Zombie.java
+++ b/net/minecraft/world/entity/monster/zombie/Zombie.java
@@ -331,7 +331,7 @@ public class Zombie extends Monster {
int x = Mth.floor(this.getX());
int y = Mth.floor(this.getY());
int z = Mth.floor(this.getZ());
- EntityType<? extends Zombie> type = this.getType();
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.function.OldFeatureConfig.oldZombieReinforcement ? EntityType.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
Zombie reinforcement = type.create(level, EntitySpawnReason.REINFORCEMENT);
if (reinforcement == null) {
return true;
@@ -333,7 +333,7 @@ public class Zombie extends Monster {
int x = Mth.floor(this.getX());
int y = Mth.floor(this.getY());
int z = Mth.floor(this.getZ());
- EntityType<? extends Zombie> type = this.getType();
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.function.OldFeatureConfig.oldZombieReinforcement ? EntityTypes.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
Zombie reinforcement = type.create(level, EntitySpawnReason.REINFORCEMENT);
if (reinforcement == null) {
return true;
@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Thu, 2 Jul 2026 18:49:40 +0800
Subject: [PATCH] Old leader zombie health logic
diff --git a/net/minecraft/world/entity/monster/zombie/Zombie.java b/net/minecraft/world/entity/monster/zombie/Zombie.java
index c913cd25cf7a0eb625bc02845bf4af4f7c1a96ab..446559f235df246e7235d2cf507cdbef82349cc4 100644
--- a/net/minecraft/world/entity/monster/zombie/Zombie.java
+++ b/net/minecraft/world/entity/monster/zombie/Zombie.java
@@ -596,7 +596,7 @@ public class Zombie extends Monster {
.addOrReplacePermanentModifier(
new AttributeModifier(LEADER_ZOMBIE_BONUS_ID, this.random.nextDouble() * 3.0 + 1.0, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL)
);
- if (spawnReason != EntitySpawnReason.CONVERSION && spawnReason != EntitySpawnReason.LOAD && spawnReason != EntitySpawnReason.DIMENSION_TRAVEL) {
+ if (!fun.bm.lophine.config.modules.function.OldFeatureConfig.oldLeaderZombieHealth && spawnReason != EntitySpawnReason.CONVERSION && spawnReason != EntitySpawnReason.LOAD && spawnReason != EntitySpawnReason.DIMENSION_TRAVEL) { // Lophine - Configurable option to disable health boost for leader zombies
this.setHealth(this.getMaxHealth());
}
@@ -5,10 +5,10 @@ Subject: [PATCH] Spawn invulnerable time
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 5f1fad59a26e3fe29f9000a92be5d6c4422dcd01..f3afab1100a35cc9ab091944de93d1f30ef040a7 100644
index 93c76c2faf75bf4901ecaba1e04d957d5ddddfca..2985d5e2dde049a999a39f6edbb6696332f6d822 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -242,6 +242,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -245,6 +245,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
private int lastSentFood = -99999999;
private boolean lastFoodSaturationZero = true;
public int lastSentExp = -99999999;
@@ -16,7 +16,7 @@ index 5f1fad59a26e3fe29f9000a92be5d6c4422dcd01..f3afab1100a35cc9ab091944de93d1f3
private ChatVisiblity chatVisibility = ChatVisiblity.FULL;
public ParticleStatus particleStatus = ParticleStatus.ALL;
private boolean canChatColor = true;
@@ -920,6 +921,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -902,6 +903,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.connection.tickClientLoadTimeout();
this.gameMode.tick();
this.wardenSpawnTracker.tick();
@@ -24,17 +24,17 @@ index 5f1fad59a26e3fe29f9000a92be5d6c4422dcd01..f3afab1100a35cc9ab091944de93d1f3
if (this.invulnerableTime > 0) {
this.invulnerableTime--;
}
@@ -1556,6 +1558,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
if (this.isInvulnerableTo(level, source)) {
@@ -1532,6 +1534,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
return false;
} else {
+ // Lophine start - spawn invulnerable time
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.spawnInvulnerableTime) {
+ if (this.spawnInvulnerableTime > 0 && !source.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
+ return false;
+ }
}
+ // Lophine start - spawn invulnerable time
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.spawnInvulnerableTime) {
+ if (this.spawnInvulnerableTime > 0 && !source.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
+ return false;
+ }
+ // Lophine end - spawn invulnerable time
Entity entity = source.getEntity();
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
!(entity instanceof Player playerx && !this.canHarmPlayer(playerx))
+ }
+ // Lophine end - spawn invulnerable time
Entity entity = source.getEntity();
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
!(entity instanceof Player player && !this.canHarmPlayer(player))
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/f3784ec0525069a37
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/commands/arguments/item/ItemInput.java b/net/minecraft/commands/arguments/item/ItemInput.java
index 28aab52fb14e9086d81dd7a3fa32e7f12136d53a..1f033b970be82b0bdb4e51b6e1c5bb03170066ae 100644
index 0dce216ae73c85dd69056bec7ef60b5e4364f23b..9ce6305e9fea9edcd3b1b853070d9990e00a667b 100644
--- a/net/minecraft/commands/arguments/item/ItemInput.java
+++ b/net/minecraft/commands/arguments/item/ItemInput.java
@@ -20,8 +20,10 @@ public record ItemInput(Holder<Item> item, DataComponentPatch components) {
@@ -21,11 +21,11 @@ index 28aab52fb14e9086d81dd7a3fa32e7f12136d53a..1f033b970be82b0bdb4e51b6e1c5bb03
+ if (count > org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(result)) {
+ throw ERROR_STACK_TOO_BIG.create(this.item.getRegisteredName(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(result));
+ // Leaves end - item over-stack util
} else {
DataResult<ItemStack> validationResult = ItemStack.validateStrict(result);
return validationResult.getOrThrow(ERROR_MALFORMED_ITEM::create);
}
DataResult<ItemStack> validationResult = ItemStack.validateStrict(result);
diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java
index c147a1acd4fd9f94c73bee69febf651ca00c28ce..f8004bf74edeabce871515fb73fa00f331941dca 100644
index be357d315f5c83349a7f7287ff45e92137950a8c..a542e38ea6a1e8fc81466acbca071d89832ba54a 100644
--- a/net/minecraft/server/commands/GiveCommand.java
+++ b/net/minecraft/server/commands/GiveCommand.java
@@ -47,7 +47,7 @@ public class GiveCommand {
@@ -38,10 +38,10 @@ index c147a1acd4fd9f94c73bee69febf651ca00c28ce..f8004bf74edeabce871515fb73fa00f3
if (count > maxAllowedCount) {
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", maxAllowedCount, prototypeItemStack.getDisplayName()));
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 15470867ed0f668fd3ba9c1fa24f84b3de8cb756..4f243a4d3143bae799619e2ec76366c961c62da6 100644
index fe6e1aea364620f82de44b942da0d3846c7d17b5..fd1ceb8c6f20b515e3a054050feeb443de33038c 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3229,7 +3229,7 @@ public class ServerGamePacketListenerImpl
@@ -3219,7 +3219,7 @@ public class ServerGamePacketListenerImpl
} else if (slot.mayPlace(cursor)) {
if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) {
int toPlace = packet.buttonNum() == 0 ? cursor.getCount() : 1;
@@ -50,7 +50,7 @@ index 15470867ed0f668fd3ba9c1fa24f84b3de8cb756..4f243a4d3143bae799619e2ec76366c9
toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount());
if (toPlace == 1) {
action = InventoryAction.PLACE_ONE;
@@ -3265,7 +3265,7 @@ public class ServerGamePacketListenerImpl
@@ -3255,7 +3255,7 @@ public class ServerGamePacketListenerImpl
}
} else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) {
if (clickedItem.getCount() >= 0) {
@@ -59,7 +59,7 @@ index 15470867ed0f668fd3ba9c1fa24f84b3de8cb756..4f243a4d3143bae799619e2ec76366c9
// As of 1.5, this is result slots only
action = InventoryAction.PICKUP_ALL;
}
@@ -3482,6 +3482,7 @@ public class ServerGamePacketListenerImpl
@@ -3472,6 +3472,7 @@ public class ServerGamePacketListenerImpl
this.player.containerMenu.broadcastFullState();
} else {
this.player.containerMenu.broadcastChanges();
@@ -67,7 +67,7 @@ index 15470867ed0f668fd3ba9c1fa24f84b3de8cb756..4f243a4d3143bae799619e2ec76366c9
}
if (packet.buttonNum() == Inventory.SLOT_OFFHAND && this.player.containerMenu != this.player.inventoryMenu) this.player.containerSynchronizer.sendOffHandSlotChange(); // Paper - update offhand data when the player is clicking in an inventory not their own as the sychronizer does not include offhand slots
if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
@@ -3593,7 +3594,7 @@ public class ServerGamePacketListenerImpl
@@ -3583,7 +3584,7 @@ public class ServerGamePacketListenerImpl
}
boolean validSlot = packet.slotNum() >= 1 && packet.slotNum() <= 45;
@@ -76,7 +76,7 @@ index 15470867ed0f668fd3ba9c1fa24f84b3de8cb756..4f243a4d3143bae799619e2ec76366c9
if (drop || (validSlot && !ItemStack.matches(this.player.inventoryMenu.getSlot(packet.slotNum()).getItem(), packet.itemStack()))) { // Insist on valid slot
// CraftBukkit start - Call click event
org.bukkit.inventory.InventoryView inventory = this.player.inventoryMenu.getBukkitView();
@@ -3635,6 +3636,7 @@ public class ServerGamePacketListenerImpl
@@ -3625,6 +3626,7 @@ public class ServerGamePacketListenerImpl
this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack);
this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack);
this.player.inventoryMenu.broadcastChanges();
@@ -85,10 +85,10 @@ index 15470867ed0f668fd3ba9c1fa24f84b3de8cb756..4f243a4d3143bae799619e2ec76366c9
} else if (drop && validData) {
if (this.dropSpamThrottler.isUnderThreshold()) {
diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java
index 54d99625cfec60530e8a3288871e6dc21e179b2d..2a1c1bd2e9c326b7298978cec1fe13112e670d33 100644
index dd2d0940eece3e85078e574f66f71a4c497d75fd..b3585aee0393142366e583fc2c8fb207f162e92b 100644
--- a/net/minecraft/world/Container.java
+++ b/net/minecraft/world/Container.java
@@ -38,6 +38,12 @@ public interface Container extends Clearable, Iterable<ItemStack>, SlotProvider,
@@ -37,6 +37,12 @@ public interface Container extends Clearable, Iterable<ItemStack>, SlotProvider,
return Math.min(this.getMaxStackSize(), itemStack.getMaxStackSize());
}
@@ -102,7 +102,7 @@ index 54d99625cfec60530e8a3288871e6dc21e179b2d..2a1c1bd2e9c326b7298978cec1fe1311
boolean stillValid(Player player);
diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java
index 21f576bb39bfd78dca87606ba3a044db8e13e28e..049c6ab6472415479435f2caab0444c3cbd33902 100644
index 073a3bbf1b1db7eac83cf35412543f370fa089ee..0f412551685a8ea76be3b389e0782e57d22bb87c 100644
--- a/net/minecraft/world/SimpleContainer.java
+++ b/net/minecraft/world/SimpleContainer.java
@@ -193,7 +193,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
@@ -124,10 +124,10 @@ index 21f576bb39bfd78dca87606ba3a044db8e13e28e..049c6ab6472415479435f2caab0444c3
if (diff > 0) {
targetStack.grow(diff);
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
index 44b06b1585e7630fa17d8dfb01f737b14efebcbc..679a941a2af886697fbfcbc7f21e5f4e0ec77dc3 100644
index b1d5d59718e5748b164f0885d4152e795c5d572d..44a5be736ba73c065a5b1a5fffcf2ea4a21d89dd 100644
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -280,10 +280,15 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
@@ -282,10 +282,15 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
private boolean isMergable() {
ItemStack item = this.getItem();
@@ -145,7 +145,7 @@ index 44b06b1585e7630fa17d8dfb01f737b14efebcbc..679a941a2af886697fbfcbc7f21e5f4e
ItemStack otherItemStack = other.getItem();
if (Objects.equals(this.target, other.target) && areMergable(thisItemStack, otherItemStack)) {
diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java
index f004911c438e6f89d6e079437e3f4104d6cbacbd..a248b1d11303237ebdf7cac4fa63865287d91a10 100644
index cd7714dffcd7e7b6d96d18a97e65fd0914a739d1..fd38d7c34910ab9a60a9f54968901be3af2a9867 100644
--- a/net/minecraft/world/entity/player/Inventory.java
+++ b/net/minecraft/world/entity/player/Inventory.java
@@ -166,10 +166,12 @@ public class Inventory implements Container, Nameable {
@@ -190,7 +190,7 @@ index f004911c438e6f89d6e079437e3f4104d6cbacbd..a248b1d11303237ebdf7cac4fa638652
int toAdd = Math.min(count, maxToAdd);
if (toAdd == 0) {
return count;
@@ -421,7 +423,7 @@ public class Inventory implements Container, Nameable {
@@ -423,7 +425,7 @@ public class Inventory implements Container, Nameable {
break;
}
@@ -213,10 +213,10 @@ index 1ace17d8fc7e7b8b4722a1889d49233c0ec55e20..d146f02338852810679a45bff932d9d6
public void accountStack(final ItemStack itemStack, final int maxCount) {
diff --git a/net/minecraft/world/entity/vehicle/ContainerEntity.java b/net/minecraft/world/entity/vehicle/ContainerEntity.java
index 9c9a08752b54222e8ac8d9a38c7a28a775bd1164..42716cf2c864eba50628dc64c59ab29c1d51dc9b 100644
index c80a44dbc54e0bf00daa525bef20422b15ce8a85..d9daef9b2ccf0f0bbe61ff3d7a20f25193aabaf8 100644
--- a/net/minecraft/world/entity/vehicle/ContainerEntity.java
+++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java
@@ -161,7 +161,7 @@ public interface ContainerEntity extends Container, MenuProvider {
@@ -160,7 +160,7 @@ public interface ContainerEntity extends Container, MenuProvider {
default void setChestVehicleItem(final int slot, final ItemStack itemStack) {
this.unpackChestVehicleLootTable(null);
this.getItemStacks().set(slot, itemStack);
@@ -226,10 +226,10 @@ index 9c9a08752b54222e8ac8d9a38c7a28a775bd1164..42716cf2c864eba50628dc64c59ab29c
default @Nullable SlotAccess getChestVehicleSlot(final int slot) {
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea072e7ca7 100644
index c063694237c0c98ad370ac7fc170172f9ed3fb37..f6d37cba8ab5688501be9170720a0b6ded810819 100644
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -294,6 +294,14 @@ public abstract class AbstractContainerMenu {
@@ -293,6 +293,14 @@ public abstract class AbstractContainerMenu {
this.sendAllDataToRemote();
}
@@ -244,7 +244,7 @@ index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea
private void updateDataSlotListeners(final int id, final int currentValue) {
for (ContainerListener containerListener : this.containerListeners) {
containerListener.dataChanged(this, id, currentValue);
@@ -450,7 +458,7 @@ public abstract class AbstractContainerMenu {
@@ -449,7 +457,7 @@ public abstract class AbstractContainerMenu {
&& (this.quickcraftType == QUICKCRAFT_TYPE_CLONE || carriedItemStack.getCount() >= this.quickcraftSlots.size())
&& this.canDragTo(slot)) {
int carry = slot.hasItem() ? slot.getItem().getCount() : 0;
@@ -253,25 +253,26 @@ index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea
int newCount = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots.size(), this.quickcraftType, source) + carry, maxSize);
remaining -= newCount - carry;
// slot.setByPlayer(source.copyWithCount(newCount));
@@ -558,7 +566,7 @@ public abstract class AbstractContainerMenu {
slotx.setByPlayer(carried);
@@ -557,7 +565,7 @@ public abstract class AbstractContainerMenu {
slot.setByPlayer(carried);
}
} else if (ItemStack.isSameItemSameComponents(clicked, carried)) {
- Optional<ItemStack> newCarried = slotx.tryRemove(clicked.getCount(), carried.getMaxStackSize() - carried.getCount(), player);
+ Optional<ItemStack> newCarried = slotx.tryRemove(clicked.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried) - carried.getCount(), player); // Leaves - item over-stack util
- Optional<ItemStack> newCarried = slot.tryRemove(clicked.getCount(), carried.getMaxStackSize() - carried.getCount(), player);
+ Optional<ItemStack> newCarried = slot.tryRemove(clicked.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried) - carried.getCount(), player); // Leaves - item over-stack util
newCarried.ifPresent(itemsTaken -> {
carried.grow(itemsTaken.getCount());
slotx.onTake(player, itemsTaken);
@@ -620,7 +628,7 @@ public abstract class AbstractContainerMenu {
Slot slotx = this.slots.get(slotIndex);
if (slotx.hasItem()) {
ItemStack item = slotx.getItem();
- this.setCarried(item.copyWithCount(item.getMaxStackSize()));
slot.onTake(player, itemsTaken);
@@ -618,7 +626,8 @@ public abstract class AbstractContainerMenu {
} else if (containerInput == ContainerInput.CLONE && player.hasInfiniteMaterials() && this.getCarried().isEmpty() && slotIndex >= 0) {
Slot slot = this.slots.get(slotIndex);
if (slot.hasItem()) {
- this.setCarried(slot.safeClone(player));
+ ItemStack item = slot.getItem();
+ this.setCarried(item.copyWithCount(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item))); // Leaves - item over-stack util
}
} else if (containerInput == ContainerInput.THROW && this.getCarried().isEmpty() && slotIndex >= 0) {
Slot slotx = this.slots.get(slotIndex);
@@ -655,15 +663,15 @@ public abstract class AbstractContainerMenu {
Slot slot = this.slots.get(slotIndex);
@@ -653,15 +662,15 @@ public abstract class AbstractContainerMenu {
int step = buttonNum == 0 ? 1 : -1;
for (int pass = 0; pass < 2; pass++) {
@@ -290,7 +291,7 @@ index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea
carried.grow(removed.getCount());
}
}
@@ -770,7 +778,7 @@ public abstract class AbstractContainerMenu {
@@ -764,7 +773,7 @@ public abstract class AbstractContainerMenu {
destSlot = endSlot - 1;
}
@@ -299,7 +300,7 @@ index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea
while (!itemStack.isEmpty() && (backwards ? destSlot >= startSlot : destSlot < endSlot)) {
Slot slot = this.slots.get(destSlot);
ItemStack target = slot.getItem();
@@ -871,7 +879,7 @@ public abstract class AbstractContainerMenu {
@@ -865,7 +874,7 @@ public abstract class AbstractContainerMenu {
public static boolean canItemQuickReplace(final @Nullable Slot slot, final ItemStack itemStack, final boolean ignoreSize) {
boolean slotIsEmpty = slot == null || !slot.hasItem();
return !slotIsEmpty && ItemStack.isSameItemSameComponents(itemStack, slot.getItem())
@@ -308,7 +309,7 @@ index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea
: slotIsEmpty;
}
@@ -879,7 +887,7 @@ public abstract class AbstractContainerMenu {
@@ -873,7 +882,7 @@ public abstract class AbstractContainerMenu {
return switch (quickCraftingType) {
case 0 -> Mth.floor((float)itemStack.getCount() / quickCraftSlotsSize);
case 1 -> 1;
@@ -317,17 +318,17 @@ index 4a177b4e714ba52cc18024d1233c9425afb93741..fa1f7dd22959632aaa54e72c8caf13ea
default -> itemStack.getCount();
};
}
@@ -902,7 +910,7 @@ public abstract class AbstractContainerMenu {
for (int i = 0; i < container.getContainerSize(); i++) {
ItemStack itemStack = container.getItem(i);
if (!itemStack.isEmpty()) {
- totalPercent += (float)itemStack.getCount() / container.getMaxStackSize(itemStack);
+ totalPercent += org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackSignalStrength(container.getMaxStackSize(), itemStack); // Leaves - item over-stack util
}
@@ -897,7 +906,7 @@ public abstract class AbstractContainerMenu {
for (int i = 0; i < container.getContainerSize(); i++) {
ItemStack itemStack = container.getItem(i);
if (!itemStack.isEmpty()) {
- totalPercent += (float)itemStack.getCount() / container.getMaxStackSize(itemStack);
+ totalPercent += org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackSignalStrength(container.getMaxStackSize(), itemStack); // Leaves - item over-stack util
}
}
diff --git a/net/minecraft/world/inventory/MerchantContainer.java b/net/minecraft/world/inventory/MerchantContainer.java
index e1b1a261a5f7a3702c1788daa38e7d367195382e..cb95fa63c585b1c3859bfd3e5d4d0e5dd84c7f0d 100644
index 7c2ab4868dc5bed6a2e444975ef48c68e9a0b6cf..a3500c25b519d7bcff673212eb88d11cee564f53 100644
--- a/net/minecraft/world/inventory/MerchantContainer.java
+++ b/net/minecraft/world/inventory/MerchantContainer.java
@@ -108,7 +108,7 @@ public class MerchantContainer implements Container {
@@ -340,7 +341,7 @@ index e1b1a261a5f7a3702c1788daa38e7d367195382e..cb95fa63c585b1c3859bfd3e5d4d0e5d
this.updateSellItem();
}
diff --git a/net/minecraft/world/inventory/Slot.java b/net/minecraft/world/inventory/Slot.java
index ee86a63c8d0d4c798ad09da87598d22c0e516840..57061d97bd368bfe934157293471fd546bb105ee 100644
index 0e86b025bad2c336cc360c2ce764dad0a75de1b6..1873b9376df57ff73d2a1583b60a512cfff7b998 100644
--- a/net/minecraft/world/inventory/Slot.java
+++ b/net/minecraft/world/inventory/Slot.java
@@ -75,7 +75,7 @@ public class Slot {
@@ -353,10 +354,10 @@ index ee86a63c8d0d4c798ad09da87598d22c0e516840..57061d97bd368bfe934157293471fd54
public @Nullable Identifier getNoItemIcon() {
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index 718a7786d73852368b6e911716fb494cc4770ef1..61466aa6d11af2858fa2898ef5b4b7515f4365df 100644
index a6805d436fd3675e385cbf8a3e5b262ae694ed90..f15ee24339b04e4fe395755bf3503c17886f1782 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -160,7 +160,7 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
@@ -159,7 +159,7 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
private int popTime;
@Deprecated
private @Nullable Holder<Item> item;
@@ -366,17 +367,17 @@ index 718a7786d73852368b6e911716fb494cc4770ef1..61466aa6d11af2858fa2898ef5b4b751
public static DataResult<ItemStack> validateStrict(final ItemStack itemStack) {
DataResult<?> result = validateComponents(itemStack.getComponents());
@@ -185,7 +185,8 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
} else {
Holder<Item> item = Item.STREAM_CODEC.decode(input);
DataComponentPatch patch = patchCodec.decode(input);
- return new ItemStack(item, count, patch);
+ ItemStack stack = new ItemStack(item, count, patch);
+ return org.leavesmc.leaves.util.ItemOverstackUtils.decodeMaxStackSize(stack); // Leaves - item over-stack util
}
Holder<Item> item = Item.STREAM_CODEC.decode(input);
DataComponentPatch patch = patchCodec.decode(input);
- return new ItemStack(item, count, patch);
+ ItemStack stack = new ItemStack(item, count, patch);
+ return org.leavesmc.leaves.util.ItemOverstackUtils.decodeMaxStackSize(stack); // Leaves - item over-stack util
}
@@ -194,17 +195,20 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
if (itemStack.isEmpty() || itemStack.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem()
@Override
@@ -193,17 +194,20 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
if (itemStack.isEmpty()) {
output.writeVarInt(0);
} else {
- output.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), itemStack, itemStack.getCount())); // Paper - potentially sanitize count
@@ -401,10 +402,10 @@ index 718a7786d73852368b6e911716fb494cc4770ef1..61466aa6d11af2858fa2898ef5b4b751
}
};
diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java
index 15ed625105539f402fb39275b292531fe388a7a0..2b97fd6af1c4956eb173b8c66c2a3efc8772a798 100644
index f0756f3d277103f95e4d5213b5ae788025b72f42..08c67084b5347bb1d6e65f17f3365ff33b542ec0 100644
--- a/net/minecraft/world/level/block/CrafterBlock.java
+++ b/net/minecraft/world/level/block/CrafterBlock.java
@@ -202,7 +202,7 @@ public class CrafterBlock extends BaseEntityBlock {
@@ -203,7 +203,7 @@ public class CrafterBlock extends BaseEntityBlock {
Direction direction = blockState.getValue(ORIENTATION).front();
Container into = HopperBlockEntity.getContainerAt(level, pos.relative(direction));
ItemStack remaining = results.copy();
@@ -414,10 +415,10 @@ index 15ed625105539f402fb39275b292531fe388a7a0..2b97fd6af1c4956eb173b8c66c2a3efc
org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(remaining);
diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
index 72a258f046c67c8970c91b8da31c0e745ec1e7ae..86a13f11fa6730f85add3e2ff47781d0fbcae170 100644
index ac93d2992fe780133439302ce5b851f9ac0c7353..5c23f48a09a73145ecd2166229b5737c42801db0 100644
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
@@ -397,7 +397,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
@@ -395,7 +395,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
ItemStack oldStack = this.items.get(slot);
boolean same = !itemStack.isEmpty() && ItemStack.isSameItemSameComponents(oldStack, itemStack);
this.items.set(slot, itemStack);
@@ -427,7 +428,7 @@ index 72a258f046c67c8970c91b8da31c0e745ec1e7ae..86a13f11fa6730f85add3e2ff47781d0
this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API
this.cookingTimer = 0;
diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
index 65ca3c97fdd60ebbdd366673c81c4375488f0cde..a7a13fb017a4c98db7639b8d672f3ad9d7814b7f 100644
index b961ec1532937be513e12e5306a34e6cbff24aee..dbf29f7c085831ce0f62942dc4ea70913fae1b15 100644
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -134,7 +134,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
@@ -440,7 +441,7 @@ index 65ca3c97fdd60ebbdd366673c81c4375488f0cde..a7a13fb017a4c98db7639b8d672f3ad9
}
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 75a8c007ba710aa6e77ba3ed9ae5f7868894629d..d036018ee64995ee754296014888ee70c0ea5ab3 100644
index 18e6dd47b0525531bae56e0ab3c3846185470ce4..7d35b299533640338aeea6e5617942e89269d048 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -155,7 +155,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -24,10 +24,10 @@ index f58b10c7dec0d2b7dc2b3d1198539b74d13038f3..0a838a2015526dde2cb8d9006a71610e
if (raid == null || raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel()) {
player.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplification));
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5028e2ca9 100644
index 32e20979b9343efa6b5903c7b6baf351205654a0..4ddc34822e88b011f58c70ca4f14e7a17912b714 100644
--- a/net/minecraft/world/entity/raid/Raid.java
+++ b/net/minecraft/world/entity/raid/Raid.java
@@ -268,7 +268,7 @@ public class Raid {
@@ -269,7 +269,7 @@ public class Raid {
}
public boolean absorbRaidOmen(final ServerPlayer player) {
@@ -35,8 +35,8 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
+ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior
if (effect == null) {
return false;
} else {
@@ -345,7 +345,13 @@ public class Raid {
}
@@ -346,7 +346,13 @@ public class Raid {
}
if (shouldTryToFindSpawnPos) {
@@ -51,7 +51,7 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
}
if (this.raidCooldownTicks == 300 || this.raidCooldownTicks % 20 == 0) {
@@ -400,7 +406,14 @@ public class Raid {
@@ -401,7 +407,14 @@ public class Raid {
int attempt = 0;
while (this.shouldSpawnGroup()) {
@@ -67,7 +67,7 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
if (spawnPos != null) {
this.started = true;
this.spawnGroup(level, spawnPos);
@@ -412,7 +425,7 @@ public class Raid {
@@ -413,7 +426,7 @@ public class Raid {
attempt++;
}
@@ -76,7 +76,7 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit
this.stop();
break;
@@ -716,7 +729,7 @@ public class Raid {
@@ -717,7 +730,7 @@ public class Raid {
int spawnX = this.center.getX() + Mth.floor(Mth.cos(angle) * 32.0F * howFar) + this.random.nextInt(3) * Mth.floor(howFar);
int spawnZ = this.center.getZ() + Mth.floor(Mth.sin(angle) * 32.0F * howFar) + this.random.nextInt(3) * Mth.floor(howFar);
int spawnY = level.getHeight(Heightmap.Types.WORLD_SURFACE, spawnX, spawnZ);
@@ -85,7 +85,7 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
spawnPos.set(spawnX, spawnY, spawnZ);
if (!level.isVillage(spawnPos) || secondsRemaining <= 7) {
int delta = 10;
@@ -899,4 +912,42 @@ public class Raid {
@@ -900,4 +913,42 @@ public class Raid {
this.spawnsPerWaveBeforeBonus = spawnsPerWaveBeforeBonus;
}
}
@@ -95,7 +95,7 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
+ private BlockPos getRavagerSpawnLocation(final ServerLevel serverWorld, final int proximity, final int tries) {
+ int i = proximity == 0 ? 2 : 2 - proximity;
+ BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
+ net.minecraft.world.entity.SpawnPlacementType spawnLocation = net.minecraft.world.entity.SpawnPlacements.getPlacementType(EntityType.RAVAGER);
+ net.minecraft.world.entity.SpawnPlacementType spawnLocation = net.minecraft.world.entity.SpawnPlacements.getPlacementType(EntityTypes.RAVAGER);
+ for (int j = 0; j < tries; j++) {
+ float f = serverWorld.getRandom().nextFloat() * (float) (Math.PI * 2);
+ int k = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0F * (float) i + serverWorld.getRandom().nextInt(5));
@@ -107,7 +107,7 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
+ }
+ if (serverWorld.hasChunksAt(mutable.getX() - 10, mutable.getZ() - 10, mutable.getX() + 10, mutable.getZ() + 10)
+ && serverWorld.isPositionEntityTicking(mutable)
+ && (spawnLocation.isSpawnPositionOk(serverWorld, mutable, EntityType.RAVAGER)
+ && (spawnLocation.isSpawnPositionOk(serverWorld, mutable, EntityTypes.RAVAGER)
+ || serverWorld.getBlockState(mutable.below()).is(net.minecraft.world.level.block.Blocks.SNOW)
+ && serverWorld.getBlockState(mutable).isAir())
+ ) {
@@ -129,10 +129,10 @@ index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5
+ // Leaves end - old FindSpawnPosition
}
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
index bc2edc48ddefaab9022029f1a913a40b72e06024..1a51da9171c13711e106731c360051d183a40893 100644
index 7e969cd81d2ac788515f4d9ad7584ade4c684a42..7555f0c5edf6a5419018203487cf8941e8095cb5 100644
--- a/net/minecraft/world/entity/raid/Raider.java
+++ b/net/minecraft/world/entity/raid/Raider.java
@@ -128,6 +128,42 @@ public abstract class Raider extends PatrollingMonster {
@@ -129,6 +129,42 @@ public abstract class Raider extends PatrollingMonster {
raidWhenKilled.removeFromRaid(serverLevel, this, false);
}
@@ -6,11 +6,11 @@ Subject: [PATCH] Compatibility fix for Raid Revert and Cross Region Damage
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 29919b8f3c05c8ffaf66f86e441778eeefb293b1..1e820f34636f415ef78cdfbed06c6952a3cf1c0b 100644
index 5762eed9e99d918bee02d77c0ddd70be0aa0e2ec..cb1589e3aa663ca058fb5c3a24da700d4482cf35 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -1234,6 +1234,30 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
}
@@ -1231,6 +1231,30 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
return changed;
}
+ // Lophine Start - raid revert adapt Cross Region Damage trace
@@ -41,10 +41,10 @@ index 29919b8f3c05c8ffaf66f86e441778eeefb293b1..1e820f34636f415ef78cdfbed06c6952
if (this.is(EntityTypeTags.IMMUNE_TO_INFESTED)) {
return !newEffect.is(MobEffects.INFESTED);
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
index 1a51da9171c13711e106731c360051d183a40893..7094a67959e9747b2dfa55a5f5a3e90552d35466 100644
index 7555f0c5edf6a5419018203487cf8941e8095cb5..44f8302a8c3fb867f122a97dc29f24a311f0ad91 100644
--- a/net/minecraft/world/entity/raid/Raider.java
+++ b/net/minecraft/world/entity/raid/Raider.java
@@ -158,7 +158,7 @@ public abstract class Raider extends PatrollingMonster {
@@ -159,7 +159,7 @@ public abstract class Raider extends PatrollingMonster {
net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, amp, false, false, true);
if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) {
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/9d2bd3f7b0a48f00d
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java b/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
index e9f86409bf9351e85ed31e747d9350dbf0cc441f..1f8f4d979d8766d6ba385f74cf8fcf8eea6c56c7 100644
index 08e253662a2c183c0ab53a51cc07485cff33bf2c..1bd678d668a1febc129f4cb4d0d95ea27acc4252 100644
--- a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
+++ b/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
@@ -40,13 +40,22 @@ public interface CustomPacketPayload {
@@ -36,10 +36,10 @@ index e9f86409bf9351e85ed31e747d9350dbf0cc441f..1f8f4d979d8766d6ba385f74cf8fcf8e
};
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 4991b8a925d9431d80f42a4480d76d6602a85347..9e290fa626caffac148920c54479a75ad0919e70 100644
index 437abeb7b2d021b38b438d0e046f05809e196930..2ccf454454582d53aee210917218c0867556181e 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -2037,6 +2037,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2006,6 +2006,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
profiler.popPush("server gui refresh");
@@ -49,7 +49,7 @@ index 4991b8a925d9431d80f42a4480d76d6602a85347..9e290fa626caffac148920c54479a75a
tickable.run();
}
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index cf4b5e436b8d81657d1deaa5b06645016d9dc3cc..f3af5660a377e2eb823f79ec274feaf3284761cd 100644
index d25c3f13a051ce6f2fbde30654eb9cdb8914b0ba..8d5a478f76ed98268ceb0ae19a438a3efea880b6 100644
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -57,6 +57,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -96,10 +96,10 @@ index cf4b5e436b8d81657d1deaa5b06645016d9dc3cc..f3af5660a377e2eb823f79ec274feaf3
bridge.removeChannel(channel);
}
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 527c495bb4f6007aee760b99cc0e9aa589931f4b..e6987eaf6e4d36d43cee4ece3ce22d31052a2a2a 100644
index 8b7e4814b00d6f6c9f25cce5186905f165b97c2f..5bfc986f3d8dc81444be857c857bd91ada8c409d 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -317,6 +317,8 @@ public abstract class PlayerList {
@@ -318,6 +318,8 @@ public abstract class PlayerList {
//return; // Folia - region threading - must still allow the player to connect, as we must add to chunk map before handling disconnect
}
@@ -108,7 +108,7 @@ index 527c495bb4f6007aee760b99cc0e9aa589931f4b..e6987eaf6e4d36d43cee4ece3ce22d31
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
@@ -517,6 +519,7 @@ public abstract class PlayerList {
@@ -514,6 +516,7 @@ public abstract class PlayerList {
return this.remove(player, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? player.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(player.getDisplayName())));
}
public net.kyori.adventure.text.@Nullable Component remove(final ServerPlayer player, final net.kyori.adventure.text.Component leaveMessage) {
@@ -116,7 +116,7 @@ index 527c495bb4f6007aee760b99cc0e9aa589931f4b..e6987eaf6e4d36d43cee4ece3ce22d31
// Paper end - Fix kick event leave message not being sent
ServerLevel level = player.level();
player.awardStat(Stats.LEAVE_GAME);
@@ -1411,6 +1414,7 @@ public abstract class PlayerList {
@@ -1417,6 +1420,7 @@ public abstract class PlayerList {
player.connection.send(recipes);
player.getRecipeBook().sendInitialRecipeBook(player);
}
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/9d2bd3f7b0a48f00d
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 047c605eb087667e10da557864ad931dadebd274..e9547fb9be40c3e999a9172acb48037595439396 100644
index 10b5783ec1220393e6f9c6233c6111654f5fd461..f001830e178d3c5d7ffb1486eae4b7c1d950e969 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -3158,7 +3158,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -3135,7 +3135,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
// Spigot start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
// Paper start - Fix merchant inventory not closing on entity removal
@@ -21,10 +21,10 @@ index 047c605eb087667e10da557864ad931dadebd274..e9547fb9be40c3e999a9172acb480375
}
// Paper end - Fix merchant inventory not closing on entity removal
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index e6987eaf6e4d36d43cee4ece3ce22d31052a2a2a..168702a5ae51a2bc42c5761e13cb14008a8162c4 100644
index 5bfc986f3d8dc81444be857c857bd91ada8c409d..ebcd7ce794ca696b44ab75dbb177beb5f929adf0 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -560,7 +560,7 @@ public abstract class PlayerList {
@@ -557,7 +557,7 @@ public abstract class PlayerList {
player.stopRiding();
vehicle.getPassengersAndSelf().forEach(e -> {
// Paper start - Fix villager boat exploit
@@ -34,7 +34,7 @@ index e6987eaf6e4d36d43cee4ece3ce22d31052a2a2a..168702a5ae51a2bc42c5761e13cb1400
if (human != null) {
villager.setTradingPlayer(null);
diff --git a/net/minecraft/world/inventory/MerchantMenu.java b/net/minecraft/world/inventory/MerchantMenu.java
index 1dd82dfa739957f00d51c8b987289a002815f622..85a329565119d376139a7449e538c0d83dfb079f 100644
index 5979e3856da1287f4513c984c0414952bfeb3ea2..d12db44b0fb165280642d2f6016869ce54f3a1db 100644
--- a/net/minecraft/world/inventory/MerchantMenu.java
+++ b/net/minecraft/world/inventory/MerchantMenu.java
@@ -74,6 +74,7 @@ public class MerchantMenu extends AbstractContainerMenu {
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/ServerTickRateManager.java b/net/minecraft/server/ServerTickRateManager.java
index ca35415e152dc63cb9f4ae8da8b06766600922fd..033715812acb8f98a7c7d895d115043e232d5161 100644
index 8432d0ce22ddc9c9bfa98901e403697f40e53c99..9ec141359c4422c1574dac71a88b7f5043350901 100644
--- a/net/minecraft/server/ServerTickRateManager.java
+++ b/net/minecraft/server/ServerTickRateManager.java
@@ -139,4 +139,10 @@ public class ServerTickRateManager extends TickRateManager {
@@ -23,10 +23,10 @@ index ca35415e152dc63cb9f4ae8da8b06766600922fd..033715812acb8f98a7c7d895d115043e
+ // Leaves end - servux
}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index e9547fb9be40c3e999a9172acb48037595439396..0ff635e6956a9935ad6d11e5c7bac189c51244b6 100644
index f001830e178d3c5d7ffb1486eae4b7c1d950e969..b03491230ed9b68e0e8f29719e34ea4b9947f408 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2584,6 +2584,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -2568,6 +2568,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
this.server.updateEffectiveRespawnData();
}
// Paper end
@@ -5,7 +5,7 @@ Subject: [PATCH] LeavesHooks
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
index d097b889499a8e410839e8f69d99dc9adfa2488b..b97d65b81ec4b86e00b7c06341b40dc5c02b9044 100644
index 08e3c75672e95248140eb0e0907cae5fbe54da34..dd17339fe2f9d7660b20eed05b61d6231302aa82 100644
--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -29,7 +29,7 @@ import net.minecraft.world.phys.AABB;
@@ -8,13 +8,13 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e96b237749a960f2
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
index 769dc39e11881d5f81a2405850cbcbd0842c5995..9fc97e8b01f66ada6af1fe76f4e27c9bb1a5dcfc 100644
index b712d7babed4941d11cf716133c8a07c5bcd51a3..b90077b44ce81d5d60f9d0ad2414f0b7c6b1e720 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -708,6 +708,7 @@ public class ServerExplosion implements Explosion {
public boolean shouldAffectBlocklikeEntities() {
boolean mobGriefingEnabled = this.level.getGameRules().get(GameRules.MOB_GRIEFING);
boolean isNotWindCharge = this.source == null || !this.source.is(EntityType.BREEZE_WIND_CHARGE) && !this.source.is(EntityType.WIND_CHARGE);
boolean isNotWindCharge = this.source == null || !this.source.is(EntityTypes.BREEZE_WIND_CHARGE) && !this.source.is(EntityTypes.WIND_CHARGE);
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldExplosionDamageCalculator) isNotWindCharge = isNotWindCharge && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage
return mobGriefingEnabled ? isNotWindCharge : this.blockInteraction.shouldAffectBlocklikeEntities() && isNotWindCharge;
}
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java
index 837f8c56bf5d68dd8bfbeca8ae1b66be8316ddea..1098695e646c20f47bc4739034fcb69b96909667 100644
index 9750a2a7f6d13f93119d0c6fba0bf11064d46e55..1913b30f1bfe013261b340fdf9917db90c98c695 100644
--- a/net/minecraft/world/item/ShearsItem.java
+++ b/net/minecraft/world/item/ShearsItem.java
@@ -80,7 +80,10 @@ public class ShearsItem extends Item {
@@ -9,15 +9,15 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 4f243a4d3143bae799619e2ec76366c961c62da6..e6c09a4b780dafbf55793fabf864f66aa6e5604d 100644
index fd1ceb8c6f20b515e3a054050feeb443de33038c..9ff62124dad00c4d9ba6de87f0cc21c25019acd4 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -346,9 +346,12 @@ public class ServerGamePacketListenerImpl
@@ -348,9 +348,12 @@ public class ServerGamePacketListenerImpl
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile);
this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat
this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event
+ this.exchangeTarget = new org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget(this); // Leaves - Syncmatica Protocol
this.playerGameConnection = new io.papermc.paper.connection.PaperPlayerGameConnection(this); // Paper
this.playerGameConnection = new io.papermc.paper.connection.PaperPlayerGameConnection(this); // Paper
}
+ public final org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget exchangeTarget; // Leaves - Syncmatica Protocol
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index da9706f866aabee6939cacbfbcc9def01fde0326..3708f9ffc46a5b1c038c0e7b2ce84802e2b22397 100644
index 3a727763cfee696c9fc87dda90260558936043bf..f4f56ec250b72df03f7e049250606c0e8b0f2990 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -772,6 +772,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
@@ -770,6 +770,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
public void setLoaded(final boolean loaded) {
this.loaded = loaded;
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 168702a5ae51a2bc42c5761e13cb14008a8162c4..ebd2f2887780d9c6c3c44983bac23eab732cf43f 100644
index ebcd7ce794ca696b44ab75dbb177beb5f929adf0..ca1e635b0fdf3d0d17447b43a558fe030536d297 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1105,6 +1105,7 @@ public abstract class PlayerList {
@@ -1107,6 +1107,7 @@ public abstract class PlayerList {
//player.connection.send(new ClientboundSetChunkCacheRadiusPacket(io.papermc.paper.FeatureHooks.getViewDistance(level))); // Paper - rewrite chunk system
//player.connection.send(new ClientboundSetSimulationDistancePacket(io.papermc.paper.FeatureHooks.getSimulationDistance(level))); // Paper - rewrite chunk system
// Paper end - view distances
@@ -25,7 +25,7 @@ index 33f9870a4f966a887023b1debd4ab9ef9d24378f..89983e7da244434a5346b23b49c74834
@Override
public org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id) {
diff --git a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
index f9fa7d0eaf9f32959a4bd12b82e5a49ea808a44c..2f3241563ad7e5ed5663b913671d2af056df97bb 100644
index 93347bd9fbab41888c5d63eb40e7928e74a1f9af..4f9e700ed621cdb556162174bbb9b219403fc05a 100644
--- a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
+++ b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
@@ -109,6 +109,12 @@ public class SmithingTrimRecipe extends SimpleSmithingRecipe {
@@ -9,10 +9,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index e6c09a4b780dafbf55793fabf864f66aa6e5604d..57e3180dc4568f58d5b69d2b9656d7cf9bbae81f 100644
index 9ff62124dad00c4d9ba6de87f0cc21c25019acd4..de3c09b26c28a1bc6012cff6f524f72332f7b1f0 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3902,7 +3902,7 @@ public class ServerGamePacketListenerImpl
@@ -3893,7 +3893,7 @@ public class ServerGamePacketListenerImpl
}
@Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add PlayerLoadedWorldEvent
@@ -22,10 +22,10 @@ index e6c09a4b780dafbf55793fabf864f66aa6e5604d..57e3180dc4568f58d5b69d2b9656d7cf
this.markClientLoaded(false);
}
diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
index 03ec05a860781f85e58055d6f58893963781bd97..c15f0a3d419fea50d4349fa864e83bf7fee78b9f 100644
index c8c50683597a2314a3c0e72888d5d75dc73fb94a..3663aa490106b05772574ae7c4ac9d4d84574e79 100644
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
@@ -72,7 +72,7 @@ public class Armadillo extends Animal {
@@ -75,7 +75,7 @@ public class Armadillo extends Animal {
public final AnimationState rollOutAnimationState = new AnimationState();
public final AnimationState rollUpAnimationState = new AnimationState();
public final AnimationState peekAnimationState = new AnimationState();
@@ -35,10 +35,10 @@ index 03ec05a860781f85e58055d6f58893963781bd97..c15f0a3d419fea50d4349fa864e83bf7
public Armadillo(final EntityType<? extends Animal> type, final Level level) {
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
index 3d4bfeae2fddb9ace26e7dea8870704d8309862b..d2862d2e6f599265bc319000bba05609e0bea2c3 100644
index 296cae1d5f5a3a054949ee03e2a2552bfeae4682..97c49875269dd52c6a4692940b122f1d1f3fd2fb 100644
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -255,7 +255,7 @@ public class Tadpole extends AbstractFish {
@@ -256,7 +256,7 @@ public class Tadpole extends AbstractFish {
}
}
@@ -48,10 +48,10 @@ index 3d4bfeae2fddb9ace26e7dea8870704d8309862b..d2862d2e6f599265bc319000bba05609
}
diff --git a/net/minecraft/world/level/storage/loot/LootPool.java b/net/minecraft/world/level/storage/loot/LootPool.java
index f08a25b76e689c2242e8ef8226c3d8c2dcec1c70..6e76e472bd1e7242f6cd7986c23ebc38d16fd46a 100644
index dde475b92375a484cb10a7de5a1256b0741ae5c6..c216b1e047a515a69a0974586a4cd0b536544c66 100644
--- a/net/minecraft/world/level/storage/loot/LootPool.java
+++ b/net/minecraft/world/level/storage/loot/LootPool.java
@@ -36,7 +36,7 @@ public class LootPool implements Validatable {
@@ -37,7 +37,7 @@ public class LootPool implements Validatable {
)
.apply(i, LootPool::new)
);
@@ -13,10 +13,10 @@ MasaGadget(https://github.com/plusls/MasaGadget)
litematica(https://github.com/maruohon/litematica)
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 57e3180dc4568f58d5b69d2b9656d7cf9bbae81f..96088ba53f043c8bc6971bc62e5dcccd98523698 100644
index de3c09b26c28a1bc6012cff6f524f72332f7b1f0..aec23bc77fc78eea6a3137b71a6923c217ad40a7 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2183,7 +2183,7 @@ public class ServerGamePacketListenerImpl
@@ -2162,7 +2162,7 @@ public class ServerGamePacketListenerImpl
if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.player.level(), pos.getX() >> 4, pos.getZ() >> 4, 8) && this.player.isWithinBlockInteractionRange(pos, 1.0)) { // Folia - do not allow players to interact with blocks outside the current region
Vec3 distance = location.subtract(Vec3.atCenterOf(pos));
double limit = 1.0000001;
@@ -26,10 +26,10 @@ index 57e3180dc4568f58d5b69d2b9656d7cf9bbae81f..96088ba53f043c8bc6971bc62e5dcccd
this.player.resetLastActionTime();
int maxY = level.getMaxY();
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
index 3167be4b7c2c61ef725af4a832d759ab6e061af0..2e2a8af12f249ec5bd0935fd13f5acbd0a777b5f 100644
index b94c4f0a6908a37d8a07dba6ff3ece7193aca1b5..0f4ac8eeb8f5f866b22a81f255f7169754437bfc 100644
--- a/net/minecraft/world/item/BlockItem.java
+++ b/net/minecraft/world/item/BlockItem.java
@@ -136,7 +136,7 @@ public class BlockItem extends Item {
@@ -140,7 +140,7 @@ public class BlockItem extends Item {
}
protected @Nullable BlockState getPlacementState(final BlockPlaceContext context) {
@@ -39,7 +39,7 @@ index 3167be4b7c2c61ef725af4a832d759ab6e061af0..2e2a8af12f249ec5bd0935fd13f5acbd
}
diff --git a/net/minecraft/world/item/StandingAndWallBlockItem.java b/net/minecraft/world/item/StandingAndWallBlockItem.java
index d5d499226d0b2c2adfae7bbb4c28c96c80411c44..cb0a4a9865df69e5504a86de6c144bc4450bd19a 100644
index bb352c44fa951367907ebe403c59f03f3c21786f..1f17f966882320b3a2ced50b3f73925cd0dfa14c 100644
--- a/net/minecraft/world/item/StandingAndWallBlockItem.java
+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java
@@ -26,14 +26,14 @@ public class StandingAndWallBlockItem extends BlockItem {
@@ -60,10 +60,10 @@ index d5d499226d0b2c2adfae7bbb4c28c96c80411c44..cb0a4a9865df69e5504a86de6c144bc4
stateForPlacement = possibleState;
break;
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
index c5f4e0570a82dfcc2ba88023f3301f69afa41cc5..30f7e8f5e3e9440713e36ee25c90150b6b93c6ff 100644
index 1af396a051cc47dccb973ca864cf1ec2e8b756ed..64066a091628ad00d914043ae7ecd8bd29d85e5e 100644
--- a/net/minecraft/world/level/block/Block.java
+++ b/net/minecraft/world/level/block/Block.java
@@ -516,6 +516,32 @@ public class Block extends BlockBehaviour implements ItemLike {
@@ -517,6 +517,32 @@ public class Block extends BlockBehaviour implements ItemLike {
public void stepOn(final Level level, final BlockPos pos, final BlockState onState, final Entity entity) {
}
@@ -7,20 +7,20 @@ Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java b/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java
index dfce5ced082de0caaff8da071fb632cd6ae787c9..d5c1862ebf6066859da74f47fa0be0256ba0f653 100644
--- a/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java
+++ b/net/minecraft/advancements/criterion/SimpleCriterionTrigger.java
@@ -41,6 +41,7 @@ public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.Si
}
diff --git a/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java b/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java
index d76a338ab4f326e6105adc451eee3d4601403c98..b827d51d23ceaebef2191a9f349bbd346e73f1af 100644
--- a/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java
+++ b/net/minecraft/advancements/triggers/SimpleCriterionTrigger.java
@@ -17,6 +17,7 @@ import net.minecraft.world.level.storage.loot.ValidationContextSource;
public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.SimpleInstance> implements CriterionTrigger<T> {
protected void trigger(final ServerPlayer player, final Predicate<T> matcher) {
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) return; // Leaves - bot skip
PlayerAdvancements advancements = player.getAdvancements();
Set<CriterionTrigger.Listener<T>> allListeners = (Set) advancements.criterionData.get(this); // Paper - fix PlayerAdvancements leak
if (allListeners != null && !allListeners.isEmpty()) {
Map<PlayerAdvancements.TriggerInstanceKey, T> listenersForType = advancements.getTriggerMapForType(this);
if (listenersForType != null && !listenersForType.isEmpty()) {
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
index efbbc1a40d203a2818eeda2a4e938b9a6117f1c3..6b85a5ad9af0c57a0d4d5b55f62b82c5ff69b0e8 100644
index d2e9d46bbd9ee4ce45419b11499d7a7bc50f0219..848967dbe41694411603ef369cfdc3a0b00240d3 100644
--- a/net/minecraft/network/Connection.java
+++ b/net/minecraft/network/Connection.java
@@ -74,7 +74,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
@@ -30,13 +30,13 @@ index efbbc1a40d203a2818eeda2a4e938b9a6117f1c3..6b85a5ad9af0c57a0d4d5b55f62b82c5
- private volatile @Nullable PacketListener packetListener;
+ protected volatile @Nullable PacketListener packetListener; // Leaves - private -> protected
private @Nullable DisconnectionDetails disconnectionDetails;
private boolean encrypted;
private final java.util.concurrent.atomic.AtomicBoolean disconnectionHandled = new java.util.concurrent.atomic.AtomicBoolean(false); // Folia - region threading - may be called concurrently during configuration stage
private int receivedPackets;
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4afe58f51 100644
index 2ccf454454582d53aee210917218c0867556181e..dd2a108f31bcbc1beae8c820c22baaa515fec7ec 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -297,6 +297,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -296,6 +296,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper - per-level scheduledEvents
private final ServerClockManager clockManager;
@@ -45,15 +45,15 @@ index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4
public static <S extends MinecraftServer> S spin(final Function<Thread, S> factory) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
AtomicReference<S> serverReference = new AtomicReference<>();
@@ -1226,6 +1228,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.safeShutdown(wait, false);
@@ -1195,6 +1197,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.halt(wait, false);
}
public void safeShutdown(final boolean wait, final boolean isRestarting) {
public void halt(final boolean wait, final boolean isRestarting) {
+ // Lophine start - Folia changes
+ safeShutdown(wait, isRestarting, false);
+ halt(wait, isRestarting, false);
+ }
+
+ public void safeShutdown(final boolean wait, final boolean isRestarting, boolean force) {
+ public void halt(final boolean wait, final boolean isRestarting, boolean force) {
+ if (!force && !this.getBotList().forceShutdown && !this.getBotList().removeAll()) { // Leaves - save or remove bot
+ this.getPlayerList().broadcastSystemMessage(Component.literal("Bot Still need to save, please wait! If you want to shuntdown without bot data saving, please use /stop force"), false);
+ return;
@@ -62,7 +62,7 @@ index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4
this.isRestarting = isRestarting;
this.hasLoggedStop = true; // Paper - Debugging
if (this.isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
@@ -1695,7 +1707,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1664,7 +1676,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
int emptyTickThreshold = this.pauseWhenEmptySeconds() * 20;
this.removeDisabledPluginsBlockingSleep(); // Paper - API to allow/disallow tick sleeping
if (false && emptyTickThreshold > 0) { // Folia - region threading - this is complicated to implement, and even if done correctly is messy
@@ -71,7 +71,7 @@ index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4
this.emptyTicks++;
} else {
this.emptyTicks = 0;
@@ -1827,6 +1839,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1796,6 +1808,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.isSaving = true;
if (playerSaveInterval > 0) {
this.playerList.saveAll(playerSaveInterval);
@@ -79,7 +79,7 @@ index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4
}
if (region == null && fullSave) { // Folia - region threading - don't auto save level data
this.saveGlobalData(false);
@@ -2065,6 +2078,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2034,6 +2047,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected void tickConnection() {
this.getConnection().tick();
@@ -87,7 +87,7 @@ index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4
}
public void forceGameTimeSynchronization() {
@@ -3270,6 +3284,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -3243,6 +3257,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return this.debugSubscribers;
}
@@ -101,14 +101,14 @@ index 9e290fa626caffac148920c54479a75ad0919e70..75d93d7d8bc6077dd80e499cd43327a4
+ }
+ // Leaves end - fakeplayer
+
public record ReloadableResources(CloseableResourceManager resourceManager, ReloadableServerResources managers) implements AutoCloseable {
@Override
public void close() {
public enum MultiplayerScope {
OFF("off"),
LAN("lan");
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
index 658db8460122db271bbc3c2c0844574b8d75f044..89448eee9f135de8b406bf5f4147b3298e33ba17 100644
index d447b444abd9b62ab241419301a96d19ae77a7eb..cdafcb724106807c6bc77c9930090839bd2cc007 100644
--- a/net/minecraft/server/PlayerAdvancements.java
+++ b/net/minecraft/server/PlayerAdvancements.java
@@ -168,6 +168,11 @@ public class PlayerAdvancements {
@@ -166,6 +166,11 @@ public class PlayerAdvancements {
}
public boolean award(final AdvancementHolder holder, final String criterion) {
@@ -121,7 +121,7 @@ index 658db8460122db271bbc3c2c0844574b8d75f044..89448eee9f135de8b406bf5f4147b329
AdvancementProgress progress = this.getOrStartProgress(holder);
boolean wasDone = progress.isDone();
diff --git a/net/minecraft/server/commands/BanIpCommands.java b/net/minecraft/server/commands/BanIpCommands.java
index 36b858bfe123edc2f1c5c7861dd0e4475ef7a5f1..e52a2ad8408d9691701dc51fa702efdb51f0acbb 100644
index dee5e12db878c13392083a46496de88d0b5924c3..922afd5e0fad3519ff2d7dc692574e5f65f119d6 100644
--- a/net/minecraft/server/commands/BanIpCommands.java
+++ b/net/minecraft/server/commands/BanIpCommands.java
@@ -40,6 +40,12 @@ public class BanIpCommands {
@@ -174,42 +174,43 @@ index c87bc86c57fde9d92e3927bdead5cdaf2e935744..950f8ed955bc09713348936ae7aa1a8b
return count;
}
diff --git a/net/minecraft/server/commands/KickCommand.java b/net/minecraft/server/commands/KickCommand.java
index 0227dd63f67537d769494e122616873c18d35350..18d49018b1330cfcaa91d9b02d0d23e4ba941809 100644
index bf361ef4cbf2a55b8bba5a75111257fb2d6d471f..82629ecca8b0e216db4ccb6f4c38de53ac1a6419 100644
--- a/net/minecraft/server/commands/KickCommand.java
+++ b/net/minecraft/server/commands/KickCommand.java
@@ -38,9 +38,17 @@ public class KickCommand {
if (!source.getServer().isPublished()) {
@@ -39,9 +39,17 @@ public class KickCommand {
throw ERROR_SINGLEPLAYER.create();
}
- int count = 0;
+ boolean hasBot = false; // Leaves - disable kick
+ int count = 0;
for (ServerPlayer player : players) {
+ // Leaves start - disable kick
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
+ source.sendFailure(Component.literal("Permission denied"));
+ hasBot = true;
+ continue;
+ }
+ // Leaves end - disable kick
if (!source.getServer().isSingleplayerOwner(player.nameAndId())) {
player.connection.disconnect(reason, org.bukkit.event.player.PlayerKickEvent.Cause.KICKED); // Paper - kick event cause
source.sendSuccess(() -> Component.translatable("commands.kick.success", player.getDisplayName(), reason), true);
@@ -50,7 +58,13 @@ public class KickCommand {
}
if (count == 0) {
- throw ERROR_KICKING_OWNER.create();
+ // Leaves start - disable kick
+ if (hasBot) {
+ return count;
+ } else {
+ throw ERROR_KICKING_OWNER.create();
+ }
+ // Leaves end - disable kick
} else {
+ boolean hasBot = false; // Leaves - disable kick
int count = 0;
for (ServerPlayer player : players) {
+ // Leaves start - disable kick
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
+ source.sendFailure(Component.literal("Permission denied"));
+ hasBot = true;
+ continue;
+ }
+ // Leaves end - disable kick
if (!source.getServer().isSingleplayerOwner(player.nameAndId())) {
player.connection.disconnect(reason, org.bukkit.event.player.PlayerKickEvent.Cause.KICK_COMMAND); // Paper - kick event cause
source.sendSuccess(() -> Component.translatable("commands.kick.success", player.getDisplayName(), reason), true);
@@ -49,7 +57,13 @@ public class KickCommand {
}
if (count == 0) {
- throw ERROR_KICKING_OWNER.create();
+ // Leaves start - disable kick
+ if (hasBot) {
+ return count;
+ } else {
+ throw ERROR_KICKING_OWNER.create();
+ }
+ // Leaves end - disable kick
} else {
return count;
}
return count;
}
diff --git a/net/minecraft/server/commands/OpCommand.java b/net/minecraft/server/commands/OpCommand.java
index 636f56bfc0e9075b257e2eb14e858975bdedd801..20cbc0e65fea3fc2d0033259c2f35e158ea81926 100644
--- a/net/minecraft/server/commands/OpCommand.java
@@ -223,26 +224,26 @@ index 636f56bfc0e9075b257e2eb14e858975bdedd801..20cbc0e65fea3fc2d0033259c2f35e15
list.op(player);
count++;
diff --git a/net/minecraft/server/commands/StopCommand.java b/net/minecraft/server/commands/StopCommand.java
index e9c9a468f046832e8eaa999bb57da261b4633604..2efe24c0378a80dd2750b10a54c1887816236c1a 100644
index 3021b70b941ed09c5c58b98d30830a2279b8339c..d289f59475b617ae527d123239297f695468b80c 100644
--- a/net/minecraft/server/commands/StopCommand.java
+++ b/net/minecraft/server/commands/StopCommand.java
@@ -11,6 +11,10 @@ public class StopCommand {
@@ -12,6 +12,10 @@ public class StopCommand {
c.getSource().sendSuccess(() -> Component.translatable("commands.stop.stopping"), true);
c.getSource().getServer().halt(false);
return 1;
return Command.SINGLE_SUCCESS;
- }));
+ }).then(Commands.literal("force").requires(Commands.hasPermission(Commands.LEVEL_OWNERS)).executes(c -> {
+ c.getSource().sendSuccess(() -> Component.translatable("commands.stop.stopping"), true);
+ c.getSource().getServer().safeShutdown(false, false, true);
+ c.getSource().getServer().halt(false, false, true);
+ return 1;
+ })));
}
}
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 1bc1e9a77dca7acfe5f989f6439f185d0d2e20a6..1790e8c141a8d3f7ccf4b11f9a28b3582325e317 100644
index 2dae0f4249eade60ac55c9fa289dd146dc3675e1..239cad02f85f0d14d4abfa746ecdc4dd82b04657 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -274,6 +274,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -230,6 +230,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
// Spigot start
@@ -250,7 +251,7 @@ index 1bc1e9a77dca7acfe5f989f6439f185d0d2e20a6..1790e8c141a8d3f7ccf4b11f9a28b358
this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage));
org.spigotmc.SpigotConfig.init((java.io.File) this.options.valueOf("spigot-settings"));
org.spigotmc.SpigotConfig.registerCommands();
@@ -295,6 +296,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -251,6 +252,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
consoleThread.start(); // Paper - Enhance console tab completions for brigadier commands; start console thread after MinecraftServer.console & PaperConfig are initialized
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
if (false) this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark // Luminol - Force disable builtin spark
@@ -259,9 +260,18 @@ index 1bc1e9a77dca7acfe5f989f6439f185d0d2e20a6..1790e8c141a8d3f7ccf4b11f9a28b358
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 0dfb25ad032429a2aea7aa441dd5fd1848a6c617..215f2a40921cc8e6b181c0a34aa1bbaf843e3059 100644
index 6cd549849bd7fb5d72431f729229d1e967cf0d98..179e39574fe2a4f395c64c51d6149e01d641a428 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -971,7 +971,7 @@ public class ChunkMap extends SimpleRegionStorage implements ChunkHolder.PlayerP
return this.level.moonrise$getEntityLookup().hasEntity(id); // Folia - region threading
}
- protected void addEntity(final Entity entity) {
+ public void addEntity(final Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
// Paper start - ignore and warn about illegal addEntity calls instead of crashing server
if (!entity.valid || entity.level() != this.level || entity.moonrise$getTrackedEntity() != null) { // Folia - region threading
@@ -1388,6 +1388,13 @@ public class ChunkMap extends SimpleRegionStorage implements ChunkHolder.PlayerP
}
} else {
@@ -277,18 +287,18 @@ index 0dfb25ad032429a2aea7aa441dd5fd1848a6c617..215f2a40921cc8e6b181c0a34aa1bbaf
}
}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 0ff635e6956a9935ad6d11e5c7bac189c51244b6..8bfb2afd7199b2739ccfbab4ad68e030e722db7e 100644
index b03491230ed9b68e0e8f29719e34ea4b9947f408..558f465e9ec2536064716a196d52d78d873d95be 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -240,6 +240,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
//public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent // Folia - region threading - move to regionised world data
//public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent // Folia - region threading - move to regionised world data
@@ -243,6 +243,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
//private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) // Folia - region threading - move to regionised world data
+ final List<ServerPlayer> realPlayers; // Leaves - skip
@Override
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
@@ -706,6 +707,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -709,6 +710,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler);
// Paper end - rewrite chunk system
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
@@ -296,7 +306,7 @@ index 0ff635e6956a9935ad6d11e5c7bac189c51244b6..8bfb2afd7199b2739ccfbab4ad68e030
this.updateTickData(); // Folia - region threading - make sure it is initialised before ticked
}
@@ -2611,6 +2613,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -2595,6 +2597,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
return this.players;
}
@@ -309,7 +319,7 @@ index 0ff635e6956a9935ad6d11e5c7bac189c51244b6..8bfb2afd7199b2739ccfbab4ad68e030
@Override
public void updatePOIOnBlockStateChange(final BlockPos pos, final BlockState oldState, final BlockState newState) {
Optional<Holder<PoiType>> oldType = PoiTypes.forState(oldState);
@@ -3091,6 +3099,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -3068,6 +3076,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
// ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true
if (entity instanceof ServerPlayer player) {
ServerLevel.this.players.add(player);
@@ -321,7 +331,7 @@ index 0ff635e6956a9935ad6d11e5c7bac189c51244b6..8bfb2afd7199b2739ccfbab4ad68e030
if (player.isReceivingWaypoints()) {
ServerLevel.this.getWaypointManager().addPlayer(player);
}
@@ -3172,6 +3185,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -3149,6 +3162,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
ServerLevel.this.getChunkSource().removeEntity(entity);
if (entity instanceof ServerPlayer player) {
ServerLevel.this.players.remove(player);
@@ -334,10 +344,10 @@ index 0ff635e6956a9935ad6d11e5c7bac189c51244b6..8bfb2afd7199b2739ccfbab4ad68e030
ServerLevel.this.updateSleepingPlayerList();
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index f3afab1100a35cc9ab091944de93d1f30ef040a7..423652d0ccef5c6a3b93480401c3d0f672bbf8a5 100644
index 2985d5e2dde049a999a39f6edbb6696332f6d822..64943c193ae73795ddf8222a6f71ea5eb1705fe2 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -229,7 +229,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -232,7 +232,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
private static final boolean DEFAULT_SPAWN_EXTRA_PARTICLES_ON_FALL = false;
public ServerGamePacketListenerImpl connection;
private final MinecraftServer server;
@@ -346,38 +356,41 @@ index f3afab1100a35cc9ab091944de93d1f30ef040a7..423652d0ccef5c6a3b93480401c3d0f6
private final PlayerAdvancements advancements;
private final ServerStatsCounter stats;
private float lastRecordedHealthAndAbsorption = Float.MIN_VALUE;
@@ -250,7 +250,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -251,9 +251,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
private boolean canChatColor = true;
private long lastActionTime = Util.getMillis();
private @Nullable Entity camera;
public boolean isChangingDimension;
- private boolean isChangingDimension;
+ protected boolean isChangingDimension;
public boolean seenCredits = false;
- private final ServerRecipeBook recipeBook;
+ protected ServerRecipeBook recipeBook; // Leaves - not final and private -> protected
private @Nullable Vec3 levitationStartPos;
private int levitationStartTime;
private boolean disconnected;
@@ -1514,7 +1514,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1489,7 +1489,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
// Luminol End - Cross Region Damage trace
// Lophine End - Cross Region Damage trace
- private void tellNeutralMobsThatIDied() {
+ protected void tellNeutralMobsThatIDied() { // Leaves private -> protected
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
this.level()
.getEntitiesOfClass(Mob.class, aabb, EntitySelector.NO_SPECTATORS)
@@ -2180,6 +2180,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.lastSentHealth = -1.0F;
this.lastSentFood = -1;
this.teleportSpectators(transition, oldLevel);
+ // Leaves start - bot support
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
+ this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(this, true)); // Leaves - render bot
+ }
+ // Leaves end - bot support
// CraftBukkit start
org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), oldLevel.getWorld());
this.level().getCraftServer().getPluginManager().callEvent(changeEvent);
@@ -2161,6 +2161,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.lastSentHealth = -1.0F;
this.lastSentFood = -1;
this.teleportSpectators(transition, oldLevel);
+ // Leaves start - bot support
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
+ this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(this, true)); // Leaves - render bot
+ }
+ // Leaves end - bot support
// CraftBukkit start
org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), oldLevel.getWorld());
this.level().getCraftServer().getPluginManager().callEvent(changeEvent);
diff --git a/net/minecraft/server/players/CachedUserNameToIdResolver.java b/net/minecraft/server/players/CachedUserNameToIdResolver.java
index 50c64f4be138f08e8a57fb10888dbfbc364c91af..382fc20df48d7d554833715a9c9f62ea7464a25d 100644
index b7553611723f7120c66e1f3e51d89df28bd2756b..7109a22a9911d452242207ab0286ee985dafd439 100644
--- a/net/minecraft/server/players/CachedUserNameToIdResolver.java
+++ b/net/minecraft/server/players/CachedUserNameToIdResolver.java
@@ -122,6 +122,12 @@ public class CachedUserNameToIdResolver implements UserNameToIdResolver {
@@ -394,7 +407,7 @@ index 50c64f4be138f08e8a57fb10888dbfbc364c91af..382fc20df48d7d554833715a9c9f62ea
boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
CachedUserNameToIdResolver.GameProfileInfo profileInfo = this.profilesByName.get(userName);
diff --git a/net/minecraft/server/players/NameAndId.java b/net/minecraft/server/players/NameAndId.java
index 484714beb5f7cdf8178834c5edd4f847fb06ebb8..ba7a280aad07f36366c15cd158b36ca9768cef19 100644
index 12190f2a2856b0d0cf95144d0b1622f1b9600bf6..be01f06d4ee02854345842c97382e8b6401ab948 100644
--- a/net/minecraft/server/players/NameAndId.java
+++ b/net/minecraft/server/players/NameAndId.java
@@ -8,18 +8,22 @@ import java.util.UUID;
@@ -442,10 +455,10 @@ index 484714beb5f7cdf8178834c5edd4f847fb06ebb8..ba7a280aad07f36366c15cd158b36ca9
// Paper start - utility method for common conversion back to the game profile
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index ebd2f2887780d9c6c3c44983bac23eab732cf43f..14be3d21cc1a613b1d9164ecc699073f0da2047c 100644
index ca1e635b0fdf3d0d17447b43a558fe030536d297..ed50484ca24ef24b1e5bef9f6369dfa4b30c359c 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -319,6 +319,19 @@ public abstract class PlayerList {
@@ -320,6 +320,19 @@ public abstract class PlayerList {
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
@@ -495,8 +508,8 @@ index ebd2f2887780d9c6c3c44983bac23eab732cf43f..14be3d21cc1a613b1d9164ecc699073f
return names;
}
@@ -1016,8 +1039,15 @@ public abstract class PlayerList {
|| this.allowCommandsForAllPlayers;
@@ -1018,8 +1041,15 @@ public abstract class PlayerList {
}
}
- public @Nullable ServerPlayer getPlayerByName(final String name) {
@@ -513,7 +526,7 @@ index ebd2f2887780d9c6c3c44983bac23eab732cf43f..14be3d21cc1a613b1d9164ecc699073f
}
public void broadcast(
@@ -1360,7 +1390,13 @@ public abstract class PlayerList {
@@ -1366,7 +1396,13 @@ public abstract class PlayerList {
}
public @Nullable ServerPlayer getPlayer(final UUID uuid) {
@@ -529,10 +542,10 @@ index ebd2f2887780d9c6c3c44983bac23eab732cf43f..14be3d21cc1a613b1d9164ecc699073f
public @Nullable ServerPlayer getPlayer(final String playerName) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 6f7e5d62901733df08c6beafbda2e54bc1c5f917..07c5fed7b0bf3ecefb54ccb0bfb922c2f11f7939 100644
index b7cc122d45ecaf922ca1aca8ff5f1632965ad357..8631acfea913aceabefad3d418d282042bbaca1a 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1257,7 +1257,7 @@ public abstract class Entity
@@ -1263,7 +1263,7 @@ public abstract class Entity
BlockPos effectPos = this.getOnPosLegacy();
BlockState effectState = this.level().getBlockState(effectPos);
@@ -541,7 +554,7 @@ index 6f7e5d62901733df08c6beafbda2e54bc1c5f917..07c5fed7b0bf3ecefb54ccb0bfb922c2
this.checkFallDamage(movement.y, this.onGround(), effectState, effectPos);
}
@@ -1602,7 +1602,7 @@ public abstract class Entity
@@ -1664,7 +1664,7 @@ public abstract class Entity
return colliders.isEmpty() ? maxDistance : -Shapes.collide(Direction.Axis.Y, aabb, colliders, -maxDistance);
}
@@ -551,10 +564,10 @@ index 6f7e5d62901733df08c6beafbda2e54bc1c5f917..07c5fed7b0bf3ecefb54ccb0bfb922c2
final boolean xZero = movement.x == 0.0;
final boolean yZero = movement.y == 0.0;
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 1e820f34636f415ef78cdfbed06c6952a3cf1c0b..8a8de7f4d62532709805ebde531dc71ad78fa5c9 100644
index cb1589e3aa663ca058fb5c3a24da700d4482cf35..d64c68651b7142869a06ce0200fb625cd45ae235 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -3347,7 +3347,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
@@ -3348,7 +3348,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
private void travelRidden(final Player controller, final Vec3 selfInput) {
Vec3 riddenInput = this.getRiddenInput(controller, selfInput);
this.tickRidden(controller, riddenInput);
@@ -563,7 +576,7 @@ index 1e820f34636f415ef78cdfbed06c6952a3cf1c0b..8a8de7f4d62532709805ebde531dc71a
this.setSpeed(this.getRiddenSpeed(controller));
this.travel(riddenInput);
} else {
@@ -4270,7 +4270,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
@@ -4280,7 +4280,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
// Paper start - lag compensate eating
// we add 1 to the expected time to avoid lag compensating when we should not
final boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L));
@@ -572,7 +585,7 @@ index 1e820f34636f415ef78cdfbed06c6952a3cf1c0b..8a8de7f4d62532709805ebde531dc71a
this.useItemRemaining = 0;
// Paper end - lag compensate eating
this.completeUsingItem();
@@ -4459,6 +4459,23 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
@@ -4469,6 +4469,23 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
this.stopUsingItem();
}
@@ -597,9 +610,18 @@ index 1e820f34636f415ef78cdfbed06c6952a3cf1c0b..8a8de7f4d62532709805ebde531dc71a
if (!this.level().isClientSide()) {
boolean wasUsingItem = this.isUsingItem();
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index f6f6d21f3393a3ab79a84212b0d66d83d0e817f1..38689fa466a20c64f9916ee32a57a9fdb58d9403 100644
index c6fa9dff800b1491b1e0fc5d7e1dc16b99b8c7db..f063e9b7601480d0e66da22ea8e5bec2e8619fee 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -156,7 +156,7 @@ public abstract class Player extends Avatar implements ContainerUser {
protected FoodData foodData = new FoodData();
protected int jumpTriggerTime;
public int takeXpDelay;
- private int sleepCounter = 0;
+ protected int sleepCounter = 0;
protected boolean wasUnderwater;
private final Abilities abilities = new Abilities();
public int experienceLevel = 0;
@@ -167,7 +167,7 @@ public abstract class Player extends Avatar implements ContainerUser {
private int lastLevelUpTime;
public GameProfile gameProfile;
@@ -608,8 +630,8 @@ index f6f6d21f3393a3ab79a84212b0d66d83d0e817f1..38689fa466a20c64f9916ee32a57a9fd
+ protected ItemStack lastItemInMainHand = ItemStack.EMPTY; // Leaves - fakeplayer
private final ItemCooldowns cooldowns = this.createItemCooldowns();
private Optional<GlobalPos> lastDeathLocation = Optional.empty();
public @Nullable FishingHook fishing;
@@ -340,6 +340,12 @@ public abstract class Player extends Avatar implements ContainerUser {
public me.earthme.luminol.functions.bars.TickableStatusBarList statusBarList = new me.earthme.luminol.functions.bars.TickableStatusBarList(this); // Luminol status bars
@@ -345,6 +345,12 @@ public abstract class Player extends Avatar implements ContainerUser {
this.updatePlayerPose();
}
@@ -622,7 +644,7 @@ index f6f6d21f3393a3ab79a84212b0d66d83d0e817f1..38689fa466a20c64f9916ee32a57a9fd
@Override
protected float getMaxHeadRotationRelativeToBody() {
return this.isBlocking() ? 15.0F : super.getMaxHeadRotationRelativeToBody();
@@ -565,7 +571,7 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -570,7 +576,7 @@ public abstract class Player extends Avatar implements ContainerUser {
public void removeEntitiesOnShoulder() {
}
@@ -631,21 +653,21 @@ index f6f6d21f3393a3ab79a84212b0d66d83d0e817f1..38689fa466a20c64f9916ee32a57a9fd
entity.playerTouch(this);
}
@@ -1247,7 +1253,7 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -1270,7 +1276,7 @@ public abstract class Player extends Avatar implements ContainerUser {
// Paper end - Configurable sprint interruption on attack
}
- if (entity instanceof ServerPlayer && entity.hurtMarked) {
+ if ((entity instanceof ServerPlayer && !(entity instanceof org.leavesmc.leaves.bot.ServerBot)) && entity.hurtMarked) { // Leaves - bot knockback
- if (entity instanceof ServerPlayer serverPlayer && entity.hurtMarked) {
+ if ((entity instanceof ServerPlayer serverPlayer && !(entity instanceof org.leavesmc.leaves.bot.ServerBot)) && entity.hurtMarked) { // Leaves - bot knockback
// CraftBukkit start - Add Velocity Event
boolean cancelled = false;
org.bukkit.entity.Player player = (org.bukkit.entity.Player) entity.getBukkitEntity();
diff --git a/net/minecraft/world/entity/projectile/FishingHook.java b/net/minecraft/world/entity/projectile/FishingHook.java
index 0c8a48988c859669cf7e38816aaf32782c245244..a554e050d0c582c441af9d5616367234caa67ab0 100644
index d7217fd075c6d6fae3622c56e940e247008dcc27..0958e7f93494766e97e87ed4d39c8e4550a641f6 100644
--- a/net/minecraft/world/entity/projectile/FishingHook.java
+++ b/net/minecraft/world/entity/projectile/FishingHook.java
@@ -58,7 +58,7 @@ public class FishingHook extends Projectile {
public static final EntityDataAccessor<Integer> DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT);
@@ -59,7 +59,7 @@ public class FishingHook extends Projectile {
private static final EntityDataAccessor<Integer> DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> DATA_BITING = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.BOOLEAN);
private int life;
- private int nibble;
@@ -654,7 +676,7 @@ index 0c8a48988c859669cf7e38816aaf32782c245244..a554e050d0c582c441af9d5616367234
public int timeUntilHooked;
public float fishAngle;
diff --git a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java
index 05176458264b110ef3280342866ace22ec5a3333..2ce33513fd8e3de912c69ca8bc558a5800784ac5 100644
index 9b887b40236a212de513e3ceece1abfec5372ae2..2f8f8fa1bef9f333978b47c2ce729c291bec66fb 100644
--- a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java
+++ b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java
@@ -270,6 +270,11 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
@@ -684,10 +706,10 @@ index 05176458264b110ef3280342866ace22ec5a3333..2ce33513fd8e3de912c69ca8bc558a58
return switch (this.getStatus()) {
case IN_WATER, UNDER_WATER, UNDER_FLOWING_WATER -> SoundEvents.BOAT_PADDLE_WATER;
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
index fa1f7dd22959632aaa54e72c8caf13ea072e7ca7..ae6056c3b6ae3eebdfb59cf54d7333dfc2cebf6a 100644
index f6d37cba8ab5688501be9170720a0b6ded810819..fdd03c9d73a8a0527d0ead3fbbba20083c617e2c 100644
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -407,6 +407,7 @@ public abstract class AbstractContainerMenu {
@@ -406,6 +406,7 @@ public abstract class AbstractContainerMenu {
private void doClick(final int slotIndex, final int buttonNum, final ContainerInput containerInput, final Player player) {
Inventory inventory = player.getInventory();
@@ -695,7 +717,7 @@ index fa1f7dd22959632aaa54e72c8caf13ea072e7ca7..ae6056c3b6ae3eebdfb59cf54d7333df
if (containerInput == ContainerInput.QUICK_CRAFT) {
int expectedStatus = this.quickcraftStatus;
this.quickcraftStatus = getQuickcraftHeader(buttonNum);
@@ -681,6 +682,22 @@ public abstract class AbstractContainerMenu {
@@ -680,6 +681,22 @@ public abstract class AbstractContainerMenu {
}
}
@@ -719,19 +741,19 @@ index fa1f7dd22959632aaa54e72c8caf13ea072e7ca7..ae6056c3b6ae3eebdfb59cf54d7333df
final Player player, final ClickAction clickAction, final Slot slot, final ItemStack clicked, final ItemStack carried
) {
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index 61466aa6d11af2858fa2898ef5b4b7515f4365df..78dd1f8fbbb1e7633142f7038de29124312878dd 100644
index f15ee24339b04e4fe395755bf3503c17886f1782..2ba711dc758d0d8530b0fb6f0939ed88ec5df169 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -453,7 +453,7 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(level, player, hand, blocks.getFirst(), pos);
}
@@ -458,7 +458,7 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(level, player, hand, capturedBlockStates.getFirst(), pos);
}
- if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild()) && (!(player instanceof org.leavesmc.leaves.bot.ServerBot))) { // Leaves - Fakeplayer skip this check
result = InteractionResult.FAIL; // cancel placement
// PAIL: Remove this when MC-99075 fixed
player.containerMenu.forceHeldSlot(hand);
@@ -982,6 +982,20 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
- if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild()) && (!(player instanceof org.leavesmc.leaves.bot.ServerBot))) { // Leaves - Fakeplayer skip this check
result = InteractionResult.FAIL; // cancel placement
// PAIL: Remove this when MC-99075 fixed
player.containerMenu.forceHeldSlot(hand);
@@ -962,6 +962,20 @@ public final class ItemStack implements DataComponentHolder, ItemInstance, Chang
}
}
@@ -753,7 +775,7 @@ index 61466aa6d11af2858fa2898ef5b4b7515f4365df..78dd1f8fbbb1e7633142f7038de29124
return this.getItem().useOnRelease(this);
}
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 282849162b88354893a15533e66d046fdd035bd6..2ecb10fe97d15954e44c61247eabc8818eb16f34 100644
index 8d761640af4ce3afb4de5b46d3627614fff0ece9..15605dacaec3860e476a70dbdd3743e4197f67a6 100644
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -152,7 +152,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
@@ -766,7 +788,7 @@ index 282849162b88354893a15533e66d046fdd035bd6..2ecb10fe97d15954e44c61247eabc881
double dx = deltaMovement.x;
double dy = deltaMovement.y;
diff --git a/net/minecraft/world/level/levelgen/PhantomSpawner.java b/net/minecraft/world/level/levelgen/PhantomSpawner.java
index 9d7238a28440ddc442c9288a617795261df767d9..142ab133d3b68eb9b88651e307653f1aafdf1de3 100644
index db0324595d7f5b6f92bd7724daf181b0903e1da4..ec3a437bd8a7d0e95e1e5fa0ff4462a70391ecf9 100644
--- a/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -49,6 +49,10 @@ public class PhantomSpawner implements CustomSpawner {
@@ -10,7 +10,7 @@ Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
This patch is Powered by ReplayMod (https://github.com/ReplayMod)
diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java
index 28776f3363810259f8c3bfdfd9f8c0455975be2a..0f562d7403aebf6c0907f2a33f758f4351ef282e 100644
index 587ec673a0821e91de67abaf3a559c78f4aa8016..4fc1aad19fd9321c44aae99c118f40ec67d78020 100644
--- a/net/minecraft/commands/CommandSourceStack.java
+++ b/net/minecraft/commands/CommandSourceStack.java
@@ -562,7 +562,7 @@ public class CommandSourceStack implements SharedSuggestionProvider, ExecutionCo
@@ -23,16 +23,18 @@ index 28776f3363810259f8c3bfdfd9f8c0455975be2a..0f562d7403aebf6c0907f2a33f758f43
@Override
diff --git a/net/minecraft/commands/arguments/selector/EntitySelector.java b/net/minecraft/commands/arguments/selector/EntitySelector.java
index 7e3912b8b29e40eb3347f1451b0fd3ebee2af4f1..0834e402e6af7028e08851378e15390ec6314380 100644
index 6c05b9276bdc267a36376f6c64592a50e4b2b36e..21d2c97b3d1e1d29c9de02b6acd58985c7c74231 100644
--- a/net/minecraft/commands/arguments/selector/EntitySelector.java
+++ b/net/minecraft/commands/arguments/selector/EntitySelector.java
@@ -142,11 +142,12 @@ public class EntitySelector {
return this.findPlayers(sender);
} else if (this.playerName != null) {
@@ -144,13 +144,14 @@ public class EntitySelector {
if (this.playerName != null) {
ServerPlayer result = sender.getServer().getPlayerList().getPlayerByName(this.playerName);
+ result = result instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : result; // Leaves - skip photographer
return result == null ? List.of() : List.of(result);
} else if (this.entityUUID != null) {
}
if (this.entityUUID != null) {
for (ServerLevel level : sender.getServer().getAllLevels()) {
Entity entity = level.getEntity(this.entityUUID);
- if (entity != null) {
@@ -40,54 +42,56 @@ index 7e3912b8b29e40eb3347f1451b0fd3ebee2af4f1..0834e402e6af7028e08851378e15390e
if (entity.getType().isEnabled(sender.enabledFeatures())) {
return List.of(entity);
}
@@ -160,7 +161,7 @@ public class EntitySelector {
@@ -164,7 +165,7 @@ public class EntitySelector {
AABB absoluteAabb = this.getAbsoluteAabb(pos);
if (this.currentEntity) {
Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, null);
- return sender.getEntity() != null && predicate.test(sender.getEntity()) ? List.of(sender.getEntity()) : List.of();
+ return sender.getEntity() != null && !(sender.getEntity() instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(sender.getEntity()) ? List.of(sender.getEntity()) : List.of(); // Leaves - skip photographer
} else {
Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, sender.enabledFeatures());
List<Entity> result = new ObjectArrayList<>();
@@ -171,6 +172,7 @@ public class EntitySelector {
this.addEntities(result, levelx, absoluteAabb, predicate);
}
}
Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, sender.enabledFeatures());
@@ -176,6 +177,7 @@ public class EntitySelector {
this.addEntities(result, level, absoluteAabb, predicate);
}
}
+ result.removeIf(entity -> entity instanceof org.leavesmc.leaves.replay.ServerPhotographer); // Leaves - skip photographer
return this.sortAndLimit(pos, result);
}
@@ -206,9 +208,11 @@ public class EntitySelector {
return this.sortAndLimit(pos, result);
}
@@ -210,11 +212,13 @@ public class EntitySelector {
this.checkPermissions(sender);
if (this.playerName != null) {
ServerPlayer result = sender.getServer().getPlayerList().getPlayerByName(this.playerName);
+ result = result instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : result; // Leaves - skip photographer
return result == null ? List.of() : List.of(result);
} else if (this.entityUUID != null) {
}
if (this.entityUUID != null) {
ServerPlayer result = sender.getServer().getPlayerList().getPlayer(this.entityUUID);
+ result = result instanceof org.leavesmc.leaves.replay.ServerPhotographer ? null : result; // Leaves - skip photographer
return result == null ? List.of() : List.of(result);
} else {
Vec3 pos = this.position.apply(sender.getPosition());
@@ -220,11 +224,11 @@ public class EntitySelector {
int limit = this.getResultLimit();
List<ServerPlayer> result;
if (this.isWorldLimited()) {
- result = sender.getLevel().getPlayers(predicate, limit);
+ result = sender.getLevel().getPlayers((player -> !(player instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(player)), limit); // Leaves - skip photographer
} else {
result = new ObjectArrayList<>();
}
- for (ServerPlayer player : sender.getServer().getPlayerList().getPlayers()) {
+ for (ServerPlayer player : sender.getServer().getPlayerList().realPlayers) { // Leaves - only real players
if (predicate.test(player)) {
result.add(player);
if (result.size() >= limit) {
@@ -228,11 +232,11 @@ public class EntitySelector {
int limit = this.getResultLimit();
List<ServerPlayer> result;
if (this.isWorldLimited()) {
- result = sender.getLevel().getPlayers(predicate, limit);
+ result = sender.getLevel().getPlayers((player -> !(player instanceof org.leavesmc.leaves.replay.ServerPhotographer) && predicate.test(player)), limit); // Leaves - skip photographer
} else {
result = new ObjectArrayList<>();
- for (ServerPlayer player : sender.getServer().getPlayerList().getPlayers()) {
+ for (ServerPlayer player : sender.getServer().getPlayerList().realPlayers) { // Leaves - only real players
if (predicate.test(player)) {
result.add(player);
if (result.size() >= limit) {
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 75d93d7d8bc6077dd80e499cd43327a4afe58f51..3b9a4f4b5794faa4955018858c94fd5c2d6ada3d 100644
index dd2a108f31bcbc1beae8c820c22baaa515fec7ec..67bdd2887afed082fd1bae03f030f2d25d55e282 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1930,7 +1930,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1899,7 +1899,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
private ServerStatus.Players buildPlayerStatus() {
@@ -96,7 +100,7 @@ index 75d93d7d8bc6077dd80e499cd43327a4afe58f51..3b9a4f4b5794faa4955018858c94fd5c
int maxPlayers = this.getMaxPlayers();
if (this.hidesOnlinePlayers()) {
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
@@ -2151,7 +2151,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2120,7 +2120,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@Override
public int getPlayerCount() {
@@ -105,16 +109,16 @@ index 75d93d7d8bc6077dd80e499cd43327a4afe58f51..3b9a4f4b5794faa4955018858c94fd5c
}
public String[] getPlayerNames() {
@@ -2363,7 +2363,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} else {
int count = 0;
@@ -2337,7 +2337,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- for (ServerPlayer player : this.getPlayerList().getPlayers()) {
+ for (ServerPlayer player : this.getPlayerList().realPlayers) { // Leaves - only real player
player.getBukkitEntity().taskScheduler.schedule((ServerPlayer updatedPlayer) -> { // Folia - region threading
// Paper start - Expand PlayerGameModeChangeEvent
org.bukkit.event.player.PlayerGameModeChangeEvent event = updatedPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null); // Folia - region threading
@@ -2550,7 +2550,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
int count = 0;
- for (ServerPlayer player : this.getPlayerList().getPlayers()) {
+ for (ServerPlayer player : this.getPlayerList().realPlayers) { // Leaves - only real player
player.getBukkitEntity().taskScheduler.schedule((ServerPlayer updatedPlayer) -> { // Folia - region threading
// Paper start - Expand PlayerGameModeChangeEvent
org.bukkit.event.player.PlayerGameModeChangeEvent event = updatedPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null); // Folia - region threading
@@ -2528,7 +2528,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (Thread.currentThread() != this.serverThread) return; // Paper
// Paper start - we don't need to save everything, just advancements
// this.getPlayerList().saveAll();
@@ -123,7 +127,7 @@ index 75d93d7d8bc6077dd80e499cd43327a4afe58f51..3b9a4f4b5794faa4955018858c94fd5c
player.getAdvancements().save();
}
// Paper end - we don't need to save everything, just advancements
@@ -2686,7 +2686,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2664,7 +2664,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
PlayerList playerList = this.getPlayerList();
UserWhiteList whiteList = playerList.getWhiteList();
@@ -133,10 +137,10 @@ index 75d93d7d8bc6077dd80e499cd43327a4afe58f51..3b9a4f4b5794faa4955018858c94fd5c
player.connection.disconnect(net.kyori.adventure.text.Component.text(org.spigotmc.SpigotConfig.whitelistMessage), org.bukkit.event.player.PlayerKickEvent.Cause.WHITELIST); // Paper - use configurable message & kick event cause
}
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
index 89448eee9f135de8b406bf5f4147b3298e33ba17..b286aefc7d328bc7a7f44ce93615392075d9fef7 100644
index cdafcb724106807c6bc77c9930090839bd2cc007..d916021ed42046d1aa37dc687ef80f6c5eb5c879 100644
--- a/net/minecraft/server/PlayerAdvancements.java
+++ b/net/minecraft/server/PlayerAdvancements.java
@@ -169,7 +169,7 @@ public class PlayerAdvancements {
@@ -167,7 +167,7 @@ public class PlayerAdvancements {
public boolean award(final AdvancementHolder holder, final String criterion) {
// Leaves start - bot can't get advancement
@@ -146,7 +150,7 @@ index 89448eee9f135de8b406bf5f4147b3298e33ba17..b286aefc7d328bc7a7f44ce936153920
}
// Leaves end - bot can't get advancement
diff --git a/net/minecraft/server/ServerScoreboard.java b/net/minecraft/server/ServerScoreboard.java
index 9bf09b888425e491072864265c8de3885154a0ba..97a8fee8280061312a28013a5400e835db2eb474 100644
index 7ffd683c42557052d7bfa963d87e68f4e8f62d6c..9d0f55250ec6613f7ad8252dd028468967953521 100644
--- a/net/minecraft/server/ServerScoreboard.java
+++ b/net/minecraft/server/ServerScoreboard.java
@@ -245,7 +245,7 @@ public class ServerScoreboard extends Scoreboard {
@@ -195,7 +199,7 @@ index 20cbc0e65fea3fc2d0033259c2f35e158ea81926..6bcd09b8d39333bd5f2c0d7c0a9a91bb
}
)
diff --git a/net/minecraft/server/commands/ParticleCommand.java b/net/minecraft/server/commands/ParticleCommand.java
index a14f82a1587e175030d4cd806726456831008dea..563d897a70f402d556cabd3e02131aaf22ff8d1e 100644
index ce8a8e665ca68f14158739dd7a07f932a472203c..390464ac4dcf698f27646efbdb034a873a8725af 100644
--- a/net/minecraft/server/commands/ParticleCommand.java
+++ b/net/minecraft/server/commands/ParticleCommand.java
@@ -36,7 +36,7 @@ public class ParticleCommand {
@@ -244,23 +248,23 @@ index a14f82a1587e175030d4cd806726456831008dea..563d897a70f402d556cabd3e02131aaf
)
.then(
diff --git a/net/minecraft/server/commands/TeamMsgCommand.java b/net/minecraft/server/commands/TeamMsgCommand.java
index d04fd8ab5f8e3c1697af5448c320838a822dbf1f..f46abe413e9b30f219fa1f7fc485de4c8859be90 100644
index 6a79944b040307acef3d1c66bd0dacaba514c708..4fa37a9772a10aea5eacaa1a02d9f834eda0877b 100644
--- a/net/minecraft/server/commands/TeamMsgCommand.java
+++ b/net/minecraft/server/commands/TeamMsgCommand.java
@@ -40,7 +40,7 @@ public class TeamMsgCommand {
} else {
List<ServerPlayer> receivers = source.getServer()
.getPlayerList()
- .getPlayers()
+ .realPlayers // Leaves - only real players
.stream()
.filter(receiver -> receiver == entity || receiver.getTeam() == team)
.toList();
@@ -41,7 +41,7 @@ public class TeamMsgCommand {
List<ServerPlayer> receivers = source.getServer()
.getPlayerList()
- .getPlayers()
+ .realPlayers // Leaves - only real players
.stream()
.filter(receiver -> receiver == entity || receiver.getTeam() == team)
.toList();
diff --git a/net/minecraft/server/commands/WhitelistCommand.java b/net/minecraft/server/commands/WhitelistCommand.java
index 907d1304503a80c6d0fd064bf1aaf4e081e9f85b..e0c1ee55888261bca42bbadec8812da2a36dded8 100644
index 3bc559b636288d38192c64a2aba15c062898182f..99aac6df1725db48b63ce68e74f6a3a18caf7956 100644
--- a/net/minecraft/server/commands/WhitelistCommand.java
+++ b/net/minecraft/server/commands/WhitelistCommand.java
@@ -44,7 +44,7 @@ public class WhitelistCommand {
@@ -45,7 +45,7 @@ public class WhitelistCommand {
(c, p) -> {
PlayerList list = c.getSource().getServer().getPlayerList();
return SharedSuggestionProvider.suggest(
@@ -285,10 +289,10 @@ index 37c9f983ae89c497f44a1b7967d741abf909e0a0..d7fb2505f2a86ca0d81f144624ef2e1a
this.setListData(players);
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 8bfb2afd7199b2739ccfbab4ad68e030e722db7e..8d6a5d2ab4589f81abdd4ae939f197051e9523fc 100644
index 558f465e9ec2536064716a196d52d78d873d95be..598867ffa41c8d38e0c18550071ac25935e34229 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -3100,7 +3100,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -3077,7 +3077,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
if (entity instanceof ServerPlayer player) {
ServerLevel.this.players.add(player);
// Leaves start - skip
@@ -297,7 +301,7 @@ index 8bfb2afd7199b2739ccfbab4ad68e030e722db7e..8d6a5d2ab4589f81abdd4ae939f19705
ServerLevel.this.realPlayers.add(player);
}
// Leaves end - skip
@@ -3186,7 +3186,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -3163,7 +3163,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
if (entity instanceof ServerPlayer player) {
ServerLevel.this.players.remove(player);
// Leaves start - skip
@@ -307,10 +311,10 @@ index 8bfb2afd7199b2739ccfbab4ad68e030e722db7e..8d6a5d2ab4589f81abdd4ae939f19705
}
// Leaves end - skip
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1f82c9279 100644
index ed50484ca24ef24b1e5bef9f6369dfa4b30c359c..64a87785048e103c10f6453e97a37f8501255adc 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -130,6 +130,7 @@ public abstract class PlayerList {
@@ -129,6 +129,7 @@ public abstract class PlayerList {
private int simulationDistance;
private boolean allowCommandsForAllPlayers;
private int sendAllPlayerInfoIn;
@@ -326,7 +330,7 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
int count = this.usersCountedAgainstLimit.size();
if (count >= limit) {
return false;
@@ -221,6 +223,124 @@ public abstract class PlayerList {
@@ -221,6 +223,123 @@ public abstract class PlayerList {
abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor
@@ -338,7 +342,6 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
+ ServerLevel worldserver1 = worldserver;
+
+ player.setServerLevel(worldserver1);
+ player.spawnIn(worldserver1);
+ player.gameMode.setLevel(player.level());
+
+ LevelData worlddata = worldserver1.getLevelData();
@@ -349,7 +352,7 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
+ boolean flag1 = gamerules.get(GameRules.REDUCED_DEBUG_INFO);
+ boolean flag2 = gamerules.get(GameRules.LIMITED_CRAFTING);
+
+ playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), io.papermc.paper.FeatureHooks.getViewDistance(worldserver1), io.papermc.paper.FeatureHooks.getSimulationDistance(worldserver1), flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1), this.server.enforceSecureProfile()));
+ playerconnection.send(new ClientboundLoginPacket(player.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), io.papermc.paper.FeatureHooks.getViewDistance(worldserver1), io.papermc.paper.FeatureHooks.getSimulationDistance(worldserver1), flag1, !flag, flag2, player.createCommonSpawnInfo(worldserver1), this.server.usesAuthentication(), this.server.enforceSecureProfile()));
+ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
+ playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
+ playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
@@ -451,7 +454,7 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
public void placeNewPlayer(final Connection connection, final ServerPlayer player, final CommonListenerCookie cookie) {
player.isRealPlayer = true; // Paper
player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
@@ -294,6 +414,7 @@ public abstract class PlayerList {
@@ -295,6 +414,7 @@ public abstract class PlayerList {
// player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below
this.players.add(player);
@@ -459,7 +462,7 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
this.playersByUUID.put(player.getUUID(), player);
// this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below
@@ -513,6 +634,7 @@ public abstract class PlayerList {
@@ -510,6 +630,7 @@ public abstract class PlayerList {
}
protected void save(final ServerPlayer player) {
@@ -467,7 +470,7 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
player.lastSave = System.nanoTime(); // Folia - region threading - changed to nanoTime tracking
this.playerIo.save(player);
@@ -527,6 +649,47 @@ public abstract class PlayerList {
@@ -524,6 +645,48 @@ public abstract class PlayerList {
}
}
@@ -493,7 +496,8 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
+
+ worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
+ entityplayer.retireScheduler();
+ entityplayer.getAdvancements().stopListening();
+ entityplayer.getBukkitEntity().packetProcessor.close(); // Folia - region threading
+ entityplayer.getAdvancements().clearTriggers();
+ this.players.remove(entityplayer);
+ // Leaves - guard name removal so a photographer sharing a real player's name won't evict the real player's mapping
+ final String nameKey = entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT);
@@ -515,14 +519,14 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
public net.kyori.adventure.text.@Nullable Component remove(final ServerPlayer player) { // CraftBukkit - return string // Paper - return Component
// Paper start - Fix kick event leave message not being sent
return this.remove(player, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? player.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(player.getDisplayName())));
@@ -600,6 +763,7 @@ public abstract class PlayerList {
@@ -597,6 +760,7 @@ public abstract class PlayerList {
player.getBukkitEntity().packetProcessor.close(); // Folia - region threading
player.getAdvancements().stopListening();
player.getAdvancements().clearTriggers();
this.players.remove(player);
+ this.realPlayers.remove(player); // Leaves - replay api
this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
if (me.earthme.luminol.config.modules.misc.UsernameCheckConfig.allowOldPlayersJoin) this.playedPlayers.remove(player.getGameProfile().name()); // Leaf - Configurable vanilla username check
this.server.getCustomBossEvents().onPlayerDisconnect(player);
UUID uuid = player.getUUID();
@@ -910,15 +1074,15 @@ public abstract class PlayerList {
}
@@ -546,10 +550,10 @@ index 14be3d21cc1a613b1d9164ecc699073f0da2047c..baa295f3dd8cf10bf7347ee4d1c249b1
// Leaves end - fakeplayer support
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 8a8de7f4d62532709805ebde531dc71ad78fa5c9..167855ad90d0c168a6d49f078ee3409ab84d4bf3 100644
index d64c68651b7142869a06ce0200fb625cd45ae235..1fe317cf3251bff7bb3e0335452a5714d4d31017 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -261,7 +261,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
@@ -276,7 +276,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
public int useItemRemaining;
protected int fallFlyTicks;
private long lastKineticHitFeedbackTime = -2147483648L;
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/da12a58e8d3bd3cd1
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java
index e302c6198d71782b524391329aa5c89d2b3e0ccf..2312803297321f66c9057bc54ce56dd17ecb6f1f 100644
index 700c9c0d40dee1df6c97f7c63ad731f16bc5f3e7..b95c56e0699fbe16e65efcf010cd514f0ac0962f 100644
--- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -199,7 +199,7 @@ public class ExperienceOrb extends Entity {
@@ -204,7 +204,7 @@ public class ExperienceOrb extends Entity {
Player prevTarget = this.followingPlayer; // CraftBukkit - store old target
if (this.followingPlayer == null || this.followingPlayer.isSpectator() || this.followingPlayer.distanceToSqr(this) > 64.0) {
Player nearestPlayer = this.level().getNearestPlayer(this, 8.0);
@@ -21,10 +21,10 @@ index e302c6198d71782b524391329aa5c89d2b3e0ccf..2312803297321f66c9057bc54ce56dd1
} else {
this.followingPlayer = null;
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 38689fa466a20c64f9916ee32a57a9fdb58d9403..ea5de9aca4908ed972c4f44bff635f2cc423a04f 100644
index f063e9b7601480d0e66da22ea8e5bec2e8619fee..d46abbea2153cac2d939416fafeac7f905fe0e02 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -279,8 +279,8 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -284,8 +284,8 @@ public abstract class Player extends Avatar implements ContainerUser {
if (this.cullTask != null) this.cullTask.requestCullSignal(); // Luminol - Ray tracing entity tracker
// Luminol end
@@ -35,7 +35,7 @@ index 38689fa466a20c64f9916ee32a57a9fdb58d9403..ea5de9aca4908ed972c4f44bff635f2c
this.setOnGround(false);
}
@@ -406,7 +406,7 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -411,7 +411,7 @@ public abstract class Player extends Avatar implements ContainerUser {
if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) {
Pose desiredPose = this.getDesiredPose();
Pose actualPose;
@@ -44,7 +44,7 @@ index 38689fa466a20c64f9916ee32a57a9fdb58d9403..ea5de9aca4908ed972c4f44bff635f2c
actualPose = desiredPose;
} else if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)) {
actualPose = Pose.CROUCHING;
@@ -535,7 +535,7 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -540,7 +540,7 @@ public abstract class Player extends Avatar implements ContainerUser {
this.updateSwingTime();
this.yHeadRot = this.getYRot();
this.setSpeed((float)this.getAttributeValue(Attributes.MOVEMENT_SPEED));
@@ -53,7 +53,7 @@ index 38689fa466a20c64f9916ee32a57a9fdb58d9403..ea5de9aca4908ed972c4f44bff635f2c
AABB pickupArea;
if (this.isPassenger() && !this.getVehicle().isRemoved()) {
pickupArea = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0, 0.0, 1.0);
@@ -1846,6 +1846,26 @@ public abstract class Player extends Avatar implements ContainerUser {
@@ -1872,6 +1872,26 @@ public abstract class Player extends Avatar implements ContainerUser {
return this.gameMode() == GameType.SPECTATOR;
}
@@ -81,10 +81,10 @@ index 38689fa466a20c64f9916ee32a57a9fdb58d9403..ea5de9aca4908ed972c4f44bff635f2c
public boolean isPickable() {
return !this.isSpectator() && super.isPickable();
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
index 2e2a8af12f249ec5bd0935fd13f5acbd0a777b5f..07b84bd0144e133d13e8e033a8998f3cf674f746 100644
index 0f4ac8eeb8f5f866b22a81f255f7169754437bfc..3b5aa0c45647c694e908aaae2a027db02b4f8385 100644
--- a/net/minecraft/world/item/BlockItem.java
+++ b/net/minecraft/world/item/BlockItem.java
@@ -158,8 +158,9 @@ public class BlockItem extends Item {
@@ -162,8 +162,9 @@ public class BlockItem extends Item {
Player player = context.getPlayer();
// CraftBukkit start
Level world = context.getLevel(); // Paper - Cancel hit for vanished players
@@ -96,7 +96,7 @@ index 2e2a8af12f249ec5bd0935fd13f5acbd0a777b5f..07b84bd0144e133d13e8e033a8998f3c
org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(
diff --git a/net/minecraft/world/item/StandingAndWallBlockItem.java b/net/minecraft/world/item/StandingAndWallBlockItem.java
index cb0a4a9865df69e5504a86de6c144bc4450bd19a..596fb91fccb4c8d6854fa859f9ee357c6d22a81e 100644
index 1f17f966882320b3a2ced50b3f73925cd0dfa14c..5a75df997c9026bcc740823d7039c8e426ea345a 100644
--- a/net/minecraft/world/item/StandingAndWallBlockItem.java
+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java
@@ -44,7 +44,7 @@ public class StandingAndWallBlockItem extends BlockItem {
@@ -109,7 +109,7 @@ index cb0a4a9865df69e5504a86de6c144bc4450bd19a..596fb91fccb4c8d6854fa859f9ee357c
org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(org.bukkit.craftbukkit.block.CraftBlock.at(context.getLevel(), pos), player, stateForPlacement.asBlockData(), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent
diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
index 6205f52ecad24f80d21b924945c5ff06c6704aca..d84159df4d2a0379ffbb6bdb0807b4a02dbec71e 100644
index 8025fec49e6b9550d6154d6e735c6a39a2352f24..2c27de099c203b51b0fb317a8160402b3189e41c 100644
--- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
@@ -153,7 +153,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
@@ -122,7 +122,7 @@ index 6205f52ecad24f80d21b924945c5ff06c6704aca..d84159df4d2a0379ffbb6bdb0807b4a0
MoverType.SHULKER_BOX,
new Vec3(
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 2ecb10fe97d15954e44c61247eabc8818eb16f34..22663ad55f669081b43644ad2cf1bd4aac48b745 100644
index 15605dacaec3860e476a70dbdd3743e4197f67a6..199f23547fded9b7d311b9cf21484d863748fd1c 100644
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -168,7 +168,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
@@ -10,40 +10,40 @@ Licensed under: MIT
This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet)
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index d036018ee64995ee754296014888ee70c0ea5ab3..aa782c6441cdce3eb39aefb28d40f3b1970d4e62 100644
index 7d35b299533640338aeea6e5617942e89269d048..569f96a1b0b8a03b6a70775f4b7f58a66feed939 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -239,8 +239,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
changed |= action.getAsBoolean(); // Paper - note: this is not a validator, it's what adds/sucks in items
}
@@ -240,8 +240,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
changed |= action.getAsBoolean();
}
+ // Leaves start - Wool hopper counter
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
+ net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, entity.getBlockPos().relative(state.getValue(HopperBlock.FACING)));
+ if (woolColor != null) {
+ for (int i = 0; i < Short.MAX_VALUE; i++) {
+ changed |= suckInItems(level, entity);
+ if (!changed) {
+ break;
+ } else {
+ woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos));
+ }
+ // Leaves start - Wool hopper counter
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
+ net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, entity.getBlockPos().relative(state.getValue(HopperBlock.FACING)));
+ if (woolColor != null) {
+ for (int i = 0; i < Short.MAX_VALUE; i++) {
+ changed |= suckInItems(level, entity);
+ if (!changed) {
+ break;
+ } else {
+ woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos));
+ }
+ }
+ }
+ // Leaves end - Wool hopper counter
+ }
+ // Leaves end - Wool hopper counter
+
if (changed) {
entity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
+ // Leaves start - Wool hopper counter
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos))) {
+ entity.setCooldown(0);
+ return true;
+ }
+ // Leaves end - Wool hopper counter
setChanged(level, pos, state);
// Leaves start - Lithium Sleeping Block Entity
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled
if (changed) {
entity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
+ // Leaves start - Wool hopper counter
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos))) {
+ entity.setCooldown(0);
+ return true;
+ }
+ // Leaves end - Wool hopper counter
setChanged(level, pos, state);
// Leaves start - Lithium Sleeping Block Entity
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled
@@ -491,6 +513,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
// Paper end - Perf: Optimize Hoppers
@@ -59,7 +59,7 @@ index d036018ee64995ee754296014888ee70c0ea5ab3..aa782c6441cdce3eb39aefb28d40f3b1
if (container == null) {
return false;
@@ -512,6 +541,26 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
return hopperPush(level, container, direction, self); // Paper - Perf: Optimize Hoppers
}
+ // Leaves start - hopper counter
@@ -5,10 +5,10 @@ Subject: [PATCH] Global Entities Counter
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
index 0cf5815672ac62d8caf7f18165be1f0f8e067aed..64d407c5a6140a7e5dc47a8e304b4c00602e2bdd 100644
index 24e186d05aa0333885178f444fade3b9c930ac97..5724a276cf4fdd41f239c47e4352ec05736a5e49 100644
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -558,6 +558,9 @@ public final class RegionizedWorldData {
@@ -563,6 +563,9 @@ public final class RegionizedWorldData {
public final Map<Long, ChunkSectionItemEntityMovementTracker> itemEntityMovementTrackerMap = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>();
// Luminol end
@@ -18,15 +18,15 @@ index 0cf5815672ac62d8caf7f18165be1f0f8e067aed..64d407c5a6140a7e5dc47a8e304b4c00
public final TickRegions.TickRegionData regionData;
public RegionizedWorldData(final ServerLevel world, final TickRegions.TickRegionData regionData) {
@@ -570,6 +573,15 @@ public final class RegionizedWorldData {
@@ -575,6 +578,15 @@ public final class RegionizedWorldData {
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
this.regionData = regionData;
+ // Lophine start - Global Entities Counter
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled()) {
+ uniqueId = fun.bm.lophine.utils.EntitiesCounterUtil.generateUniqueId();
+ fun.bm.lophine.utils.EntitiesCounterUtil.reportAreaMap(world, spawnChunkTracker, uniqueId);
+ fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(world, loadedEntities, uniqueId);
+ if (!fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isDefaultModule()) fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(world, loadedEntities, uniqueId);
+ underGlobalEntitiesCounter = true;
+ }
+ // Lophine end - Global Entities Counter
@@ -35,15 +35,15 @@ index 0cf5815672ac62d8caf7f18165be1f0f8e067aed..64d407c5a6140a7e5dc47a8e304b4c00
this.updateTickData();
}
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 27389ff98942e27c2a877ea5b671caa31353d18c..e9e5f929d638d3ddf279423d3e23b3f824ad7df2 100644
index 0011653c857ee82f86355cc49b170120d9f96cfd..237ac6912f3b30c0405493b6ce9ca4765c19f985 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -513,6 +513,25 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -511,6 +511,26 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
this.chunkMap.tick(haveTime);
profiler.pop();
this.clearCache();
+ // Lophine start - Global Entities Counter
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled()) {
+ io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData();
+ if (regionizedWorldData != null) {
+ if (regionizedWorldData.underGlobalEntitiesCounter) {
@@ -53,6 +53,7 @@ index 27389ff98942e27c2a877ea5b671caa31353d18c..e9e5f929d638d3ddf279423d3e23b3f8
+ }
+ } else {
+ if (!regionizedWorldData.getLocalPlayers().isEmpty()) {
+ regionizedWorldData.uniqueId = fun.bm.lophine.utils.EntitiesCounterUtil.generateUniqueId();
+ fun.bm.lophine.utils.EntitiesCounterUtil.reportAreaMap(level, regionizedWorldData.spawnChunkTracker, regionizedWorldData.uniqueId);
+ fun.bm.lophine.utils.EntitiesCounterUtil.addDataToLoaded(level, (ca.spottedleaf.moonrise.common.list.ReferenceList<Entity>) regionizedWorldData.getLoadedEntities(), regionizedWorldData.uniqueId);
+ regionizedWorldData.underGlobalEntitiesCounter = true;
@@ -64,14 +65,14 @@ index 27389ff98942e27c2a877ea5b671caa31353d18c..e9e5f929d638d3ddf279423d3e23b3f8
}
private void tickChunks() {
@@ -577,7 +596,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -575,7 +595,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
}
spawnCookie = NaturalSpawner.createState(chunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
} else {
- spawnCookie = NaturalSpawner.createState(chunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
+ // Lophine start - Global Entities Counter
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
+ spawnCookie = fun.bm.lophine.utils.EntitiesCounterUtil.runRemainingTasks(level, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false);
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled()) {
+ spawnCookie = fun.bm.lophine.utils.EntitiesCounterUtil.createSpawnState(level, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false);
+ } else {
+ spawnCookie = NaturalSpawner.createState(chunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
+ }
@@ -79,7 +80,7 @@ index 27389ff98942e27c2a877ea5b671caa31353d18c..e9e5f929d638d3ddf279423d3e23b3f8
}
} finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler
// Paper end - Optional per player mob spawns
@@ -585,7 +610,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -583,7 +609,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
boolean doMobSpawning = this.level.getGameRules().get(GameRules.SPAWN_MOBS) && !this.level.getLocalPlayers().isEmpty(); // CraftBukkit // Folia - region threading
int tickSpeed = this.level.getGameRules().get(GameRules.RANDOM_TICK_SPEED);
List<MobCategory> spawningCategories;
@@ -88,7 +89,7 @@ index 27389ff98942e27c2a877ea5b671caa31353d18c..e9e5f929d638d3ddf279423d3e23b3f8
// Paper start - PlayerNaturallySpawnCreaturesEvent
for (ServerPlayer player : this.level.getLocalPlayers()) { // Folia - region threading
int chunkRange = Math.min(level.spigotConfig.mobSpawnRange, player.getBukkitEntity().getViewDistance());
@@ -645,7 +670,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -643,7 +669,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
this.level.tickThunder(chunk);
}
@@ -98,31 +99,67 @@ index 27389ff98942e27c2a877ea5b671caa31353d18c..e9e5f929d638d3ddf279423d3e23b3f8
NaturalSpawner.spawnForChunk(this.level, chunk, spawnCookie, spawningCategories);
}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 8d6a5d2ab4589f81abdd4ae939f197051e9523fc..54011666a2f358fe38ca03bc39d68d122011c796 100644
index 598867ffa41c8d38e0c18550071ac25935e34229..eee0cd75cc0e551cb521be190c40044cca313c5b 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -808,6 +808,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -822,6 +822,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
}
public void tick(BooleanSupplier haveTime, final io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking
+ // Lophine start - Global Entities Counter
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled()) {
+ if (fun.bm.lophine.utils.EntitiesCounterUtil.canRunNewTask(this)) fun.bm.lophine.utils.EntitiesCounterUtil.tick(this);
+ }
+ // Lophine end - Global Entities Counter
final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
ProfilerFiller profiler = Profiler.get();
@@ -2884,6 +2889,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
public void close() throws IOException {
super.close();
//this.entityManager.close(); // Paper - rewrite chunk system
+ // Lophine start - Precise mob cap
+ if (!fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isDefaultModule()) {
+ fun.bm.lophine.utils.EntitiesCounterUtil.onWorldUnload(this);
+ }
+ // Lophine end - Precise mob cap
}
@Override
@@ -3113,6 +3123,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
entity.inWorld = true; // CraftBukkit - Mark entity as in world
entity.valid = true; // CraftBukkit
ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server
+ // Lophine start - Precise mob cap
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled() && !fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isDefaultModule()) {
+ fun.bm.lophine.utils.EntitiesCounterUtil.onEntityTrackingStart(ServerLevel.this, entity);
+ }
+ // Lophine end - Precise mob cap
// Paper start - Entity origin API
if (entity.origin == null) {
entity.origin = entity.position();
@@ -3128,6 +3143,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@Override
public void onTrackingEnd(final Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
+ // Lophine start - Precise mob cap
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled() && !fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isDefaultModule()) {
+ fun.bm.lophine.utils.EntitiesCounterUtil.onEntityTrackingEnd(ServerLevel.this, entity);
+ }
+ // Lophine end - Precise mob cap
ServerLevel.this.getCurrentWorldData().removeLoadedEntity(entity); // Folia - region threading
// Spigot start // TODO I don't think this is needed anymore
if (entity instanceof Player player) {
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index fc29654dd7ee3329edf1ccf705f45631d0ecc079..5cad076041ed008670cfd8e51a3601c2ef972ad1 100644
index e7ebdbb8d77f841551c5ebb0f8e7b4402f6a4751..f3813df2734c9bc1fcecb317b8450ff13b9706dd 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -813,6 +813,44 @@ public abstract class Mob extends LivingEntity implements Targeting, EquipmentUs
@@ -826,6 +826,44 @@ public abstract class Mob extends LivingEntity implements Targeting, EquipmentUs
}
}
} else {
+ // Lophine start - fix some bug if player is cross scheduler >> to remove monster if the region don't have any valid player
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.enabled) {
+ if (fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter.isEnabled()) {
+ List<net.minecraft.server.level.ServerPlayer> playerList = this.level().getServer().getPlayerList().getPlayers();
+ if (!playerList.isEmpty()) {
+ double d = -1.0;
@@ -158,12 +195,12 @@ index fc29654dd7ee3329edf1ccf705f45631d0ecc079..5cad076041ed008670cfd8e51a3601c2
+ }
+ }
+ }
+ // Lophine end
+ // Lophine end - fix some bug if player is cross scheduler >> to remove monster if the region don't have any valid player
this.noActionTime = 0;
}
}
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index b3b8160927147468c1dd4a30fac51f96a9d60c9a..cd20d10ee4cd2fe98131c9a93367ae133f96b8d4 100644
index 500dcbe924fca160bd673592e1aba384f6eb9ed2..0d8d2459457167d78a9a9ea43765980240416947 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -121,7 +121,7 @@ public final class NaturalSpawner {
@@ -175,7 +212,7 @@ index b3b8160927147468c1dd4a30fac51f96a9d60c9a..cd20d10ee4cd2fe98131c9a93367ae13
return chunk.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())).value();
}
@@ -628,7 +628,7 @@ public final class NaturalSpawner {
@@ -625,7 +625,7 @@ public final class NaturalSpawner {
private @Nullable EntityType<?> lastCheckedType;
private double lastCharge;
@@ -8,49 +8,56 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/network/PacketProcessor.java b/net/minecraft/network/PacketProcessor.java
index 24f5b890b0126fc817863f99b676da1a548f7608..78bea975c15130c91c90f48c868ac32e2db7433f 100644
index 10fa576838c726d026df078eef6c693d14c2cbda..03c4fab3f9be4f69d8c418e6fdd88211cb1b6ff7 100644
--- a/net/minecraft/network/PacketProcessor.java
+++ b/net/minecraft/network/PacketProcessor.java
@@ -106,7 +106,19 @@ public class PacketProcessor implements AutoCloseable {
@@ -105,7 +105,23 @@ public class PacketProcessor implements AutoCloseable {
final int packetTimerId = profiler.getOrCreateTimerAndStart(() -> "Packet Handler: ".concat(ListenerAndPacket.this.packet.getClass().getName())); try { // Folia - profiler
this.packet.handle(this.listener);
} finally { profiler.stopTimer(packetTimerId); } // Folia - profiler
+ // Lophine start - catch update suppression crash
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ if (this.listener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl gamePacketListener) {
+ exception.providePlayer(gamePacketListener.player);
+ }
+ exception.consume();
} catch (Exception var3) {
+ if (var3.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ // Lophine end - catch update suppression crash
} catch (Exception e) {
+ // Lophine start - catch update suppression crash
+ if (e.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ if (this.listener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl gamePacketListener) {
+ exception.providePlayer(gamePacketListener.player);
+ }
+ exception.consume();
+ }
+
if (var3 instanceof ReportedException re && re.getCause() instanceof OutOfMemoryError) {
throw PacketUtils.makeReportedException(var3, this.packet, this.listener);
+ // Lophine end - catch update suppression crash
if (e instanceof ReportedException re && re.getCause() instanceof OutOfMemoryError) {
throw PacketUtils.makeReportedException(e, this.packet, this.listener);
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 3b9a4f4b5794faa4955018858c94fd5c2d6ada3d..19bef18e606d873308d08987d90e298703efb574 100644
index 67bdd2887afed082fd1bae03f030f2d25d55e282..64c4dc62b5dbfee8ae4df3efb9dcbc5740ff22fd 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -2019,11 +2019,26 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1988,11 +1988,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
try {
foliaProfiler.startTimer(level.tickTimerId); try { // Folia - profiler
level.tick(haveTime, region); // Folia - region threading
+ // Lophine start - catch update suppression crash
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ exception.provideLevel(level);
+ exception.consume();
+ // Lophine end - catch update suppression crash
} finally { foliaProfiler.stopTimer(level.tickTimerId); } // Folia - profiler
} catch (Throwable var7) {
- CrashReport report = CrashReport.forThrowable(var7, "Exception ticking world");
} catch (Throwable t) {
- CrashReport report = CrashReport.forThrowable(t, "Exception ticking world");
- level.fillReportDetails(report);
- throw new ReportedException(report);
+ // Lophine start - catch update suppression crash
+ org.leavesmc.leaves.util.UpdateSuppressionException updateSuppressionException = null;
+ if (var7 instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ if (t instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ updateSuppressionException = exception;
+ } else if (var7.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ } else if (t.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ updateSuppressionException = exception;
+ }
+
@@ -58,22 +65,24 @@ index 3b9a4f4b5794faa4955018858c94fd5c2d6ada3d..19bef18e606d873308d08987d90e2987
+ updateSuppressionException.provideLevel(level);
+ updateSuppressionException.consume();
+ } else {
+ CrashReport report = CrashReport.forThrowable(var7, "Exception ticking world");
+ CrashReport report = CrashReport.forThrowable(t, "Exception ticking world");
+ level.fillReportDetails(report);
+ throw new ReportedException(report);
+ }
+ // Lophine end - catch update suppression crash
}
profiler.pop();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 54011666a2f358fe38ca03bc39d68d122011c796..3496696c6b023e7df95027917b3391557dddd8d0 100644
index eee0cd75cc0e551cb521be190c40044cca313c5b..6e830a841802cf121dcb9ba245e30ab7a6567e83 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -967,7 +967,16 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -956,7 +956,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
// Kaiiju end
profiler.push("tick");
- this.guardEntityTick(this::tickNonPassenger, entity);
+ // Lophine start - catch update suppression crash
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.mergedUpdateSuppressionCrashEnabled()) {
+ try {
+ this.guardEntityTick(this::tickNonPassenger, entity);
@@ -84,33 +93,38 @@ index 54011666a2f358fe38ca03bc39d68d122011c796..3496696c6b023e7df95027917b339155
+ } else {
+ this.guardEntityTick(this::tickNonPassenger, entity);
+ }
+ // Lophine end - catch update suppression crash
profiler.pop();
}
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 423652d0ccef5c6a3b93480401c3d0f672bbf8a5..65965089d184695588c74294afb2f5c0b28bbf17 100644
index 64943c193ae73795ddf8222a6f71ea5eb1705fe2..4034b4b9bd5e567b882169b5b1e17f75b64ba8db 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1130,6 +1130,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1111,6 +1111,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
// Folia - region threading - move to main tick loop where we can detect duplicates
// CraftBukkit end
+ // Lophine start - catch update suppression crash
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ exception.providePlayer(this);
+ exception.provideLevel(this.level());
+ exception.consume();
} catch (Throwable var4) {
CrashReport report = CrashReport.forThrowable(var4, "Ticking player");
+ // Lophine end - catch update suppression crash
} catch (Throwable t) {
CrashReport report = CrashReport.forThrowable(t, "Ticking player");
CrashReportCategory category = report.addCategory("Player being ticked");
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 07c5fed7b0bf3ecefb54ccb0bfb922c2f11f7939..8a92d1748464ef8d1d33e51163a3e0d74120e5a7 100644
index 8631acfea913aceabefad3d418d282042bbaca1a..dc9923eab641873412d2832c0ef7c579ac453bca 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1459,7 +1459,15 @@ public abstract class Entity
}
@@ -1522,8 +1522,18 @@ public abstract class Entity
}
if (shouldVibrate) {
- this.level().gameEvent(GameEvent.STEP, this.position(), GameEvent.Context.of(this, blockState));
if (shouldVibrate) {
- this.level().gameEvent(GameEvent.STEP, this.position(), GameEvent.Context.of(this, blockState));
- }
+ // Lophine start - catch update suppression crash
+ try {
+ this.level().gameEvent(GameEvent.STEP, this.position(), GameEvent.Context.of(this, blockState));
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
@@ -120,18 +134,21 @@ index 07c5fed7b0bf3ecefb54ccb0bfb922c2f11f7939..8a92d1748464ef8d1d33e51163a3e0d7
+ }
+ exception.consume();
+ }
}
+ // Lophine end - catch update suppression crash
+ }
return true;
return true;
} else {
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
index 08ad9f418fbe733b788ec27e13b61994c3a5f09d..c0b086fd5084fc0e39b91d3f6bd6904ef19f4157 100644
index ccc3a380f892d1238952a224c7cbb15938cbfd92..f347e27ac957c1cdcaaf29f61fdc2ca4bdc36dbb 100644
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
@@ -181,7 +181,14 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
@@ -183,7 +183,16 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
@Override
protected int getAnalogOutputSignal(final BlockState state, final Level level, final BlockPos pos, final Direction direction) {
- return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
+ // Lophine start - catch update suppression crash
+ try {
+ return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
+ } catch (ClassCastException ex) {
@@ -140,18 +157,20 @@ index 08ad9f418fbe733b788ec27e13b61994c3a5f09d..c0b086fd5084fc0e39b91d3f6bd6904e
+ }
+ throw ex;
+ }
+ // Lophine end - catch update suppression crash
}
public @Nullable DyeColor getColor() {
diff --git a/net/minecraft/world/level/block/state/StateHolder.java b/net/minecraft/world/level/block/state/StateHolder.java
index b72861c0164ebb13b6fc3e78cd7ce0a2c484f22d..6d3af2481e81795771ac8f82d984681ec8c9e0b9 100644
index 47a4aa4a45978dfec52ea995d197022f4fe32808..2a5a32ea8757ef9d03d5a9a9cb68be63a31e789a 100644
--- a/net/minecraft/world/level/block/state/StateHolder.java
+++ b/net/minecraft/world/level/block/state/StateHolder.java
@@ -118,7 +118,14 @@ public abstract class StateHolder<O, S> implements ca.spottedleaf.moonrise.patch
@@ -117,7 +117,16 @@ public abstract class StateHolder<O, S> implements ca.spottedleaf.moonrise.patch
if (ret != null) {
return ret;
}
- throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner);
+ // Lophine start - catch update suppression crash
+ IllegalArgumentException iae = new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner);
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.mergedUpdateSuppressionCrashEnabled()) {
+ org.leavesmc.leaves.util.UpdateSuppressionException exception = new org.leavesmc.leaves.util.UpdateSuppressionException(null, null, null, null, iae);
@@ -160,54 +179,61 @@ index b72861c0164ebb13b6fc3e78cd7ce0a2c484f22d..6d3af2481e81795771ac8f82d984681e
+ }
+ }
+ throw iae;
+ // Lophine end - catch update suppression crash
// Paper end - optimise blockstate property access
}
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 3708f9ffc46a5b1c038c0e7b2ce84802e2b22397..7760a711f4c49fc3499bf71fabb59ee8b4c85083 100644
index f4f56ec250b72df03f7e049250606c0e8b0f2990..668e2b12d706ba2b0727ac7e2ba0698d997e415b 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -400,6 +400,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
return null;
} else {
Block newBlock = state.getBlock();
+ try {
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(localX, y, localZ, state);
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(localX, y, localZ, state);
this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR).update(localX, y, localZ, state);
@@ -468,6 +469,10 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
this.markUnsaved();
return oldState;
}
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ exception.provideBlock(this.level, pos, newBlock);
+ throw exception;
+ }
}
@@ -401,6 +401,8 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
}
Block newBlock = state.getBlock();
+ // Lophine start - catch update suppression crash
+ try {
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(localX, y, localZ, state);
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(localX, y, localZ, state);
this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR).update(localX, y, localZ, state);
@@ -469,6 +471,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
this.markUnsaved();
return oldState;
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ exception.provideBlock(this.level, pos, newBlock);
+ throw exception;
+ }
+ // Lophine end - catch update suppression crash
}
@Deprecated
diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java
index 9b8d63f69ed1101f1b7b2728690e35165b9aeb99..6d25139a94df7c0442cc9fea96d5839ce8a23d54 100644
index 44dbe6f83c8593c213132feabc7fe27615cb0049..90145a3ea384b568897ee665b80b24cccba1b6c5 100644
--- a/net/minecraft/world/level/redstone/NeighborUpdater.java
+++ b/net/minecraft/world/level/redstone/NeighborUpdater.java
@@ -87,9 +87,20 @@ public interface NeighborUpdater {
@@ -87,9 +87,24 @@ public interface NeighborUpdater {
} finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
// Spigot start
} catch (StackOverflowError ex) {
+ // Lophine start - catch update suppression crash
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.mergedUpdateSuppressionCrashEnabled()) {
+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, level, changedBlock, null, ex);
+ }
+ // Lophine end - catch update suppression crash
level.lastPhysicsProblem = pos.immutable();
// Spigot end
} catch (Throwable var9) {
} catch (Throwable t) {
+ // Lophine start - catch update suppression crash
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.mergedUpdateSuppressionCrashEnabled()) {
+ if (var9 instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ if (t instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
+ exception.provideBlock(level, pos, changedBlock);
+ throw exception;
+ }
+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, level, changedBlock, null, var9);
+ throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, level, changedBlock, null, t);
+ }
+
CrashReport report = CrashReport.forThrowable(var9, "Exception while updating neighbours");
+ // Lophine end - catch update suppression crash
CrashReport report = CrashReport.forThrowable(t, "Exception while updating neighbours");
CrashReportCategory category = report.addCategory("Block being updated");
category.setDetail(
@@ -8,17 +8,19 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
index c0b086fd5084fc0e39b91d3f6bd6904ef19f4157..8259f530ec50554906c254b60f1e964b52c02852 100644
index f347e27ac957c1cdcaaf29f61fdc2ca4bdc36dbb..0dc80ee92f2aed4c8ca4bc60f4b189af764fe81d 100644
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
@@ -182,7 +182,9 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
@Override
@@ -185,7 +185,11 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
protected int getAnalogOutputSignal(final BlockState state, final Level level, final BlockPos pos, final Direction direction) {
// Lophine start - catch update suppression crash
try {
- return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
+ // Lophine start - configurable shulker CCE
+ return fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.shulkerBoxCCEReintroduced
+ ? AbstractContainerMenu.getRedstoneSignalFromContainer((net.minecraft.world.Container)level.getBlockEntity(pos))
+ : AbstractContainerMenu.getRedstoneSignalFromBlockEntity(level.getBlockEntity(pos));
+ // Lophine end - configurable shulker CCE
} catch (ClassCastException ex) {
if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.mergedUpdateSuppressionCrashEnabled()) {
throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, null, this, null, ex);
@@ -10,55 +10,63 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/level/block/ComparatorBlock.java b/net/minecraft/world/level/block/ComparatorBlock.java
index 45e11737bc2558a4ebfffe133d43111f45dd7d16..d3bcef3fa3228c3869041754b2c18dfc987aac35 100644
index 499311de746f868c092e34ff5fffeb37ec8e338a..eac6501e9242bb5b550bab1aeab4868602eb097b 100644
--- a/net/minecraft/world/level/block/ComparatorBlock.java
+++ b/net/minecraft/world/level/block/ComparatorBlock.java
@@ -59,6 +59,9 @@ public class ComparatorBlock extends DiodeBlock implements EntityBlock {
@@ -59,6 +59,11 @@ public class ComparatorBlock extends DiodeBlock implements EntityBlock {
final BlockState neighbourState,
final RandomSource random
) {
+ // Lophine start - redstone ignore upwards update
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.dustTrapdoorReintroduced && directionToNeighbour == Direction.DOWN) {
+ return state;
+ }
+ // Lophine end - redstone ignore upwards update
return directionToNeighbour == Direction.DOWN && !this.canSurviveOn(level, neighbourPos, neighbourState)
? Blocks.AIR.defaultBlockState()
: super.updateShape(state, level, ticks, pos, directionToNeighbour, neighbourPos, neighbourState, random);
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
index 759eb347299813c20226cc2fc5dc7718d12b7f56..619f5e37919693fc5976aedefed3bb5428395439 100644
index 957c45b39e9d6f74fb9791ecd121b0e2bd6bc732..973d423a9ab5a6a3338f43c27f6d99d7b7d94301 100644
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -179,7 +179,9 @@ public class RedStoneWireBlock extends Block {
@@ -179,7 +179,11 @@ public class RedStoneWireBlock extends Block {
final RandomSource random
) {
if (directionToNeighbour == Direction.DOWN) {
- return !this.canSurviveOn(level, neighbourPos, neighbourState) ? Blocks.AIR.defaultBlockState() : state;
+ // Lophine start - redstone ignore upwards update
+ return fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.dustTrapdoorReintroduced
+ ? state
+ : !this.canSurviveOn(level, neighbourPos, neighbourState) ? Blocks.AIR.defaultBlockState() : state;
} else if (directionToNeighbour == Direction.UP) {
return this.getConnectionState(level, state, pos);
} else {
@@ -243,7 +245,8 @@ public class RedStoneWireBlock extends Block {
+ // Lophine end - redstone ignore upwards update
}
if (directionToNeighbour == Direction.UP) {
@@ -243,7 +247,10 @@ public class RedStoneWireBlock extends Block {
BlockPos relativePos = pos.relative(direction);
BlockState relativeState = level.getBlockState(relativePos);
if (canConnectUp) {
- boolean isPlaceableAbove = relativeState.getBlock() instanceof TrapDoorBlock || this.canSurviveOn(level, relativePos, relativeState);
+ // Lophine start - redstone ignore upwards update
+ boolean isPlaceableAbove = (!fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.dustTrapdoorReintroduced && relativeState.getBlock() instanceof TrapDoorBlock)
+ || this.canSurviveOn(level, relativePos, relativeState);
+ // Lophine end - redstone ignore upwards update
if (isPlaceableAbove && shouldConnectTo(level.getBlockState(relativePos.above()))) {
if (relativeState.isFaceSturdy(level, relativePos, direction.getOpposite())) {
return RedstoneSide.UP;
diff --git a/net/minecraft/world/level/block/RepeaterBlock.java b/net/minecraft/world/level/block/RepeaterBlock.java
index d301ca4c91e75d715998aa7ed155fd44ccd64785..cc2694d0fc3c9bbe5e91771b3aef8ffb749515b4 100644
index 407d1025dbc7c57114c07e41789f12a36d39952d..800539bae071c845864a390f0346707abb899657 100644
--- a/net/minecraft/world/level/block/RepeaterBlock.java
+++ b/net/minecraft/world/level/block/RepeaterBlock.java
@@ -70,6 +70,9 @@ public class RepeaterBlock extends DiodeBlock {
@@ -70,6 +70,11 @@ public class RepeaterBlock extends DiodeBlock {
final BlockState neighbourState,
final RandomSource random
) {
+ // Lophine start - redstone ignore upwards update
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.dustTrapdoorReintroduced && directionToNeighbour == Direction.DOWN) {
+ return state;
+ }
+ // Lophine end - redstone ignore upwards update
if (directionToNeighbour == Direction.DOWN && !this.canSurviveOn(level, neighbourPos, neighbourState)) {
return Blocks.AIR.defaultBlockState();
} else {
@@ -5,30 +5,32 @@ Subject: [PATCH] Instant Block Updater
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
index 64d407c5a6140a7e5dc47a8e304b4c00602e2bdd..1a426e1aa456a8ea432f62483c3be5c328b97953 100644
index 5724a276cf4fdd41f239c47e4352ec05736a5e49..3a50e625160d0dad6bd8fa534b719087dae7881d 100644
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -506,7 +506,7 @@ public final class RegionizedWorldData {
@@ -509,7 +509,7 @@ public final class RegionizedWorldData {
public long lastMidTickExecuteFailure;
// From Level
public boolean populating;
- public final CollectingNeighborUpdater neighborUpdater;
+ public final net.minecraft.world.level.redstone.NeighborUpdater neighborUpdater;
+ public final net.minecraft.world.level.redstone.NeighborUpdater neighborUpdater; // Lophine - Instant Block Updater
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
public final Map<BlockPos, CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
@@ -567,7 +567,9 @@ public final class RegionizedWorldData {
@@ -572,7 +572,11 @@ public final class RegionizedWorldData {
this.world = world;
this.blockLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, true);
this.fluidLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, false);
- this.neighborUpdater = new CollectingNeighborUpdater(world, world.neighbourUpdateMax);
+ // Lophine start - Instant Block Updater
+ this.neighborUpdater = fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.instantBlockUpdaterReintroduced
+ ? new net.minecraft.world.level.redstone.InstantNeighborUpdater(world)
+ : new CollectingNeighborUpdater(world, world.neighbourUpdateMax);
+ // Lophine end - Instant Block Updater
this.nearbyPlayers = new NearbyPlayers(world);
this.wireHandler = new alternate.current.wire.WireHandler(world);
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
@@ -896,4 +898,4 @@ public final class RegionizedWorldData {
@@ -901,4 +905,4 @@ public final class RegionizedWorldData {
public int getChunkCount() {
return this.chunks.size();
}
@@ -36,10 +38,10 @@ index 64d407c5a6140a7e5dc47a8e304b4c00602e2bdd..1a426e1aa456a8ea432f62483c3be5c3
\ No newline at end of file
+}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 3496696c6b023e7df95027917b3391557dddd8d0..d8718805a965db11dfce8ed7f5ea65a638cc4510 100644
index 6e830a841802cf121dcb9ba245e30ab7a6567e83..ca68d73cdc0f679a5f653c8e2ae27f590d7a84b5 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -999,11 +999,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
@@ -990,11 +990,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
// Paper - rewrite chunk system
profiler.pop();
profiler.push("debugSynchronizers");
@@ -48,6 +50,7 @@ index 3496696c6b023e7df95027917b3391557dddd8d0..d8718805a965db11dfce8ed7f5ea65a6
- .setDebugListener(blockPos -> this.debugSynchronizers.broadcastEventToTracking(blockPos, DebugSubscriptions.NEIGHBOR_UPDATES, blockPos));
- } else {
- regionizedWorldData.neighborUpdater.setDebugListener(null); // Folia - region threading
+ // Lophine start - Instant Block Updater
+ if (regionizedWorldData.neighborUpdater instanceof net.minecraft.world.level.redstone.CollectingNeighborUpdater neighborUpdater) {
+ if (this.debugSynchronizers.hasAnySubscriberFor(DebugSubscriptions.NEIGHBOR_UPDATES)) {
+ neighborUpdater // Folia - region threading
@@ -55,6 +58,7 @@ index 3496696c6b023e7df95027917b3391557dddd8d0..d8718805a965db11dfce8ed7f5ea65a6
+ } else {
+ neighborUpdater.setDebugListener(null); // Folia - region threading
+ }
+ // Lophine end - Instant Block Updater
}
this.debugSynchronizers.tick(this.server.debugSubscribers());
@@ -5,10 +5,10 @@ Subject: [PATCH] Revert TrapDoorBlock changes form Paper
diff --git a/net/minecraft/world/level/block/TrapDoorBlock.java b/net/minecraft/world/level/block/TrapDoorBlock.java
index cfc8b668980e0cba74b3f0d42c4902eb6aa8b01e..da4a39e3e8bf9672614a04fae9834a54555cc9f1 100644
index 614f70a520d13f6fe422ac7e42808c813fb3506d..eb36bea7d3dd593539cdbc6938f1fe29df58dadf 100644
--- a/net/minecraft/world/level/block/TrapDoorBlock.java
+++ b/net/minecraft/world/level/block/TrapDoorBlock.java
@@ -133,31 +133,7 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
@@ -129,31 +129,7 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW
if (!level.isClientSide()) {
boolean signal = level.hasNeighborSignal(pos);
if (signal != state.getValue(POWERED)) {
@@ -37,7 +37,7 @@ index cfc8b668980e0cba74b3f0d42c4902eb6aa8b01e..da4a39e3e8bf9672614a04fae9834a54
- }
- if (open) {
- // Paper end - break redstone on trapdoors early
+ if (state.getValue(OPEN) != signal) {
+ if (state.getValue(OPEN) != signal) { // Lophine - revert Paper trapdoor redstone handling
state = state.setValue(OPEN, signal);
this.playSound(null, level, pos, signal);
}
@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Tue, 18 Nov 2025 23:26:27 +0800
Subject: [PATCH] Leaves: Do not reset placed block on exception & Do not
prevent block entity and entity crash at LevelChunk
Co-authored by: MC_XiaoHei <xiaohei.xor7@outlook.com>
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
index 07b84bd0144e133d13e8e033a8998f3cf674f746..9c016e7d93e4c44ddf2df520e5c57d92a0e085b3 100644
--- a/net/minecraft/world/item/BlockItem.java
+++ b/net/minecraft/world/item/BlockItem.java
@@ -69,20 +69,8 @@ public class BlockItem extends Item {
BlockState placedState = level.getBlockState(pos);
if (placedState.is(placementState.getBlock())) {
placedState = this.updateBlockStateFromTag(pos, level, itemStack, placedState);
- // Paper start - Reset placed block on exception
- try {
this.updateCustomBlockEntityTag(pos, level, player, itemStack, placedState);
updateBlockEntityComponents(level, pos, itemStack);
- } catch (Exception ex) {
- ((org.bukkit.craftbukkit.block.CraftBlockState) previousState).revertPlace();
- if (player instanceof ServerPlayer serverPlayer) {
- net.minecraft.server.MinecraftServer.LOGGER.warn("Player {} tried placing invalid block", player.getScoreboardName(), ex);
- serverPlayer.connection.disconnect(net.minecraft.network.chat.Component.literal("Packet processing error"));
- return InteractionResult.FAIL;
- }
- throw ex; // Rethrow exception if not placed by a player
- }
- // Paper end - Reset placed block on exception
placedState.getBlock().setPlacedBy(level, pos, placedState, player, itemStack);
// CraftBukkit start - special case for handling block placement with water lilies, frog spawn and snow buckets
if (player != null && (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem)) {
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 7760a711f4c49fc3499bf71fabb59ee8b4c85083..ef3508dc4c8b3a9c8a6c7ff520cf51a68d6a13d9 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1015,12 +1015,6 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
profiler.pop();
} catch (Throwable var5) {
- // Paper start - Prevent block entity and entity crashes
- final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", io.papermc.paper.util.MCUtil.getLevelName(LevelChunk.this.getLevel()), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
- net.minecraft.server.MinecraftServer.LOGGER.error(msg, var5);
- net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, var5))); // Paper - ServerExceptionEvent
- LevelChunk.this.removeBlockEntity(this.getPos());
- // Paper end - Prevent block entity and entity crashes
}
}
}
@@ -9,14 +9,15 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
index e1de10e1a0ec221a1109a03d86fddf47b1c06a5f..d8cba057be61005d75b8c66910096aec148e2e2a 100644
index 13e981bfd070d9351d8880478b5a86e39bcd73ad..d0ac2d15388e842ed56ec39ecdbc99994e0617bc 100644
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -392,7 +392,16 @@ public class ServerPlayerGameMode {
this.level.getCurrentWorldData().captureDrops = new java.util.ArrayList<>(); // Folia - region threading
// CraftBukkit end
BlockState adjustedState = block.playerWillDestroy(this.level, pos, state, this.player);
- boolean changed = this.level.removeBlock(pos, false);
@@ -394,7 +394,18 @@ public class ServerPlayerGameMode {
this.level.getCurrentWorldData().captureDrops = new java.util.ArrayList<>(); // Folia - region threading
// CraftBukkit end
BlockState adjustedState = block.playerWillDestroy(this.level, pos, state, this.player);
- boolean changed = this.level.removeBlock(pos, false);
+ // Lophine start - preserve drops before update suppression
+ boolean changed;
+ org.leavesmc.leaves.util.UpdateSuppressionException updateSuppressionException = null;
+ try {
@@ -27,16 +28,19 @@ index e1de10e1a0ec221a1109a03d86fddf47b1c06a5f..d8cba057be61005d75b8c66910096aec
+ updateSuppressionException.providePlayer(this.player);
+ changed = false;
+ }
if (SharedConstants.DEBUG_BLOCK_BREAK) {
LOGGER.info("server broke {} {} -> {}", pos, adjustedState, this.level.getBlockState(pos));
}
@@ -424,6 +433,9 @@ public class ServerPlayerGameMode {
if (event.isDropItems()) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, bState, this.player, itemsToDrop); // Paper - capture all item additions to the world
}
+ // Lophine end - preserve drops before update suppression
if (SharedConstants.DEBUG_BLOCK_BREAK) {
LOGGER.info("server broke {} {} -> {}", pos, adjustedState, this.level.getBlockState(pos));
}
@@ -422,6 +433,11 @@ public class ServerPlayerGameMode {
if (event.isDropItems()) {
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, bState, this.player, itemsToDrop); // Paper - capture all item additions to the world
}
+ // Lophine start - preserve drops before update suppression
+ if (updateSuppressionException != null) {
+ throw updateSuppressionException;
+ }
+ // Lophine end - preserve drops before update suppression
// Drop event experience
if (changed) {
// Drop event experience
if (changed) {
@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Tue, 18 Nov 2025 23:26:27 +0800
Subject: [PATCH] Leaves: Do not reset placed block on exception & Do not
prevent block entity and entity crash at LevelChunk
Co-authored by: MC_XiaoHei <xiaohei.xor7@outlook.com>
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
index 3b5aa0c45647c694e908aaae2a027db02b4f8385..aebcab247f49ada6af76b3c0e60944134d8f6f88 100644
--- a/net/minecraft/world/item/BlockItem.java
+++ b/net/minecraft/world/item/BlockItem.java
@@ -77,21 +77,8 @@ public class BlockItem extends Item {
java.util.function.UnaryOperator<InteractionResult.PaperSuccessContext> context = c -> c.placedBlockAt(pos.immutable()); // Paper - track placed block position from block item
if (placedState.is(placementState.getBlock())) {
placedState = this.updateBlockStateFromTag(pos, level, itemStack, placedState);
- // Paper start - Reset placed block on exception
- try {
- boolean updatedBlockEntity = this.updateCustomBlockEntityTag(pos, level, player, itemStack, placedState);
- context = context.andThen(c -> c.updatedBlockEntity(updatedBlockEntity))::apply; // track whether the block entity got updated or not
- updateBlockEntityComponents(level, pos, itemStack);
- } catch (Exception ex) {
- ((org.bukkit.craftbukkit.block.CraftBlockState) previousState).revertPlace(false);
- if (player instanceof ServerPlayer serverPlayer) {
- net.minecraft.server.MinecraftServer.LOGGER.warn("Player {} tried placing invalid block", player.getScoreboardName(), ex);
- serverPlayer.connection.disconnect(net.minecraft.network.chat.Component.literal("Packet processing error"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION);
- return InteractionResult.FAIL;
- }
- throw ex; // Rethrow exception if not placed by a player
- }
- // Paper end - Reset placed block on exception
+ this.updateCustomBlockEntityTag(pos, level, player, itemStack, placedState);
+ updateBlockEntityComponents(level, pos, itemStack);
placedState.getBlock().setPlacedBy(level, pos, placedState, player, itemStack);
// CraftBukkit start - special case for handling block placement with water lilies, frog spawn and snow buckets
if (player != null && (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem)) {
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 668e2b12d706ba2b0727ac7e2ba0698d997e415b..f103b1633f7483bd57da760e59fea132c63faec5 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1018,12 +1018,6 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
profiler.pop();
} catch (Throwable t) {
- // Paper start - Prevent block entity and entity crashes
- final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", io.papermc.paper.util.MCUtil.getLevelName(LevelChunk.this.getLevel()), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
- LevelChunk.LOGGER.error(msg, t);
- LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, t))); // Paper - ServerExceptionEvent
- LevelChunk.this.removeBlockEntity(this.getPos());
- // Paper end - Prevent block entity and entity crashes
}
}
}
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/Containers.java b/net/minecraft/world/Containers.java
index 1311d4936f84652c5ffc51544f99cb98fc293906..3a62831838a60776159dcb1ca783d3f00e6cd35e 100644
index e9e2ef680cfc72cd47fa13d72c03619d2f1ca5fc..6370f0eb9039941687d37a0fe387fbd676ec151b 100644
--- a/net/minecraft/world/Containers.java
+++ b/net/minecraft/world/Containers.java
@@ -51,4 +51,16 @@ public class Containers {
@@ -61,7 +61,7 @@ index 98561dcc465ca9d5394e58b05ad3e8dc59773ebc..72e3d6c1ce3389972df21d5ff6e4d74b
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/BarrelBlock.java b/net/minecraft/world/level/block/BarrelBlock.java
index 5332fd32fa7a0d3fc3be1b0a7c2ca5dee8e402c6..37667a8e512bdba385c563e950d8c5d5cdd18832 100644
index 7bb880bfa9008a431acfd7c5d543f1e5a4bb67b2..58e92db685204660b41de9bfc0a5092383c8ec18 100644
--- a/net/minecraft/world/level/block/BarrelBlock.java
+++ b/net/minecraft/world/level/block/BarrelBlock.java
@@ -51,6 +51,15 @@ public class BarrelBlock extends BaseEntityBlock {
@@ -81,7 +81,7 @@ index 5332fd32fa7a0d3fc3be1b0a7c2ca5dee8e402c6..37667a8e512bdba385c563e950d8c5d5
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/BasePressurePlateBlock.java b/net/minecraft/world/level/block/BasePressurePlateBlock.java
index c2fbf44e93e44c36423465d406b5e4d3db029a80..a28a453f139295834c77aa908027c74c8dfd7aba 100644
index f2d7c5fc0339a62c4fc56aa5871cd999e1136ca6..75d8bd8f7f3614dbdc89088fc12eb05b317ea0e0 100644
--- a/net/minecraft/world/level/block/BasePressurePlateBlock.java
+++ b/net/minecraft/world/level/block/BasePressurePlateBlock.java
@@ -133,6 +133,20 @@ public abstract class BasePressurePlateBlock extends Block {
@@ -106,11 +106,11 @@ index c2fbf44e93e44c36423465d406b5e4d3db029a80..a28a453f139295834c77aa908027c74c
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston && this.getSignalForState(state) > 0) {
diff --git a/net/minecraft/world/level/block/BaseRailBlock.java b/net/minecraft/world/level/block/BaseRailBlock.java
index bc79a7c2cb18237dad15432ae7e1238125108696..5ef16955c69f0e0fecc772067a0fb006e6413011 100644
index dff6c7868065c93c8b1a8b41a3323b3f1cec4e02..f7030ffad37e30c38a94e3672cd4872755319550 100644
--- a/net/minecraft/world/level/block/BaseRailBlock.java
+++ b/net/minecraft/world/level/block/BaseRailBlock.java
@@ -123,6 +123,24 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
}
@@ -118,6 +118,24 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl
return new RailState(level, pos, state).place(level.hasNeighborSignal(pos), first, current).getState();
}
+ // Leaves start - behaviour 1.21.1-
@@ -135,10 +135,10 @@ index bc79a7c2cb18237dad15432ae7e1238125108696..5ef16955c69f0e0fecc772067a0fb006
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston) {
diff --git a/net/minecraft/world/level/block/BrewingStandBlock.java b/net/minecraft/world/level/block/BrewingStandBlock.java
index aea12aad3270b966eed7779eaf77d26052f8a21f..6c39edf98f33df437880a77450557082ea9b0f6c 100644
index 5f14be7cd9abe30292c4c6c614d048cd1e0a9c1f..73f1c44acc9d296b523d5b6ba5978d0e0a2659cc 100644
--- a/net/minecraft/world/level/block/BrewingStandBlock.java
+++ b/net/minecraft/world/level/block/BrewingStandBlock.java
@@ -80,6 +80,15 @@ public class BrewingStandBlock extends BaseEntityBlock {
@@ -81,6 +81,15 @@ public class BrewingStandBlock extends BaseEntityBlock {
level.addParticle(ParticleTypes.SMOKE, x, y, z, 0.0, 0.0, 0.0);
}
@@ -155,7 +155,7 @@ index aea12aad3270b966eed7779eaf77d26052f8a21f..6c39edf98f33df437880a77450557082
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/ButtonBlock.java b/net/minecraft/world/level/block/ButtonBlock.java
index 86f4dcd959bb83247c6d2c5e947c79230aed3189..1b0223f1d533d1a8db5497ab9104052bc799f691 100644
index 9c859b04519f78988e765a164cf39cd8a99447df..2e6fb4f2021e6f008b85b7c0160f51c0e496ee8c 100644
--- a/net/minecraft/world/level/block/ButtonBlock.java
+++ b/net/minecraft/world/level/block/ButtonBlock.java
@@ -131,6 +131,20 @@ public class ButtonBlock extends FaceAttachedHorizontalDirectionalBlock {
@@ -180,10 +180,10 @@ index 86f4dcd959bb83247c6d2c5e947c79230aed3189..1b0223f1d533d1a8db5497ab9104052b
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston && state.getValue(POWERED)) {
diff --git a/net/minecraft/world/level/block/CampfireBlock.java b/net/minecraft/world/level/block/CampfireBlock.java
index 8b706b34914326c039b761387f25e488f30fe6c8..b816594fcd83d26037734ec051f2c5d7f7dbde9f 100644
index 4a24a36e022356d44a77306028ef2c09cd221fa5..d882980c4a956bd4b6c7f2ad9e71634f4fda41e5 100644
--- a/net/minecraft/world/level/block/CampfireBlock.java
+++ b/net/minecraft/world/level/block/CampfireBlock.java
@@ -111,6 +111,21 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB
@@ -112,6 +112,21 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB
return InteractionResult.TRY_WITH_EMPTY_HAND;
}
@@ -206,10 +206,10 @@ index 8b706b34914326c039b761387f25e488f30fe6c8..b816594fcd83d26037734ec051f2c5d7
protected void entityInside(
final BlockState state,
diff --git a/net/minecraft/world/level/block/ChestBlock.java b/net/minecraft/world/level/block/ChestBlock.java
index d3f0680d59ec87990b54dc3dbce27706bfadf5f1..b5595d87339e4d313c5691a06c2b1b3d1b40b6de 100644
index 4bd84b80199c7f625475ca62da02266d871a8639..70a0d30552d42d91778e0524bb89f6619c1fd0b0 100644
--- a/net/minecraft/world/level/block/ChestBlock.java
+++ b/net/minecraft/world/level/block/ChestBlock.java
@@ -257,6 +257,15 @@ public class ChestBlock extends AbstractChestBlock<ChestBlockEntity> implements
@@ -253,6 +253,15 @@ public class ChestBlock extends AbstractChestBlock<ChestBlockEntity> implements
return this.chestCanConnectTo(state) && state.getValue(TYPE) == ChestType.SINGLE ? state.getValue(FACING) : null;
}
@@ -226,11 +226,11 @@ index d3f0680d59ec87990b54dc3dbce27706bfadf5f1..b5595d87339e4d313c5691a06c2b1b3d
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/ChiseledBookShelfBlock.java b/net/minecraft/world/level/block/ChiseledBookShelfBlock.java
index 0682acaae12650549eea3c291d8cde7bb17766bd..ac12ef0c99c82d771e5275ec7ced7f76c76f5938 100644
index b7d7f1acf8e5cb3dddb7fb39fe003d25a9a41840..2627dd2687c67301279dbbb10e36d4db72fceb8b 100644
--- a/net/minecraft/world/level/block/ChiseledBookShelfBlock.java
+++ b/net/minecraft/world/level/block/ChiseledBookShelfBlock.java
@@ -168,6 +168,28 @@ public class ChiseledBookShelfBlock extends BaseEntityBlock implements Selectabl
SLOT_OCCUPIED_PROPERTIES.forEach(property -> builder.add(property));
@@ -171,6 +171,28 @@ public class ChiseledBookShelfBlock extends BaseEntityBlock implements Selectabl
SLOT_OCCUPIED_PROPERTIES.forEach(xva$0 -> var2.add(xva$0));
}
+ // Leaves start - behaviour 1.21.1-
@@ -259,10 +259,10 @@ index 0682acaae12650549eea3c291d8cde7bb17766bd..ac12ef0c99c82d771e5275ec7ced7f76
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java
index 2b97fd6af1c4956eb173b8c66c2a3efc8772a798..90326fe95673edbf5ed8c1a5d9020735fdd4d53e 100644
index 08c67084b5347bb1d6e65f17f3365ff33b542ec0..a2f2f0af4dc1df950e6d76717757a52231884857 100644
--- a/net/minecraft/world/level/block/CrafterBlock.java
+++ b/net/minecraft/world/level/block/CrafterBlock.java
@@ -130,6 +130,15 @@ public class CrafterBlock extends BaseEntityBlock {
@@ -131,6 +131,15 @@ public class CrafterBlock extends BaseEntityBlock {
}
}
@@ -279,10 +279,10 @@ index 2b97fd6af1c4956eb173b8c66c2a3efc8772a798..90326fe95673edbf5ed8c1a5d9020735
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/CreakingHeartBlock.java b/net/minecraft/world/level/block/CreakingHeartBlock.java
index 3dd5f8c20ad68e0bd6222c8ba1687df0b2ad3b0d..b2e1e78cd70e20dd1c17ef0199059fc2b4e513b5 100644
index 57292f216052110c5f03e8f3fe51709c87b7995c..837c2dad0800577fd2dd5cfff25fe18bd7dd14e7 100644
--- a/net/minecraft/world/level/block/CreakingHeartBlock.java
+++ b/net/minecraft/world/level/block/CreakingHeartBlock.java
@@ -152,6 +152,17 @@ public class CreakingHeartBlock extends BaseEntityBlock {
@@ -153,6 +153,17 @@ public class CreakingHeartBlock extends BaseEntityBlock {
builder.add(AXIS, STATE, NATURAL);
}
@@ -301,7 +301,7 @@ index 3dd5f8c20ad68e0bd6222c8ba1687df0b2ad3b0d..b2e1e78cd70e20dd1c17ef0199059fc2
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/DecoratedPotBlock.java b/net/minecraft/world/level/block/DecoratedPotBlock.java
index 3ce41ce3f9d2bf7a79e4b9811e043a69e0dedb13..2856b4081cddb38bac5c1d7199649a7531ef077f 100644
index 1c131955ba7a01348d9d9d5cf733d107c2531915..b6f18ac0fa511d11c28e3fd2c020b70efabbe0c1 100644
--- a/net/minecraft/world/level/block/DecoratedPotBlock.java
+++ b/net/minecraft/world/level/block/DecoratedPotBlock.java
@@ -172,6 +172,15 @@ public class DecoratedPotBlock extends BaseEntityBlock implements SimpleWaterlog
@@ -321,10 +321,10 @@ index 3ce41ce3f9d2bf7a79e4b9811e043a69e0dedb13..2856b4081cddb38bac5c1d7199649a75
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/DiodeBlock.java b/net/minecraft/world/level/block/DiodeBlock.java
index 3457a1fa8f5efc4bf173bf155165ab5e5ae9f303..1342607e3bf28ca085f51ade22efaf34f19da170 100644
index 5e0bd45aad738b0bc15404494e5e004b375f8a71..b79b457f0e618e680b072f0263c7e0481876c748 100644
--- a/net/minecraft/world/level/block/DiodeBlock.java
+++ b/net/minecraft/world/level/block/DiodeBlock.java
@@ -180,6 +180,17 @@ public abstract class DiodeBlock extends HorizontalDirectionalBlock {
@@ -182,6 +182,17 @@ public abstract class DiodeBlock extends HorizontalDirectionalBlock {
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled && this instanceof ComparatorBlock && !oldState.is(Blocks.COMPARATOR)) org.leavesmc.leaves.lithium.common.block.entity.inventory_comparator_tracking.ComparatorTracking.notifyNearbyBlockEntitiesAboutNewComparator(level, pos); // Leaves - Lithium Sleeping Block Entity
}
@@ -343,10 +343,10 @@ index 3457a1fa8f5efc4bf173bf155165ab5e5ae9f303..1342607e3bf28ca085f51ade22efaf34
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston) {
diff --git a/net/minecraft/world/level/block/DispenserBlock.java b/net/minecraft/world/level/block/DispenserBlock.java
index dca954bd076fa917512af91e0b93d449eb5cac6d..7f880ba7cdd08be392dd4fe5a06fffbf6962318b 100644
index 754f2a541e80947553c56420bdc962dbcf80d36e..79bb8e34e7a7999b10e19cebc2a7b08ba3571684 100644
--- a/net/minecraft/world/level/block/DispenserBlock.java
+++ b/net/minecraft/world/level/block/DispenserBlock.java
@@ -159,6 +159,15 @@ public class DispenserBlock extends BaseEntityBlock {
@@ -161,6 +161,15 @@ public class DispenserBlock extends BaseEntityBlock {
return this.defaultBlockState().setValue(FACING, context.getNearestLookingDirection().getOpposite());
}
@@ -363,10 +363,10 @@ index dca954bd076fa917512af91e0b93d449eb5cac6d..7f880ba7cdd08be392dd4fe5a06fffbf
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/HopperBlock.java b/net/minecraft/world/level/block/HopperBlock.java
index 88606b84ea3a33ffbb0cfa6e073eb8f59d7188d0..c3ccebd7f27fd4d313cbcd616d58180a70f5f574 100644
index 1095c94d7adb8e6baa51bf3cb8a31000592aa990..9cc6ca5b329f8cd62620b9cdbfcbf4c2b668d108 100644
--- a/net/minecraft/world/level/block/HopperBlock.java
+++ b/net/minecraft/world/level/block/HopperBlock.java
@@ -139,6 +139,15 @@ public class HopperBlock extends BaseEntityBlock implements org.leavesmc.leaves.
@@ -140,6 +140,15 @@ public class HopperBlock extends BaseEntityBlock implements org.leavesmc.leaves.
}
}
@@ -383,11 +383,11 @@ index 88606b84ea3a33ffbb0cfa6e073eb8f59d7188d0..c3ccebd7f27fd4d313cbcd616d58180a
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/JukeboxBlock.java b/net/minecraft/world/level/block/JukeboxBlock.java
index a9e46a66ffc868c3b4ef2bb6257f23a20f12b1a6..cee96a825f0e0e740ede8df0bf6dc5256b9fb8d3 100644
index f202953a0eacfa61635ad1b13e4dbf9960e004ec..b544b959634e458f482ea863b7a4b28b5de61765 100644
--- a/net/minecraft/world/level/block/JukeboxBlock.java
+++ b/net/minecraft/world/level/block/JukeboxBlock.java
@@ -82,6 +82,20 @@ public class JukeboxBlock extends BaseEntityBlock {
}
@@ -83,6 +83,20 @@ public class JukeboxBlock extends BaseEntityBlock {
return !result.consumesAction() ? InteractionResult.TRY_WITH_EMPTY_HAND : result;
}
+ // Leaves start - behaviour 1.21.1-
@@ -408,7 +408,7 @@ index a9e46a66ffc868c3b4ef2bb6257f23a20f12b1a6..cee96a825f0e0e740ede8df0bf6dc525
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/LecternBlock.java b/net/minecraft/world/level/block/LecternBlock.java
index 75660fb19c25444e35dbbe58cd20f9b3d3f7ad32..196051c80baa489f43065a11a61f22a8c61251e7 100644
index b5ac0a094d7c67afe59716857cef425e11545054..b1fa698160e9ebd950758bfe04381d85ad253859 100644
--- a/net/minecraft/world/level/block/LecternBlock.java
+++ b/net/minecraft/world/level/block/LecternBlock.java
@@ -200,6 +200,37 @@ public class LecternBlock extends BaseEntityBlock {
@@ -450,7 +450,7 @@ index 75660fb19c25444e35dbbe58cd20f9b3d3f7ad32..196051c80baa489f43065a11a61f22a8
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (state.getValue(POWERED)) {
diff --git a/net/minecraft/world/level/block/LeverBlock.java b/net/minecraft/world/level/block/LeverBlock.java
index 341960ef67a689f660d0dcf61aaf5bf52bdc9074..6fc372e782f2a34a34a9ef1faed41ace6db5ec1b 100644
index 772a1cb8b275506ed0310294369b985746f8f567..2a05139db15858991202b53e380b47cde43393b2 100644
--- a/net/minecraft/world/level/block/LeverBlock.java
+++ b/net/minecraft/world/level/block/LeverBlock.java
@@ -127,6 +127,20 @@ public class LeverBlock extends FaceAttachedHorizontalDirectionalBlock {
@@ -475,7 +475,7 @@ index 341960ef67a689f660d0dcf61aaf5bf52bdc9074..6fc372e782f2a34a34a9ef1faed41ace
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston && state.getValue(POWERED)) {
diff --git a/net/minecraft/world/level/block/LightningRodBlock.java b/net/minecraft/world/level/block/LightningRodBlock.java
index 47ca45518df306cc4368983eefb89294e56b015a..31be8864aa28eff804b507efdab614b35e3fea6f 100644
index c2001c9475e0773fb84b987afcf2d02ae136af3a..871a802fce141b3a36acab6b899349754f5d81e1 100644
--- a/net/minecraft/world/level/block/LightningRodBlock.java
+++ b/net/minecraft/world/level/block/LightningRodBlock.java
@@ -123,6 +123,19 @@ public class LightningRodBlock extends RodBlock implements SimpleWaterloggedBloc
@@ -499,10 +499,10 @@ index 47ca45518df306cc4368983eefb89294e56b015a..31be8864aa28eff804b507efdab614b3
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (state.getValue(POWERED)) {
diff --git a/net/minecraft/world/level/block/ObserverBlock.java b/net/minecraft/world/level/block/ObserverBlock.java
index 6a3413ca875ce78f48cd8d3ce2cfe7798be1a19e..be572eff561ffdd961a9602eaa6136761c4d48a4 100644
index 680a357db27407e2dc21c615fadaf9754421c361..1d68ebf02f4e83a69fc30f36e0b9f688799210c3 100644
--- a/net/minecraft/world/level/block/ObserverBlock.java
+++ b/net/minecraft/world/level/block/ObserverBlock.java
@@ -128,6 +128,18 @@ public class ObserverBlock extends DirectionalBlock {
@@ -133,6 +133,18 @@ public class ObserverBlock extends DirectionalBlock {
}
}
@@ -522,10 +522,10 @@ index 6a3413ca875ce78f48cd8d3ce2cfe7798be1a19e..be572eff561ffdd961a9602eaa613676
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (state.getValue(POWERED) && level.getBlockTicks().hasScheduledTick(pos, this)) {
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
index 619f5e37919693fc5976aedefed3bb5428395439..ed190e16df7c6b80fd90561e7c2fdd53c745e54a 100644
index 973d423a9ab5a6a3338f43c27f6d99d7b7d94301..1ccacb7ffa7e8b9c3fdd37910d3e8bded86a4d3a 100644
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -378,6 +378,28 @@ public class RedStoneWireBlock extends Block {
@@ -382,6 +382,28 @@ public class RedStoneWireBlock extends Block {
}
}
@@ -555,7 +555,7 @@ index 619f5e37919693fc5976aedefed3bb5428395439..ed190e16df7c6b80fd90561e7c2fdd53
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston) {
diff --git a/net/minecraft/world/level/block/RedstoneTorchBlock.java b/net/minecraft/world/level/block/RedstoneTorchBlock.java
index 0d0b5443c5c56825e88fd64c02c993eca6044d45..e2e5552008547fa1782b0a5ed3129162e94647c9 100644
index 1434dd70d443a6aa7312740d901e5dc40fd926d2..e41f4453e482874e66ec3f4ddfbfaf28de345c6d 100644
--- a/net/minecraft/world/level/block/RedstoneTorchBlock.java
+++ b/net/minecraft/world/level/block/RedstoneTorchBlock.java
@@ -54,6 +54,16 @@ public class RedstoneTorchBlock extends BaseTorchBlock {
@@ -576,10 +576,10 @@ index 0d0b5443c5c56825e88fd64c02c993eca6044d45..e2e5552008547fa1782b0a5ed3129162
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston) {
diff --git a/net/minecraft/world/level/block/SculkSensorBlock.java b/net/minecraft/world/level/block/SculkSensorBlock.java
index 2bbce50d9dd0ca65f9e3bc90c8de098473039bc5..9a9fcb593c4b5f2bb0c57f9268dfdc9eb21d38ea 100644
index 10cff0f9db2910c543c20fa055c0c5b759becc15..cf349086b8d3faffbe971b3c47fd819b6c7b0502 100644
--- a/net/minecraft/world/level/block/SculkSensorBlock.java
+++ b/net/minecraft/world/level/block/SculkSensorBlock.java
@@ -129,6 +129,19 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg
@@ -130,6 +130,19 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg
}
}
@@ -600,10 +600,10 @@ index 2bbce50d9dd0ca65f9e3bc90c8de098473039bc5..9a9fcb593c4b5f2bb0c57f9268dfdc9e
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (getPhase(state) == SculkSensorPhase.ACTIVE) {
diff --git a/net/minecraft/world/level/block/SculkShriekerBlock.java b/net/minecraft/world/level/block/SculkShriekerBlock.java
index d7e5ec23c64b60c47ab6b54cbf282e88c3a4a045..037aa3592a963bbb142465d31040f60e95cb146e 100644
index 5a15671202a0129b1ce97fae5515ddefa5b3fb01..099a1e75f48ca6a2a8eb83571f5c06674b88f3d8 100644
--- a/net/minecraft/world/level/block/SculkShriekerBlock.java
+++ b/net/minecraft/world/level/block/SculkShriekerBlock.java
@@ -68,6 +68,17 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo
@@ -69,6 +69,17 @@ public class SculkShriekerBlock extends BaseEntityBlock implements SimpleWaterlo
super.stepOn(level, pos, onState, entity);
}
@@ -611,7 +611,7 @@ index d7e5ec23c64b60c47ab6b54cbf282e88c3a4a045..037aa3592a963bbb142465d31040f60e
+ @Override
+ protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
+ if (level instanceof ServerLevel serverLevel && state.getValue(SHRIEKING) && !state.is(newState.getBlock())) {
+ serverLevel.getBlockEntity(pos, BlockEntityType.SCULK_SHRIEKER).ifPresent(sculkShrieker -> sculkShrieker.tryRespond(serverLevel));
+ serverLevel.getBlockEntity(pos, BlockEntityTypes.SCULK_SHRIEKER).ifPresent(sculkShrieker -> sculkShrieker.tryRespond(serverLevel));
+ }
+ super.onRemove(state, level, pos, newState, movedByPiston);
+ }
@@ -622,10 +622,10 @@ index d7e5ec23c64b60c47ab6b54cbf282e88c3a4a045..037aa3592a963bbb142465d31040f60e
protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) {
if (state.getValue(SHRIEKING)) {
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
index 8259f530ec50554906c254b60f1e964b52c02852..59ad645785bc99758f4bc124c56e39d87c4b75c2 100644
index 0dc80ee92f2aed4c8ca4bc60f4b189af764fe81d..a80535ebb7b4fcc3a6c7b84eb08e275461c7ae36 100644
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
@@ -150,6 +150,20 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
@@ -152,6 +152,20 @@ public class ShulkerBoxBlock extends BaseEntityBlock {
// Paper end - re-set loot table if it was cleared
}
@@ -647,7 +647,7 @@ index 8259f530ec50554906c254b60f1e964b52c02852..59ad645785bc99758f4bc124c56e39d8
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
Containers.updateNeighboursAfterDestroy(state, level, pos);
diff --git a/net/minecraft/world/level/block/TripWireBlock.java b/net/minecraft/world/level/block/TripWireBlock.java
index 04e5995409a3532947dfab1c8ef05bd546a6f66d..6bf811477a27bbbeeeba6c9d768d33fc677ea5e7 100644
index e19a82ebb7b3be71e51ac28914de58fab32a708e..76aed7ac9fc908dc066001afcaf7e57355233143 100644
--- a/net/minecraft/world/level/block/TripWireBlock.java
+++ b/net/minecraft/world/level/block/TripWireBlock.java
@@ -107,6 +107,17 @@ public class TripWireBlock extends Block {
@@ -669,7 +669,7 @@ index 04e5995409a3532947dfab1c8ef05bd546a6f66d..6bf811477a27bbbeeeba6c9d768d33fc
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index fd808353181e05f2fc527a391ce7bb990f61b4c7..836eae0c3e0891a3e3309b684f15d65f891215cf 100644
index 49b3f9e78ae9db257b653a6094619880784c6370..b451f8234e92c36fa1395a80b01dc8780824d88e 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -248,6 +248,26 @@ public class TripWireHookBlock extends Block {
@@ -700,10 +700,10 @@ index fd808353181e05f2fc527a391ce7bb990f61b4c7..836eae0c3e0891a3e3309b684f15d65f
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
if (!movedByPiston) {
diff --git a/net/minecraft/world/level/block/entity/BlockEntityType.java b/net/minecraft/world/level/block/entity/BlockEntityType.java
index ac58bbed01edaf5dfe4839c89649ca865c339c8a..caead1012ff3b5b5f78c24a3baf20b7d00b84cf6 100644
index cda0d6d01035570844f03e523db7721cc6cc3e6d..b88b1b123563f06ce00f20ce775a3dfcd5df79de 100644
--- a/net/minecraft/world/level/block/entity/BlockEntityType.java
+++ b/net/minecraft/world/level/block/entity/BlockEntityType.java
@@ -301,7 +301,7 @@ public class BlockEntityType<T extends BlockEntity> {
@@ -28,7 +28,7 @@ public class BlockEntityType<T extends BlockEntity> {
}
public boolean isValid(final BlockState state) {
@@ -713,11 +713,11 @@ index ac58bbed01edaf5dfe4839c89649ca865c339c8a..caead1012ff3b5b5f78c24a3baf20b7d
@Deprecated
diff --git a/net/minecraft/world/level/block/piston/MovingPistonBlock.java b/net/minecraft/world/level/block/piston/MovingPistonBlock.java
index 2b6ad989e1e1424d0283bae39e5dae33eba44923..0f47fb528422d591bd03434a089ea69c7f27bf8c 100644
index 6138c8bd76fc405b67282ac349d41e02a4f9deba..56a397e8a38a960e1334ce65ebb66703ed2e01a4 100644
--- a/net/minecraft/world/level/block/piston/MovingPistonBlock.java
+++ b/net/minecraft/world/level/block/piston/MovingPistonBlock.java
@@ -70,6 +70,19 @@ public class MovingPistonBlock extends BaseEntityBlock {
return createTickerHelper(type, BlockEntityType.PISTON, PistonMovingBlockEntity::tick);
@@ -71,6 +71,19 @@ public class MovingPistonBlock extends BaseEntityBlock {
return createTickerHelper(type, BlockEntityTypes.PISTON, PistonMovingBlockEntity::tick);
}
+ // Leaves start - behaviour 1.21.1-
@@ -762,10 +762,10 @@ index f8caa0b3c21766dbad73c524c1680346e4257188..b658d602953ade618d89c02745eb46be
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
BlockPos basePos = pos.relative(state.getValue(FACING).getOpposite());
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
index 0fbdf810c785c8a596d461e7651361fdedbb6217..ff1471f40b73582df68efbf2996a854c6aa37d65 100644
index 7358c75802a37e84e30b1b94a046251d2547a388..972b953a579120c1c05f2dc9bfc2b408d6071d26 100644
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -174,6 +174,16 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
@@ -172,6 +172,16 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
org.spigotmc.AsyncCatcher.catchOp("block onPlace"); // Spigot
}
@@ -782,7 +782,7 @@ index 0fbdf810c785c8a596d461e7651361fdedbb6217..ff1471f40b73582df68efbf2996a854c
protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) {
}
@@ -889,6 +899,13 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
@@ -900,6 +910,13 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
// CraftBukkit end
}
@@ -797,47 +797,26 @@ index 0fbdf810c785c8a596d461e7651361fdedbb6217..ff1471f40b73582df68efbf2996a854c
this.getBlock().affectNeighborsAfterRemoval(this.asState(), level, pos, movedByPiston);
}
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index ef3508dc4c8b3a9c8a6c7ff520cf51a68d6a13d9..11f0f5e1b8ee9ce7e6833d46ccb557d896674431 100644
index f103b1633f7483bd57da760e59fea132c63faec5..a4d5bf1773a9ce8184a940384696f0d38690a421 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -423,22 +423,28 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
boolean blockChanged = !oldState.is(newBlock);
boolean movedByPiston = (flags & Block.UPDATE_MOVE_BY_PISTON) != 0;
boolean sideEffects = (flags & Block.UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS) == 0;
- if (blockChanged && oldState.hasBlockEntity() && !state.shouldChangedStateKeepBlockEntity(oldState)) {
- if (!this.level.isClientSide() && sideEffects) {
- BlockEntity blockEntity = this.level.getBlockEntity(pos);
- if (blockEntity != null) {
- blockEntity.preRemoveSideEffects(pos, oldState);
+ // Leaves start - behaviour 1.21.1-
+ if (!fun.bm.lophine.config.modules.experiment.RedStoneConfig.oldBlockRemoveBehaviour) {
+ if (blockChanged && oldState.hasBlockEntity() && !state.shouldChangedStateKeepBlockEntity(oldState)) {
+ if (!this.level.isClientSide() && sideEffects) {
+ BlockEntity blockEntity = this.level.getBlockEntity(pos);
+ if (blockEntity != null) {
+ blockEntity.preRemoveSideEffects(pos, oldState);
+ }
}
- }
@@ -425,6 +425,8 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
boolean blockChanged = !oldState.is(newBlock);
boolean movedByPiston = (flags & Block.UPDATE_MOVE_BY_PISTON) != 0;
boolean sideEffects = (flags & Block.UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS) == 0;
+ // Leaves start - behaviour 1.21.1-
+ if (!fun.bm.lophine.config.modules.experiment.RedStoneConfig.oldBlockRemoveBehaviour) {
if (blockChanged && oldState.hasBlockEntity() && !state.shouldChangedStateKeepBlockEntity(oldState)) {
if (!this.level.isClientSide() && sideEffects) {
BlockEntity blockEntity = this.level.getBlockEntity(pos);
@@ -441,6 +443,10 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
&& ((flags & Block.UPDATE_NEIGHBORS) != 0 || movedByPiston)) {
oldState.affectNeighborsAfterRemoval(serverLevel, pos, movedByPiston);
}
+ } else {
+ oldState.onRemove(this.level, pos, state, movedByPiston);
+ }
+ // Leaves end - behaviour 1.21.1-
- this.removeBlockEntity(pos);
- }
+ this.removeBlockEntity(pos);
+ }
- if ((blockChanged || newBlock instanceof BaseRailBlock)
- && this.level instanceof ServerLevel serverLevel
- && ((flags & Block.UPDATE_NEIGHBORS) != 0 || movedByPiston)) {
- oldState.affectNeighborsAfterRemoval(serverLevel, pos, movedByPiston);
+ if ((blockChanged || newBlock instanceof BaseRailBlock)
+ && this.level instanceof ServerLevel serverLevel
+ && ((flags & Block.UPDATE_NEIGHBORS) != 0 || movedByPiston)) {
+ oldState.affectNeighborsAfterRemoval(serverLevel, pos, movedByPiston);
+ }
+ } else {
+ oldState.onRemove(this.level, pos, state, movedByPiston);
}
+ // Leaves end - behaviour 1.21.1-
if (!section.getBlockState(localX, localY, localZ).is(newBlock)) {
return null;
if (!section.getBlockState(localX, localY, localZ).is(newBlock)) {
return null;
@@ -5,7 +5,7 @@ Subject: [PATCH] MiniTweaks mob fire and explosion rules
diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java
index 5005f2b923aa94dbc38fb75d5b6f58344888c895..0d4ba81c82b683c32addf6441de3843abf462c3c 100644
index 4a90294f8d8447bb2f2cef7572119274a1a2c62e..054bfdac44a2bf1d568f2d56b4ae0cb0057862a8 100644
--- a/net/minecraft/world/entity/monster/Creeper.java
+++ b/net/minecraft/world/entity/monster/Creeper.java
@@ -250,7 +250,8 @@ public class Creeper extends Monster {
@@ -19,10 +19,10 @@ index 5005f2b923aa94dbc38fb75d5b6f58344888c895..0d4ba81c82b683c32addf6441de3843a
this.triggerOnDeathMobEffects(level, Entity.RemovalReason.KILLED);
this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
diff --git a/net/minecraft/world/entity/projectile/hurtingprojectile/LargeFireball.java b/net/minecraft/world/entity/projectile/hurtingprojectile/LargeFireball.java
index 711b97aa9e49b7edee34c91d77b1005be4fa96bd..1d9232c9061bde9c545e3ee25bc9c6b0417b9ece 100644
index 8195ab561d12abb33f4359a68b3c1579ce284242..5f79999db6e3ca296a6d018af821fec213bed18a 100644
--- a/net/minecraft/world/entity/projectile/hurtingprojectile/LargeFireball.java
+++ b/net/minecraft/world/entity/projectile/hurtingprojectile/LargeFireball.java
@@ -37,7 +37,9 @@ public class LargeFireball extends Fireball {
@@ -38,7 +38,9 @@ public class LargeFireball extends Fireball {
// CraftBukkit start - fire ExplosionPrimeEvent
org.bukkit.event.entity.ExplosionPrimeEvent event = new org.bukkit.event.entity.ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
if (event.callEvent()) {
@@ -34,10 +34,10 @@ index 711b97aa9e49b7edee34c91d77b1005be4fa96bd..1d9232c9061bde9c545e3ee25bc9c6b0
// CraftBukkit end - fire ExplosionPrimeEvent
this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
diff --git a/net/minecraft/world/entity/projectile/hurtingprojectile/SmallFireball.java b/net/minecraft/world/entity/projectile/hurtingprojectile/SmallFireball.java
index 1a72ee1559f75660796a9cbc1a9d9cdd6883dc90..480042d9401b6d7618fc2f36f16145606414d475 100644
index ea2ed37063a5f62ad2ade39e9f39f2c2ba6f1772..aae519caab1162af8c7308b81ee33286475b87e6 100644
--- a/net/minecraft/world/entity/projectile/hurtingprojectile/SmallFireball.java
+++ b/net/minecraft/world/entity/projectile/hurtingprojectile/SmallFireball.java
@@ -63,7 +63,7 @@ public class SmallFireball extends Fireball {
@@ -64,7 +64,7 @@ public class SmallFireball extends Fireball {
super.onHitBlock(hitResult);
if (this.level() instanceof ServerLevel serverLevel) {
Entity owner = this.getOwner();
@@ -1,142 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Wed, 21 Jan 2026 21:28:21 +0800
Subject: [PATCH] Carpet Features Compatible
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
index 8b05860d2787a40495f8a025bc0bc43789d6a6af..2ef6a7fb5a9c3452dfff70a67542e2ca2531c897 100644
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
@@ -340,7 +340,7 @@ public final class RegionizedServer {
final long tickStartNanos = System.nanoTime();
++this.tickCount;
// Luminol start - Add a config to enable tick command
- if (me.earthme.luminol.config.modules.experiment.CommandConfig.tick) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick) { // Lophine - redirect
MinecraftServer.getServer().tickRateManager().tick();
}
// Luminol end - Add a config to enable tick command
@@ -529,7 +529,7 @@ public final class RegionizedServer {
}
private void tickTime(final ServerLevel world, final long tickCount) {
- if ((!me.earthme.luminol.config.modules.experiment.CommandConfig.tick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command
+ if ((!fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command // Lophine - redirect
world.serverLevelData.setGameTime(world.serverLevelData.getGameTime() + tickCount);
}
}
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
index 917d6965e91527fc79d545c041765f78a357eac2..19ddbee489e9b17ef0bf794fa6cc3c10cc0ed565 100644
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
@@ -595,7 +595,7 @@ public final class TickRegionScheduler {
// next start isn't updated until the end of this tick
this.tickRegion(tickCount, tickStart, scheduledEnd);
// Luminol start - Add a config to enable tick command
- if (me.earthme.luminol.config.modules.experiment.CommandConfig.tick) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick) { // Lophine - redirect
MinecraftServer.getServer().tickRateManager().endTickWork();
}
// Luminol end - Add a config to enable tick command
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index bb5059a77741bf1d9e73bd8c7f0da6681ec63f67..270ee3c01ad0b351bee068a507b09a9d0041ae9c 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -266,7 +266,7 @@ public class Commands {
TellRawCommand.register(this.dispatcher, context);
//TestCommand.register(this.dispatcher, context); // Folia - region threading
// Luminol start - Add a config to enable tick command
- if (me.earthme.luminol.config.modules.experiment.CommandConfig.tick) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick) { // Lophine - redirect
TickCommand.register(this.dispatcher); // Folia - region threading - TODO later
}
// Luminol end - Add a config to enable tick command
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 5ebff729bb7e75e1c84449c0e3021b972ad0d936..d35cc60b1f4a59ab1b74da5d8d55d63c94a9055b 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -2186,7 +2186,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.lastSentFood = -1;
this.teleportSpectators(transition, oldLevel);
// Leaves start - bot support
- if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.checkEnabled()) {
this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(this, true)); // Leaves - render bot
}
// Leaves end - bot support
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index baa295f3dd8cf10bf7347ee4d1c249b1f82c9279..1d5376650d0f5eeb23fde8d7116b47cfae37576f 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -280,7 +280,7 @@ public abstract class PlayerList {
// org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
// Leaves start - bot support
- if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.checkEnabled()) {
org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
if (bot != null) {
this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, false);
@@ -441,7 +441,7 @@ public abstract class PlayerList {
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
// Leaves start - bot support
- if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.checkEnabled()) {
org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
if (bot != null) {
this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, false);
@@ -969,7 +969,7 @@ public abstract class PlayerList {
).callEvent();
// Paper end
// Leaves start - bot support
- if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.checkEnabled()) {
this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(player, true)); // Leaves - render bot
}
// Leaves end - bot support
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 3e4fae7a5ae7f8a26bf78727e81c4a87e8fed332..1340ef0ba7660a0e3c4cce105a90fcc4eadcf559 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -240,7 +240,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
// Leaves start - Wool hopper counter
- if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
+ if (fun.bm.lophine.carpet.config.modules.WoolHopperCounterConfig.hopperCountersUnlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, entity.getBlockPos().relative(state.getValue(HopperBlock.FACING)));
if (woolColor != null) {
for (int i = 0; i < Short.MAX_VALUE; i++) {
@@ -258,7 +258,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (changed) {
entity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
// Leaves start - Wool hopper counter
- if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos))) {
+ if (fun.bm.lophine.carpet.config.modules.WoolHopperCounterConfig.hopperCountersUnlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos))) {
entity.setCooldown(0);
return true;
}
@@ -664,7 +664,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
public static boolean addItem(final Container container, final ItemEntity entity) {
- if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && entity.isRemoved()) return false; // Leaves - Wool hopper counter
+ if (fun.bm.lophine.carpet.config.modules.WoolHopperCounterConfig.hopperCountersUnlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && entity.isRemoved()) return false; // Leaves - Wool hopper counter
boolean changed = false;
// CraftBukkit start
if (org.bukkit.event.inventory.InventoryPickupItemEvent.getHandlerList().getRegisteredListeners().length > 0) { // Paper - optimize hoppers
diff --git a/net/minecraft/world/level/dimension/end/EnderDragonFight.java b/net/minecraft/world/level/dimension/end/EnderDragonFight.java
index 5ca008b3dca83c00f2ae86a608d726972a8d9f9d..4274f22710035b547f5aca617c80c5c99f3a4dc8 100644
--- a/net/minecraft/world/level/dimension/end/EnderDragonFight.java
+++ b/net/minecraft/world/level/dimension/end/EnderDragonFight.java
@@ -323,7 +323,7 @@ public class EnderDragonFight extends SavedData {
private int cachePortalOriginIteratorY = -1;
public BlockPattern.@Nullable BlockPatternMatch findExitPortal() {
- if (me.earthme.luminol.config.modules.optimizations.OptimizedDragonRespawnConfig.optimizedRespawn) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.optimizedDragonRespawn) {
int i, j;
for (i = cachePortalChunkIteratorX; i <= 8; ++i) {
for (j = cachePortalChunkIteratorZ; j <= 8; ++j) {
@@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Wed, 21 Jan 2026 21:28:21 +0800
Subject: [PATCH] Carpet Features Compatible
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
index 7ee9eb8439330724c537f9b1451be78dd3a107ad..7577533f82688304f06c445fd5a1c3fa3c4575fc 100644
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
@@ -241,7 +241,7 @@ public final class RegionizedServer {
final long tickStartNanos = System.nanoTime(); // Lophine - Carpet features
++this.tickCount;
// Luminol start - Add a config to enable tick command
- if (me.earthme.luminol.config.modules.experiment.CommandConfig.tick) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick) { // Lophine - redirect
MinecraftServer.getServer().tickRateManager().tick();
}
// Luminol end - Add a config to enable tick command
@@ -435,7 +435,7 @@ public final class RegionizedServer {
}
private void tickTime(final ServerLevel world, final long tickCount) {
- if ((!me.earthme.luminol.config.modules.experiment.CommandConfig.tick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command
+ if ((!fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command // Lophine - redirect
world.serverLevelData.setGameTime(world.serverLevelData.getGameTime() + tickCount);
}
}
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
index 57a35d7a801621fc461e896eb2bba533d9d5bc1b..ae424c8931a2f82c6c8d4ddd8422a2c142a77a95 100644
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
@@ -576,7 +576,7 @@ public final class TickRegionScheduler {
// next start isn't updated until the end of this tick
this.tickRegion(tickCount, tickStart, scheduledEnd);
// Luminol start - Add a config to enable tick command
- if (me.earthme.luminol.config.modules.experiment.CommandConfig.tick) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick) { // Lophine - redirect
MinecraftServer.getServer().tickRateManager().endTickWork();
}
// Luminol end - Add a config to enable tick command
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 03f3fe221b14f0317947d74e25049bcce2ebeb66..6882e85fb6413e5c346c189a82b69f3e408aafba 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -268,7 +268,7 @@ public class Commands {
TellRawCommand.register(this.dispatcher, context);
//TestCommand.register(this.dispatcher, context); // Folia - region threading
// Luminol start - Add a config to enable tick command
- if (me.earthme.luminol.config.modules.experiment.CommandConfig.tick) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.commandTick) { // Lophine - redirect
TickCommand.register(this.dispatcher); // Folia - region threading - TODO later
}
// Luminol end - Add a config to enable tick command
diff --git a/net/minecraft/world/level/dimension/end/EnderDragonFight.java b/net/minecraft/world/level/dimension/end/EnderDragonFight.java
index 3388bf5d2cff00b397af1dd7b9ab93669985b35c..e70a6c295e8c26bdf56528826801f037ad0f93b0 100644
--- a/net/minecraft/world/level/dimension/end/EnderDragonFight.java
+++ b/net/minecraft/world/level/dimension/end/EnderDragonFight.java
@@ -323,7 +323,7 @@ public class EnderDragonFight extends SavedData {
private int cachePortalOriginIteratorY = -1;
public BlockPattern.@Nullable BlockPatternMatch findExitPortal() {
- if (me.earthme.luminol.config.modules.optimizations.OptimizedDragonRespawnConfig.optimizedRespawn) {
+ if (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.optimizedDragonRespawn) { // Lophine - Carpet Features Compatible
int i, j;
for (i = cachePortalChunkIteratorX; i <= 8; ++i) {
for (j = cachePortalChunkIteratorZ; j <= 8; ++j) {
@@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bacteriawa <A3167717663@hotmail.com>
Date: Tue, 23 Jun 2026 02:32:14 +0800
Subject: [PATCH] PCA sync protocol
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/252a16955f6e1e31aac85d222b093b0797d392f8/leaves-server/minecraft-patches/features/0027-PCA-sync-protocol.patch)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java
index 0f412551685a8ea76be3b389e0782e57d22bb87c..6da0fd10e1a4a346dc1b073563e9bd8cf9b3c76d 100644
--- a/net/minecraft/world/SimpleContainer.java
+++ b/net/minecraft/world/SimpleContainer.java
@@ -199,6 +199,11 @@ public class SimpleContainer implements Container, StackedContentsCompatible {
@Override
public void setChanged() {
+ // Leaves start - PCA sync protocol
+ if (fun.bm.lophine.config.modules.function.protocol.PcaSyncProtocolConfig.enabled && this.getOwner() instanceof org.bukkit.craftbukkit.entity.CraftEntity entity) {
+ org.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(entity.getHandle());
+ }
+ // Leaves end - PCA sync protocol
}
@Override
diff --git a/net/minecraft/world/entity/vehicle/boat/AbstractChestBoat.java b/net/minecraft/world/entity/vehicle/boat/AbstractChestBoat.java
index 58b99596b16e1dd8b0c9bcde5d465c6df52cc28b..3bb07698d1908f310ea7a1bb7a0da531f4040999 100644
--- a/net/minecraft/world/entity/vehicle/boat/AbstractChestBoat.java
+++ b/net/minecraft/world/entity/vehicle/boat/AbstractChestBoat.java
@@ -142,6 +142,11 @@ public abstract class AbstractChestBoat extends AbstractBoat implements HasCusto
@Override
public void setChanged() {
+ // Leaves start - PCA sync protocol
+ if (fun.bm.lophine.config.modules.function.protocol.PcaSyncProtocolConfig.enabled) {
+ org.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
+ }
+ // Leaves end - PCA sync protocol
}
@Override
diff --git a/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java b/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java
index d87dcb72fd5d2b22eafc1a444d4fc3807595b6a5..bd92576ec323befd4bc0aaf36cf3c1d03826668a 100644
--- a/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java
+++ b/net/minecraft/world/entity/vehicle/minecart/AbstractMinecartContainer.java
@@ -66,6 +66,11 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
@Override
public void setChanged() {
+ // Leaves start - PCA sync protocol
+ if (fun.bm.lophine.config.modules.function.protocol.PcaSyncProtocolConfig.enabled) {
+ org.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
+ }
+ // Leaves end - PCA sync protocol
}
@Override
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
index f8a6f3d4d6593ec416ce25a72871a5d40352480a..b677a8fec91968ea777b1f38ca00596e9072de92 100644
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -236,6 +236,14 @@ public abstract class BlockEntity implements DebugValueSource, TypedInstance<Blo
if (!blockState.isAir()) {
level.updateNeighbourForOutputSignal(worldPosition, blockState.getBlock());
}
+ // Leaves start - PCA sync protocol
+ if (fun.bm.lophine.config.modules.function.protocol.PcaSyncProtocolConfig.enabled && !level.isClientSide()) {
+ BlockEntity blockEntity = level.getBlockEntity(worldPosition);
+ if (blockEntity != null) {
+ org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(blockEntity);
+ }
+ }
+ // Leaves end - PCA sync protocol
}
public BlockPos getBlockPos() {
@@ -0,0 +1,249 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bacteriawa <A3167717663@hotmail.com>
Date: Tue, 23 Jun 2026 03:06:41 +0800
Subject: [PATCH] Add Vanilla-like experience Config
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
index dd17339fe2f9d7660b20eed05b61d6231302aa82..d997e4f7ae6ee4e81f5fffe874f2895dda314df9 100644
--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -204,6 +204,11 @@ public class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
@Override
public int configMaxAutoSavePerTick(final ServerLevel world) {
+ // Lophine start - Vanilla-like experience
+ if (fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled) {
+ return 200;
+ }
+ // Lophine end - Vanilla-like experience
return world.paperConfig().chunks.maxAutoSaveChunksPerTick;
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 4c53b688ed6b26ca7231841f3235f9a824416bba..cef9c7887332b91e2466a97a5250db81f7af0dcf 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -2360,7 +2360,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public boolean isInvulnerableTo(final ServerLevel level, final DamageSource source) {
// Paper start - disable player cramming
return (super.isInvulnerableTo(level, source) || this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL) || !this.connection.hasClientLoaded())
- || (!this.level().paperConfig().collisions.allowPlayerCrammingDamage && source.is(DamageTypes.CRAMMING));
+ || (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && !this.level().paperConfig().collisions.allowPlayerCrammingDamage && source.is(DamageTypes.CRAMMING)); // Lophine - Vanilla-like experience
// Paper end - disable player cramming
}
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 14a79e8ef5a98b1eef2f2d3e0c63f21cb5bb4dbf..429116ab6bac69054a30b0c766ea5d0186877fae 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -4004,7 +4004,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
// Paper start - Cap entity collisions
this.numCollisions = Math.max(0, this.numCollisions - this.level().paperConfig().collisions.maxEntityCollisions);
for (Entity entity : pushableEntities) {
- if (this.numCollisions >= this.level().paperConfig().collisions.maxEntityCollisions) {
+ if (this.numCollisions >= (fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled ? Integer.MAX_VALUE : this.level().paperConfig().collisions.maxEntityCollisions)) { // Lophine - Vanilla-like experience
break;
}
diff --git a/net/minecraft/world/entity/item/FallingBlockEntity.java b/net/minecraft/world/entity/item/FallingBlockEntity.java
index 137389f7ee97fc3a15c8f5f87c058065af91264e..dac9eab2eb844ff63353b11c5712cb825d93cf55 100644
--- a/net/minecraft/world/entity/item/FallingBlockEntity.java
+++ b/net/minecraft/world/entity/item/FallingBlockEntity.java
@@ -384,7 +384,7 @@ public class FallingBlockEntity extends Entity {
ResourceKey<Level> oldDimension = this.level().dimension();
boolean fromOrToEnd = (oldDimension == Level.END || newDimension == Level.END) && oldDimension != newDimension;
Entity newEntity = super.teleport(transition);
- this.forceTickAfterTeleportToDuplicate = newEntity != null && fromOrToEnd && (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation || me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled); // Paper // Luminol - Unsafe teleportation
+ this.forceTickAfterTeleportToDuplicate = newEntity != null && fromOrToEnd && (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation || me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled || fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled); // Paper // Luminol - Unsafe teleportation // Lophine - Vanilla-like experience
return newEntity;
}
}
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
index 44a5be736ba73c065a5b1a5fffcf2ea4a21d89dd..73ee829e4e67f1e403b78ec39937dd5d37fd304f 100644
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -261,7 +261,7 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
if (this.isMergable()) {
double radius = this.level().spigotConfig.itemMerge; // Spigot
for (ItemEntity entity : this.level()
- .getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D, radius), other -> other != this && other.isMergable())) { // Spigot // Paper - configuration to only merge items horizontally
+ .getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled ? radius : (this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D), radius), other -> other != this && other.isMergable())) { // Spigot // Paper - configuration to only merge items horizontally // Lophine - Vanilla-like experience
if (entity.isMergable()) {
// Paper start - Fix items merging through walls
if (this.level().paperConfig().fixes.fixItemsMergingThroughWalls) {
diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java
index 34018a6f7a8c97c489a938222df189e8790d015d..69e663f71a9798c33cc36f6f9341c24a15168760 100644
--- a/net/minecraft/world/entity/item/PrimedTnt.java
+++ b/net/minecraft/world/entity/item/PrimedTnt.java
@@ -110,7 +110,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
@Override
public void tick() {
- if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().getCurrentWorldData().currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot // Folia - region threading
+ if (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().getCurrentWorldData().currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot // Folia - region threading // Lophine - Vanilla-like experience
//this.handlePortal(); // Folia - region threading
this.applyGravity();
this.move(MoverType.SELF, this.getDeltaMovement());
diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java
index 6130c477349096d5912dce859b616661e2f43b36..c8c433dcfef3442ff8385c9fc1f1ea4786b1cddc 100644
--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -252,7 +252,7 @@ public class Phantom extends Mob implements Enemy {
for (Player player : players) {
if (Phantom.this.canAttack(level, player, TargetingConditions.DEFAULT)) {
- if (!level().paperConfig().entities.behavior.phantomsOnlyAttackInsomniacs || EntitySelector.IS_INSOMNIAC.test(player)) { // Paper - Add phantom creative and insomniac controls
+ if (!level().paperConfig().entities.behavior.phantomsOnlyAttackInsomniacs || fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || EntitySelector.IS_INSOMNIAC.test(player)) { // Paper - Add phantom creative and insomniac controls // Lophine - Vanilla-like experience
Phantom.this.setTarget(player, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER); // CraftBukkit - reason
return true;
} // Paper - Add phantom creative and insomniac controls
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 717cd4b18da2c637fc070c738741f926649b097f..dfb85696affef368d85f93cb0b465abb88267aa1 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -90,7 +90,8 @@ public final class NaturalSpawner {
MobCategory category = entity.getType().getCategory();
if (category != MobCategory.MISC) {
// Paper start - Only count natural spawns
- if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
+ if (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && // Lophine - Vanilla-like experience
+ !entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
!(entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL ||
entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
continue;
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
index 4f4512d30717e5e41bd98703574485c0e2b866fb..bb9950af265715dab71f2a48011de78961d83677 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -451,7 +451,7 @@ public class ServerExplosion implements Explosion {
if (this.fire || !cachedBlock.blockState.isAir()) {
ret.add(cachedBlock.immutablePos);
// Paper start - prevent headless pistons from forming
- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON) {
+ if (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && !io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == net.minecraft.world.level.block.Blocks.MOVING_PISTON) { // Lophine - Vanilla-like experience
net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(cachedBlock.immutablePos); // Paper - optimise collisions
if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) {
net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING);
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
index 64066a091628ad00d914043ae7ecd8bd29d85e5e..4fd9eb9b215c6aa5fdd95e9e961c6f991589d4b9 100644
--- a/net/minecraft/world/level/block/Block.java
+++ b/net/minecraft/world/level/block/Block.java
@@ -113,7 +113,7 @@ public class Block extends BlockBehaviour implements ItemLike {
private BlockState defaultBlockState;
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
public final boolean isDestroyable() {
- return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits ||
+ return fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || // Lophine - Vanilla-like experience
this != Blocks.BARRIER &&
this != Blocks.BEDROCK &&
this != Blocks.END_PORTAL_FRAME &&
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index b451f8234e92c36fa1395a80b01dc8780824d88e..d1068a7e89c4eee67b997d6424ff1bfc89afff70 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -188,7 +188,7 @@ public class TripWireHookBlock extends Block {
if (!cancelledEmitterHook) { // Paper - Call BlockRedstoneEvent
emitState(level, pos, attached, powered, wasAttached, wasPowered);
if (!isBeingDestroyed) {
- if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.skipTripwireHookPlacementValidation || level.getBlockState(pos).is(Blocks.TRIPWIRE_HOOK)) // Paper - Validate tripwire hook placement before update
+ if (fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.skipTripwireHookPlacementValidation || level.getBlockState(pos).is(Blocks.TRIPWIRE_HOOK)) // Paper - Validate tripwire hook placement before update // Lophine - Vanilla-like experience
level.setBlock(pos, newState.setValue(FACING, direction), Block.UPDATE_ALL);
if (canUpdate) {
notifyNeighbors(block, level, pos, direction);
diff --git a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
index 0bbce88f95c8f96d865f3c58e830e5aa006e48bb..1cf8b71bb636b92df21b2e5027ad3deed8476e80 100644
--- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -322,7 +322,7 @@ public class BeehiveBlockEntity extends BlockEntity {
iterator.remove();
}
// Paper start - Fix bees aging inside; use exitTickCounter to keep actual bee life
- else if (level.paperConfig().entities.behavior.cooldownFailedBeehiveReleases) {
+ else if (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && level.paperConfig().entities.behavior.cooldownFailedBeehiveReleases) { // Lophine - Vanilla-like experience
data.exitTickCounter = data.occupant.minTicksInHive / 2;
}
// Paper end - Fix bees aging inside; use exitTickCounter to keep actual bee life
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index df57ae93f91daf8daed2fef48b685c72f0615763..37c15510d182aa6751827c7ec4d151047101faf8 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -346,7 +346,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
origItemStack.setCount(originalItemCount);
}
}
- if (foundItem && level.paperConfig().hopper.cooldownWhenFull) { // Inventory was full - cooldown
+ if (foundItem && !fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && level.paperConfig().hopper.cooldownWhenFull) { // Inventory was full - cooldown // Lophine - Vanilla-like experience
hopper.setCooldown(level.spigotConfig.hopperTransfer);
}
return false;
diff --git a/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/net/minecraft/world/level/block/piston/PistonBaseBlock.java
index e8f7944220d76d5c9111c6552e7904751aa26018..0c0076dc14cfb07c9de28ec1b2375d0dc4253fe4 100644
--- a/net/minecraft/world/level/block/piston/PistonBaseBlock.java
+++ b/net/minecraft/world/level/block/piston/PistonBaseBlock.java
@@ -152,7 +152,7 @@ public class PistonBaseBlock extends DirectionalBlock {
Direction direction = state.getValue(FACING);
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed; prevent retracting when we're facing the wrong way (we were replaced before retraction could occur)
Direction directionQueuedAs = Direction.from3DDataValue(b1 & 7); // Paper - copied from below
- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits && direction != directionQueuedAs) {
+ if (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && !io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits && direction != directionQueuedAs) { // Lophine - Vanilla-like experience
return false;
}
// Paper end - Protect Bedrock and End Portal/Frames from being destroyed
@@ -236,7 +236,7 @@ public class PistonBaseBlock extends DirectionalBlock {
} else {
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed; fix headless pistons breaking blocks
BlockPos headPos = pos.relative(direction);
- if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || level.getBlockState(headPos) == Blocks.PISTON_HEAD.defaultBlockState().setValue(FACING, direction)) { // double check to make sure we're not a headless piston
+ if (fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || level.getBlockState(headPos) == Blocks.PISTON_HEAD.defaultBlockState().setValue(FACING, direction)) { // double check to make sure we're not a headless piston // Lophine - Vanilla-like experience
level.removeBlock(headPos, false);
} else {
((ServerLevel) level).getChunkSource().blockChanged(headPos); // ... fix client desync
@@ -387,7 +387,7 @@ public class PistonBaseBlock extends DirectionalBlock {
for (int i = toPush.size() - 1; i >= 0; i--) {
// Paper start - fix a variety of piston desync dupes
- boolean allowDesync = !fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.tntDupingFix;
+ boolean allowDesync = fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || !fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.tntDupingFix; // Lophine - Vanilla-like experience
BlockPos oldPos = toPush.get(i);
BlockPos pos = oldPos;
BlockState blockState = allowDesync ? level.getBlockState(oldPos) : null;
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
index 199f23547fded9b7d311b9cf21484d863748fd1c..04e310cdbe22b1d4abfd6d4673551abc5a40d2a9 100644
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -334,7 +334,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
if (level.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
BlockState newState = Block.updateFromNeighbourShapes(entity.movedState, level, pos);
if (newState.isAir()) {
- level.setBlock(pos, entity.movedState, Block.UPDATE_NONE | Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_KNOWN_SHAPE | (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication ? 0 : Block.UPDATE_CLIENTS)); // Paper - fix a variety of piston desync dupes; force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air
+ level.setBlock(pos, entity.movedState, Block.UPDATE_NONE | Block.UPDATE_MOVE_BY_PISTON | Block.UPDATE_KNOWN_SHAPE | ((fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication) ? 0 : Block.UPDATE_CLIENTS)); // Paper - fix a variety of piston desync dupes; force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air // Lophine - Vanilla-like experience
Block.updateOrDestroy(entity.movedState, newState, level, pos, Block.UPDATE_ALL);
} else {
if (newState.hasProperty(BlockStateProperties.WATERLOGGED) && newState.getValue(BlockStateProperties.WATERLOGGED)) {
diff --git a/net/minecraft/world/level/levelgen/PhantomSpawner.java b/net/minecraft/world/level/levelgen/PhantomSpawner.java
index ec3a437bd8a7d0e95e1e5fa0ff4462a70391ecf9..007be83486f8b7b921e3bd06abaf02ae6d60b8ea 100644
--- a/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -41,7 +41,7 @@ public class PhantomSpawner implements CustomSpawner {
// Paper end - Ability to control player's insomnia and phantoms
if (level.getSkyDarken() >= 5 || !level.dimensionType().hasSkyLight()) {
for (ServerPlayer player : level.getLocalPlayers()) { // Folia - region threading
- if (!player.isSpectator() && (!level.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !player.isCreative())) { // Paper - Add phantom creative and insomniac controls
+ if (!player.isSpectator() && (fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled || !level.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !player.isCreative())) { // Paper - Add phantom creative and insomniac controls // Lophine - Vanilla-like experience
BlockPos playerPos = player.blockPosition();
if (!level.dimensionType().hasSkyLight() || playerPos.getY() >= level.getSeaLevel() && level.canSeeSky(playerPos)) {
DifficultyInstance difficulty = level.getCurrentDifficultyAt(playerPos);
diff --git a/net/minecraft/world/level/portal/PortalForcer.java b/net/minecraft/world/level/portal/PortalForcer.java
index a468a1013058089115d023e8957f976ae34935ad..a2ba7f683aedb5eadb785db7660dae446e914ab4 100644
--- a/net/minecraft/world/level/portal/PortalForcer.java
+++ b/net/minecraft/world/level/portal/PortalForcer.java
@@ -233,7 +233,7 @@ public class PortalForcer {
origin, direction.getStepX() * width + clockWise.getStepX() * offset, height, direction.getStepZ() * width + clockWise.getStepZ() * offset
);
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits) {
+ if (!fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig.enabled && !io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits) { // Lophine - Vanilla-like experience
if (!this.level.getBlockState(mutable).isDestroyable()) {
return false;
}
@@ -0,0 +1,224 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bacteriawa <A3167717663@hotmail.com>
Date: Wed, 24 Jun 2026 00:00:00 +0800
Subject: [PATCH] Restore vanilla ender pearl loading
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index cef9c7887332b91e2466a97a5250db81f7af0dcf..a17212c1910ce9490fe8df8c4ef507e25b89c545 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -277,7 +277,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
private @Nullable BlockPos raidOmenPosition;
private Vec3 lastKnownClientMovement = Vec3.ZERO;
private Input lastClientInput = Input.EMPTY;
- private final Set<ThrownEnderpearl> enderPearls = new HashSet<>();
+ private final Set<ThrownEnderpearl> enderPearls = java.util.concurrent.ConcurrentHashMap.newKeySet(); // Lophine - restore vanilla ender pearl loading on Folia
private long timeEntitySatOnShoulder;
private CompoundTag shoulderEntityLeft = new CompoundTag();
private CompoundTag shoulderEntityRight = new CompoundTag();
@@ -785,16 +785,17 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
private void saveEnderPearls(final ValueOutput playerOutput) {
if (!this.enderPearls.isEmpty()) {
- ValueOutput.ValueOutputList pearlsOutput = playerOutput.childrenList("ender_pearls");
-
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ ValueOutput.TypedOutputList<CompoundTag> pearlsOutput = null;
for (ThrownEnderpearl enderPearl : this.enderPearls) {
- if (enderPearl.level().paperConfig().misc.legacyEnderPearlBehavior) continue; // Paper - Allow using old ender pearl behavior
- if (enderPearl.isRemoved()) {
- LOGGER.warn("Trying to save removed ender pearl, skipping");
+ CompoundTag pearlTag = enderPearl.getLastSavedEnderPearlTag();
+ if (pearlTag == null) {
+ LOGGER.warn("Trying to save ender pearl without a region-owned snapshot, skipping");
} else {
- ValueOutput pearlTag = pearlsOutput.addChild();
- enderPearl.save(pearlTag);
- pearlTag.store("ender_pearl_dimension", Level.RESOURCE_KEY_CODEC, enderPearl.level().dimension());
+ if (pearlsOutput == null) {
+ pearlsOutput = playerOutput.list(ServerPlayer.ENDER_PEARLS_TAG, CompoundTag.CODEC);
+ }
+ pearlsOutput.add(pearlTag);
}
}
}
@@ -1185,6 +1186,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
);
}
}
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
}
@@ -3568,11 +3570,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
public void registerEnderPearl(final ThrownEnderpearl enderPearl) {
- //this.enderPearls.add(enderPearl); // Folia - region threading - do not track ender pearls
+ this.enderPearls.add(enderPearl); // Lophine - restore vanilla ender pearl loading on Folia
}
public void deregisterEnderPearl(final ThrownEnderpearl enderPearl) {
- //this.enderPearls.remove(enderPearl); // Folia - region threading - do not track ender pearls
+ this.enderPearls.remove(enderPearl); // Lophine - restore vanilla ender pearl loading on Folia
}
public Set<ThrownEnderpearl> getEnderPearls() {
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 432a6dfff8e45eccea653b0d4cf04956edec6d98..835c13ff69592951261f917ad999d9a7689e802c 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -748,11 +748,13 @@ public abstract class PlayerList {
player.unRide();
for (ThrownEnderpearl enderpearl : player.getEnderPearls()) {
- // Paper start - Allow using old ender pearl behavior
- if (!enderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) {
- enderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, org.bukkit.event.entity.EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause
- }
- // Paper end - Allow using old ender pearl behavior
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ enderpearl.getBukkitEntity().taskScheduler.scheduleOrExecute((Entity pearl) -> {
+ if (!pearl.isRemoved()) {
+ pearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, org.bukkit.event.entity.EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause
+ }
+ });
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
level.removePlayerImmediately(player, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
diff --git a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java
index ad35eafa457f706879ba8a9c92b3a34e620ee2d6..7b607a9fb9955f0a1b843ed59d6b15e97fd37325 100644
--- a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java
+++ b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java
@@ -31,7 +31,11 @@ import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
public class ThrownEnderpearl extends ThrowableItemProjectile {
+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Lophine - restore vanilla ender pearl loading on Folia
private long ticketTimer = 0L;
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ private volatile net.minecraft.nbt.@Nullable CompoundTag lastSavedEnderPearlTag;
+ // Lophine end - restore vanilla ender pearl loading on Folia
public ThrownEnderpearl(final EntityType<? extends ThrownEnderpearl> type, final Level level) {
super(type, level);
@@ -39,6 +43,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
public ThrownEnderpearl(final Level level, final LivingEntity mob, final ItemStack itemStack) {
super(EntityTypes.ENDER_PEARL, mob, level, itemStack);
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ this.updateLastSavedEnderPearlTag();
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
@Override
@@ -51,21 +58,73 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
this.deregisterFromCurrentOwner();
super.setOwner(owner);
this.registerToCurrentOwner();
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ this.updateLastSavedEnderPearlTag();
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
private void deregisterFromCurrentOwner() {
- // Folia - region threading - we remove the registration logic, we do not need to fetch the owner
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ if (this.owner != null && this.level() instanceof ServerLevel serverLevel && serverLevel.getServer().getPlayerList().getPlayer(this.owner.getUUID()) instanceof ServerPlayer serverPlayer) {
+ serverPlayer.deregisterEnderPearl(this);
+ }
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
private void registerToCurrentOwner() {
- // Folia - region threading - we remove the registration logic, we do not need to fetch the owner
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ if (this.owner != null
+ && this.level() instanceof ServerLevel serverLevel
+ && !serverLevel.paperConfig().misc.legacyEnderPearlBehavior
+ && serverLevel.getServer().getPlayerList().getPlayer(this.owner.getUUID()) instanceof ServerPlayer serverPlayer) {
+ serverPlayer.registerEnderPearl(this);
+ }
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ public net.minecraft.nbt.@Nullable CompoundTag getLastSavedEnderPearlTag() {
+ net.minecraft.nbt.CompoundTag tag = this.lastSavedEnderPearlTag;
+ return tag == null ? null : tag.copy();
+ }
+
+ public void updateLastSavedEnderPearlTag() {
+ if (this.owner == null || this.isRemoved() || !(this.level() instanceof ServerLevel serverLevel) || serverLevel.paperConfig().misc.legacyEnderPearlBehavior) {
+ this.lastSavedEnderPearlTag = null;
+ return;
+ }
+ try (net.minecraft.util.ProblemReporter.ScopedCollector problemReporter = new net.minecraft.util.ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) {
+ net.minecraft.world.level.storage.TagValueOutput pearlOutput = net.minecraft.world.level.storage.TagValueOutput.createWithContext(problemReporter, this.registryAccess());
+ if (this.save(pearlOutput)) {
+ pearlOutput.store(ServerPlayer.ENDER_PEARL_DIMENSION_TAG, Level.RESOURCE_KEY_CODEC, this.level().dimension());
+ this.lastSavedEnderPearlTag = pearlOutput.buildResult();
+ } else {
+ this.lastSavedEnderPearlTag = null;
+ }
+ }
+ }
+ // Lophine end - restore vanilla ender pearl loading on Folia
+
@Override
public @Nullable Entity getOwner() {
return this.owner != null && this.level() instanceof ServerLevel serverLevel ? this.owner.getEntity(serverLevel, Entity.class) : super.getOwner();
}
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ @Override
+ protected void readAdditionalSaveData(final net.minecraft.world.level.storage.ValueInput input) {
+ super.readAdditionalSaveData(input);
+ this.updateLastSavedEnderPearlTag();
+ }
+
+ @Override
+ public void restoreFrom(final Entity oldEntity) {
+ super.restoreFrom(oldEntity);
+ this.registerToCurrentOwner();
+ this.updateLastSavedEnderPearlTag();
+ }
+ // Lophine end - restore vanilla ender pearl loading on Folia
+
private static @Nullable Entity findOwnerIncludingDeadPlayer(final ServerLevel serverLevel, final UUID uuid) {
Entity owner = serverLevel.getEntityInAnyDimension(uuid);
return owner != null ? owner : serverLevel.getServer().getPlayerList().getPlayer(uuid);
@@ -283,6 +342,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
&& owner instanceof ServerPlayer serverPlayer) {
this.ticketTimer = serverPlayer.registerAndUpdateEnderPearlTicket(this);
}
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ this.updateLastSavedEnderPearlTag();
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
} else {
super.tick();
@@ -330,6 +392,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
public void onRemoval(final Entity.RemovalReason reason) {
if (reason != Entity.RemovalReason.UNLOADED_WITH_PLAYER) {
this.deregisterFromCurrentOwner();
+ // Lophine start - restore vanilla ender pearl loading on Folia
+ this.lastSavedEnderPearlTag = null;
+ // Lophine end - restore vanilla ender pearl loading on Folia
}
super.onRemoval(reason);
diff --git a/net/minecraft/world/item/EnderpearlItem.java b/net/minecraft/world/item/EnderpearlItem.java
index 17a005321601b0fef71604e4468134f1e98cd974..a270b4ca7d65b91ffcf292ff80f3a23124cd595c 100644
--- a/net/minecraft/world/item/EnderpearlItem.java
+++ b/net/minecraft/world/item/EnderpearlItem.java
@@ -27,6 +27,7 @@ public class EnderpearlItem extends Item {
final Projectile.Delayed<ThrownEnderpearl> thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, serverLevel, itemStack, player, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, 1.0F);
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity());
if (event.callEvent() && thrownEnderpearl.attemptSpawn()) {
+ thrownEnderpearl.projectile().updateLastSavedEnderPearlTag(); // Lophine - restore vanilla ender pearl loading on Folia
if (event.shouldConsume()) {
itemStack.consume(1, player);
} else {
@@ -35,7 +35,7 @@ index fcdfd4f6de5e1c2d5e80c7f3d8cb0b33a62d257d..6eaa4e9bd1ecbfa531313ce1f470d55e
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>();
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
index a5f2e4454258886536251288c3694f58386c7420..28371ecf31d5fc280aaa03ed9a86f5b565cf32f6 100644
index fd7cd6f72390c71d036ebfc0e4c67dad51eb2e9c..62e5fcc1845d1240a1b97cdf252c94b75e81d4ab 100644
--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
@@ -40,8 +40,8 @@ public class PaperVersionFetcher implements VersionFetcher {
@@ -44,13 +44,13 @@ index a5f2e4454258886536251288c3694f58386c7420..28371ecf31d5fc280aaa03ed9a86f5b5
private static final int DISTANCE_UNKNOWN = -2;
- private static final String DOWNLOAD_PAGE = "https://github.com/LuminolMC/Luminol"; // Luminol
- private static final String REPOSITORY = "LuminolMC/Luminol"; // Luminol
+ private static final String DOWNLOAD_PAGE = "https://github.com/LuminolMC/Lophine"; // Luminol // Lophine
+ private static final String REPOSITORY = "LuminolMC/Lophine"; // Luminol // Lophine
+ private static final String DOWNLOAD_PAGE = "https://github.com/LophineCraft/Lophine"; // Luminol // Lophine
+ private static final String REPOSITORY = "LophineCraft/Lophine"; // Luminol // Lophine
private static final ServerBuildInfo BUILD_INFO = ServerBuildInfo.buildInfo();
private static final String USER_AGENT = BUILD_INFO.brandName() + "/" + BUILD_INFO.asString(VERSION_SIMPLE) + " (https://papermc.io)";
private static final Gson GSON = new Gson();
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
index 4ada790812957657d580cb748077c4961987d0cb..3a539df860305e777e85ed6dc72b5effe76734b4 100644
index 4ada790812957657d580cb748077c4961987d0cb..ddf3ad20e7ce967d9e096345f99c55abf066c3b3 100644
--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
@@ -31,7 +31,7 @@ public record ServerBuildInfoImpl(
@@ -58,7 +58,7 @@ index 4ada790812957657d580cb748077c4961987d0cb..3a539df860305e777e85ed6dc72b5eff
private static final String BRAND_PAPER_NAME = "Paper";
- private static final String BRAND_LUMINOL_NAME = "Luminol";
+ private static final String BRAND_LOPHINE_NAME = "Lophine";
+ private static final String BRAND_LOPHINE_NAME = "Lophine"; // Lophine - Rebrand to Lophine
private static final String BUILD_DEV = "DEV";
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e7f4a313ff0d2469
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index ba0779211405b8b83f7c7e7b1c55b3e4846029a3..5f685b07878443bfe5f63147a0728df0708d79ad 100644
index d61f38fdf84830c2e94dee8dd7c9a0400ec07318..14a8a00d9c1fc7d49d6f870bf10b9a5e178b1189 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -483,6 +483,7 @@ public final class CraftServer implements Server {
@@ -479,6 +479,7 @@ public final class CraftServer implements Server {
this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
if (false) this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark // Luminol - Force disable builtin spark
@@ -19,7 +19,7 @@ index ba0779211405b8b83f7c7e7b1c55b3e4846029a3..5f685b07878443bfe5f63147a0728df0
}
public boolean getCommandBlockOverride(String command) {
@@ -1057,6 +1058,7 @@ public final class CraftServer implements Server {
@@ -1052,6 +1053,7 @@ public final class CraftServer implements Server {
if (false) this.spark.registerCommandBeforePlugins(this); // Paper - spark // Luminol - Force disable builtin spark
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
@@ -41,10 +41,10 @@ index 9180f23529a31b6b0a5b38bb7cda3e32d487f691..d0b763f07aee56f69a67c87d7dd15a44
if (!registration.getPlugin().isEnabled()) {
continue;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
index 5339ff469a38d35e72ea7227503a84395462f84a..d75b4ecb24f2ea42afc82ac255775d8f35121fe5 100644
index 3a47e4c633ee016d5deeb6a5ee9e2e26769d5193..efb47f914fd0c0e966c6921ed1b26c4139754c55 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
@@ -373,6 +373,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
@@ -375,6 +375,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
@SuppressWarnings("unchecked")
public <T extends Entity> T addEntity(T entity) {
Preconditions.checkArgument(!entity.isInWorld(), "Entity has already been added to a world");
@@ -53,10 +53,10 @@ index 5339ff469a38d35e72ea7227503a84395462f84a..d75b4ecb24f2ea42afc82ac255775d8f
if (nmsEntity.level() != this.getHandle().getLevel()) {
throw new IllegalArgumentException(entity + " wasn't created with this world, you must create the entity with the world you want to add it to.");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 5f685b07878443bfe5f63147a0728df0708d79ad..0eb89fc127738e02e8d4d49418b83baaffe00cbd 100644
index 14a8a00d9c1fc7d49d6f870bf10b9a5e178b1189..7fd08dac549261c50cf5723ef380ba90ea0da56f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -303,6 +303,7 @@ public final class CraftServer implements Server {
@@ -304,6 +304,7 @@ public final class CraftServer implements Server {
private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer;
public io.papermc.paper.SparksFly spark; // Paper - spark // Luminol - Force disable builtin spark
private final ServerConfiguration serverConfig = new PaperServerConfiguration();
@@ -64,7 +64,7 @@ index 5f685b07878443bfe5f63147a0728df0708d79ad..0eb89fc127738e02e8d4d49418b83baa
// Paper start - Folia region threading API
private final io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler(); // Folia - region threading
@@ -484,6 +485,7 @@ public final class CraftServer implements Server {
@@ -480,6 +481,7 @@ public final class CraftServer implements Server {
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
if (false) this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark // Luminol - Force disable builtin spark
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.init(); // Leaves - protocol
@@ -72,7 +72,7 @@ index 5f685b07878443bfe5f63147a0728df0708d79ad..0eb89fc127738e02e8d4d49418b83baa
}
public boolean getCommandBlockOverride(String command) {
@@ -1377,7 +1379,7 @@ public final class CraftServer implements Server {
@@ -1380,7 +1382,7 @@ public final class CraftServer implements Server {
return false;
}
@@ -81,7 +81,7 @@ index 5f685b07878443bfe5f63147a0728df0708d79ad..0eb89fc127738e02e8d4d49418b83baa
return false;
}
@@ -3113,6 +3115,13 @@ public final class CraftServer implements Server {
@@ -3119,6 +3121,13 @@ public final class CraftServer implements Server {
}
// Leaves end - Feature API
@@ -96,10 +96,10 @@ index 5f685b07878443bfe5f63147a0728df0708d79ad..0eb89fc127738e02e8d4d49418b83baa
/**
* Gets the TPS from the region which owns the specified location, or {@code null} if no region owns
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 03ad9254c4b5556119fe73d533ceac7073b8fe74..fd2e24b6219219fa1fe7d2ba1d877ee4c24676ca 100644
index 5fc4b44c05b34b64dfdfc1fe996124ec03490465..d90a194ac7ec1fd496fb305caf6752732bccfb45 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -255,7 +255,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -247,7 +247,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public int getPlayerCount() {
@@ -108,7 +108,7 @@ index 03ad9254c4b5556119fe73d533ceac7073b8fe74..fd2e24b6219219fa1fe7d2ba1d877ee4
}
@Override
@@ -1126,9 +1126,9 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -1122,9 +1122,9 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public List<Player> getPlayers() {
@@ -120,7 +120,7 @@ index 03ad9254c4b5556119fe73d533ceac7073b8fe74..fd2e24b6219219fa1fe7d2ba1d877ee4
HumanEntity bukkitEntity = human.getBukkitEntity();
if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) {
@@ -1628,7 +1628,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -1624,7 +1624,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public void playSound(final net.kyori.adventure.sound.Sound sound) {
org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
final long seed = sound.seed().orElseGet(this.world.getRandom()::nextLong);
@@ -129,7 +129,7 @@ index 03ad9254c4b5556119fe73d533ceac7073b8fe74..fd2e24b6219219fa1fe7d2ba1d877ee4
player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player.getX(), player.getY(), player.getZ(), seed, null));
}
}
@@ -1656,7 +1656,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -1652,7 +1652,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
final long seed = sound.seed().orElseGet(this.getHandle().getRandom()::nextLong);
if (emitter == net.kyori.adventure.sound.Sound.Emitter.self()) {
@@ -138,7 +138,7 @@ index 03ad9254c4b5556119fe73d533ceac7073b8fe74..fd2e24b6219219fa1fe7d2ba1d877ee4
player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player, seed, null));
}
} else if (emitter instanceof CraftEntity craftEntity) {
@@ -1779,7 +1779,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -1775,7 +1775,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
}
this.getHandle().sendParticlesSource(
@@ -148,10 +148,10 @@ index 03ad9254c4b5556119fe73d533ceac7073b8fe74..fd2e24b6219219fa1fe7d2ba1d877ee4
CraftParticle.createParticleParam(particle, data), // Particle
force,
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index d43b1a6e6a8ac2a21b0a048e838115b0403170dd..42c2c6a05645e5aef26e9d3a91ad93563a297ca3 100644
index efcb8b97cd685e1243c770bf3e8daf03615abb1d..4722e027ed5869516adddf696ac030fd84df834d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -127,6 +127,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -128,6 +128,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return new CraftHumanEntity(server, (net.minecraft.world.entity.player.Player) entity);
}
@@ -161,10 +161,10 @@ index d43b1a6e6a8ac2a21b0a048e838115b0403170dd..42c2c6a05645e5aef26e9d3a91ad9356
if (entity instanceof EnderDragonPart complexPart) {
if (complexPart.parentMob instanceof EnderDragon) {
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 23882dbe5fdfe9f0cf98a13791f70fe83393639d..41cf8145a6a5f1542e06af522201fccef1d5f07d 100644
index 0754bd441290bacc27f3d1ae2d6cf5af94345745..04119b949c878064a0ae1028f7147de7c0e7aa16 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1004,7 +1004,11 @@ public class CraftEventFactory {
@@ -1009,7 +1009,11 @@ public class CraftEventFactory {
event.setKeepInventory(keepInventory);
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
populateFields(victim, event); // Paper - make cancellable
@@ -21,10 +21,10 @@ index d0b763f07aee56f69a67c87d7dd15a44b6f44db7..bd301425f4c3cdf2b2bd22c1775b7ca9
}
// Leaves end - skip bot
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0eb89fc127738e02e8d4d49418b83baaffe00cbd..53e49df883ec0fab984f2329d044d12ed6b1edff 100644
index 7fd08dac549261c50cf5723ef380ba90ea0da56f..7cfa9a5a1629c3af1e1105b137cbfc4c0aabe86e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -304,6 +304,7 @@ public final class CraftServer implements Server {
@@ -305,6 +305,7 @@ public final class CraftServer implements Server {
public io.papermc.paper.SparksFly spark; // Paper - spark // Luminol - Force disable builtin spark
private final ServerConfiguration serverConfig = new PaperServerConfiguration();
private final org.leavesmc.leaves.entity.bot.CraftBotManager botManager; // Leaves
@@ -32,16 +32,16 @@ index 0eb89fc127738e02e8d4d49418b83baaffe00cbd..53e49df883ec0fab984f2329d044d12e
// Paper start - Folia region threading API
private final io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler(); // Folia - region threading
@@ -398,7 +399,7 @@ public final class CraftServer implements Server {
@@ -399,7 +400,7 @@ public final class CraftServer implements Server {
public CraftServer(DedicatedServer console, PlayerList playerList) {
this.console = console;
this.playerList = (DedicatedPlayerList) playerList;
- this.playerView = Collections.unmodifiableList(Lists.transform(playerList.players, new Function<ServerPlayer, CraftPlayer>() {
+ this.playerView = Collections.unmodifiableList(Lists.transform(playerList.realPlayers, new Function<ServerPlayer, CraftPlayer>() { // Leaves - replay api
@Override
public CraftPlayer apply(ServerPlayer player) {
return player.getBukkitEntity();
@@ -3186,4 +3187,11 @@ public final class CraftServer implements Server {
- this.playerView = MCUtil.transformUnmodifiable(playerList.getPlayers(), ServerPlayer::getBukkitEntity);
+ this.playerView = MCUtil.transformUnmodifiable(playerList.realPlayers, ServerPlayer::getBukkitEntity);
this.serverVersion = io.papermc.paper.ServerBuildInfo.buildInfo().asString(io.papermc.paper.ServerBuildInfo.StringRepresentation.VERSION_SIMPLE); // Paper - improve version
this.structureManager = new CraftStructureManager(console.getStructureManager(), console.registryAccess());
this.serverTickManager = new CraftServerTickManager(console.tickRateManager());
@@ -3192,4 +3193,11 @@ public final class CraftServer implements Server {
}
}
// Folia end - region TPS API
@@ -54,10 +54,10 @@ index 0eb89fc127738e02e8d4d49418b83baaffe00cbd..53e49df883ec0fab984f2329d044d12e
+ // Leaves end - replay mod api
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 42c2c6a05645e5aef26e9d3a91ad93563a297ca3..759d54f1f012461fc322d452bb26f7fd6e601039 100644
index 4722e027ed5869516adddf696ac030fd84df834d..4d20f07ff4bf782e938ac990e2b9aaeb90b92db1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -128,6 +128,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -129,6 +129,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
}
if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) { return new org.leavesmc.leaves.entity.bot.CraftBot(server, bot); }
@@ -66,10 +66,10 @@ index 42c2c6a05645e5aef26e9d3a91ad93563a297ca3..759d54f1f012461fc322d452bb26f7fd
// Special case complex part, since there is no extra entity type for them
if (entity instanceof EnderDragonPart complexPart) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 47926ff2fba43bb83e2d9747420a526cce8ebe65..e72cd3c9919978a0ed91614d51d018bfb2cdb900 100644
index e655c6b817b1ef2b3186c4b16a1039081139e97f..96d8ed40eae0765d5d48b1397de525581b8bf2fb 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2086,7 +2086,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa
@@ -2085,7 +2085,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa
@Override
public boolean canSee(Player player) {
@@ -79,10 +79,10 @@ index 47926ff2fba43bb83e2d9747420a526cce8ebe65..e72cd3c9919978a0ed91614d51d018bf
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index fa3e2bf2b31ca5173d71082e93eb7eaa4faa2816..bd3c4eb10489f13562b31f4b809e80b19717bc25 100644
index c189f583598f94fc7944afcabe130c5ee9504c0d..2e56d20d50d8a5d5630816b822b10a43ce3fa6c7 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -347,7 +347,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@@ -294,7 +294,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
Bukkit.getLogger().log(Level.SEVERE, "Error saving advancement " + key, ex);
}
@@ -92,14 +92,14 @@ index fa3e2bf2b31ca5173d71082e93eb7eaa4faa2816..bd3c4eb10489f13562b31f4b809e80b1
player.getAdvancements().flushDirty(player, false);
});
diff --git a/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java b/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java
index 25aae550dcdcef2df268d0dd99bdcc9bbd49fcf8..83af50de50a03e164d572f3c3466b6d0b42ed138 100644
index 15261d2e96347584e4baf65f12b336b73a68cd37..83af50de50a03e164d572f3c3466b6d0b42ed138 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java
@@ -23,7 +23,7 @@ public class LazyPlayerSet extends LazyHashSet<Player> {
}
public static Set<Player> makePlayerSet(final MinecraftServer server) {
- List<ServerPlayer> players = server.getPlayerList().players;
- List<ServerPlayer> players = server.getPlayerList().getPlayers();
+ List<ServerPlayer> players = server.getPlayerList().realPlayers; // Leaves - only real players
Set<Player> reference = new HashSet<>(players.size());
for (ServerPlayer player : players) {
@@ -4,6 +4,7 @@ import fun.bm.lophine.carpet.config.modules.FakePlayerCompatConfig;
import fun.bm.lophine.carpet.config.modules.GeneralCompatConfig;
import fun.bm.lophine.carpet.config.modules.WoolHopperCounterConfig;
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
import fun.bm.lophine.config.modules.function.protocol.PcaSyncProtocolConfig;
import fun.bm.lophine.protocol.CarpetLoggerProtocol;
import org.leavesmc.leaves.protocol.CarpetServerProtocol;
@@ -24,75 +25,83 @@ public final class CarpetCompatSync {
}
private static void registerProtocolRules() {
CarpetServerProtocol.CarpetRules.clear();
CarpetServerProtocol.CarpetRules.beginBatch();
try {
CarpetServerProtocol.CarpetRules.clear();
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "language", GeneralCompatConfig.language));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "amsUpdateSuppressionCrashFix", GeneralCompatConfig.amsUpdateSuppressionCrashFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "yeetUpdateSuppressionCrash", GeneralCompatConfig.yeetUpdateSuppressionCrash));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "dustTrapdoorReintroduced", GeneralCompatConfig.dustTrapdoorReintroduced));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "shulkerBoxCCEReintroduced", GeneralCompatConfig.shulkerBoxCCEReintroduced));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "instantBlockUpdaterReintroduced", GeneralCompatConfig.instantBlockUpdaterReintroduced));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "commandTick", GeneralCompatConfig.commandTick));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "creativeNoClip", GeneralCompatConfig.creativeNoClip));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedDragonRespawn", GeneralCompatConfig.optimizedDragonRespawn));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "antiSpamDisabled", GeneralCompatConfig.antiSpamDisabled));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "blockPlacementIgnoreEntity", GeneralCompatConfig.blockPlacementIgnoreEntity));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "creativeOpenContainerForcibly", GeneralCompatConfig.creativeOpenContainerForcibly));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "creativeOneHitKill", GeneralCompatConfig.creativeOneHitKill));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "observerNoDetection", GeneralCompatConfig.observerNoDetection));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "bambooModelNoOffset", GeneralCompatConfig.bambooModelNoOffset));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "creativeNoItemCooldown", GeneralCompatConfig.creativeNoItemCooldown));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "ctrlQCraftingFix", GeneralCompatConfig.ctrlQCraftingFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "carpetAlwaysSetDefault", GeneralCompatConfig.carpetAlwaysSetDefault));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "placementRotationFix", GeneralCompatConfig.placementRotationFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "tntDoNotUpdate", GeneralCompatConfig.tntDoNotUpdate));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "totallyNoBlockUpdate", GeneralCompatConfig.totallyNoBlockUpdate));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tiscmNetworkProtocol", GeneralCompatConfig.tiscmNetworkProtocol));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetorgaddition", "hopperNoItemCost", GeneralCompatConfig.hopperNoItemCost));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "explosionNoBlockDamage", GeneralCompatConfig.explosionNoBlockDamage));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedTNTHighPriority", GeneralCompatConfig.optimizedTNTHighPriority));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "tntPrimerMomentumRemoved", GeneralCompatConfig.tntPrimerMomentumRemoved));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tntIgnoreRedstoneSignal", GeneralCompatConfig.tntIgnoreRedstoneSignal));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tntDupingFix", GeneralCompatConfig.tntDupingFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "interactionUpdates", GeneralCompatConfig.interactionUpdates));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "xpNoCooldown", GeneralCompatConfig.xpNoCooldown));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "powerfulExpMending", GeneralCompatConfig.powerfulExpMending));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "clientSettingsLostOnRespawnFix", GeneralCompatConfig.clientSettingsLostOnRespawnFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "sensibleEnderman", GeneralCompatConfig.sensibleEnderman));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "entityInstantDeathRemoval", GeneralCompatConfig.entityInstantDeathRemoval));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "farmlandTrampledDisabled", GeneralCompatConfig.farmlandTrampledDisabled));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "shulkerGolem", GeneralCompatConfig.shulkerGolem));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "preventEndSpikeRespawn", GeneralCompatConfig.preventEndSpikeRespawn));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "yeetOutOfOrderChatKick", GeneralCompatConfig.yeetOutOfOrderChatKick));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "betterCraftableBoneBlock", GeneralCompatConfig.betterCraftableBoneBlock));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "betterCraftableDispenser", GeneralCompatConfig.betterCraftableDispenser));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "viewDistance", GeneralCompatConfig.viewDistance));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tickCommandPermission", GeneralCompatConfig.normalizedTickCommandPermission()));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tickFreezeCommandToggleable", GeneralCompatConfig.tickFreezeCommandToggleable));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "syncServerMsptMetricsData", GeneralCompatConfig.syncServerMsptMetricsData));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetorgaddition", "simpleInGameCalculator", GeneralCompatConfig.simpleInGameCalculator));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "microTiming", GeneralCompatConfig.microTiming));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "fastRedstoneDust", GeneralCompatConfig.fastRedstoneDust));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "lagFreeSpawning", GeneralCompatConfig.lagFreeSpawning));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedFastEntityMovement", GeneralCompatConfig.optimizedFastEntityMovement));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedHardHitBoxEntityCollision", GeneralCompatConfig.optimizedHardHitBoxEntityCollision));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tntFuseDuration", GeneralCompatConfig.normalizedTntFuseDuration()));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "defaultLoggers", CarpetLoggerProtocol.serializeConfiguredDefaults(sanitizeDefaultLoggers(GeneralCompatConfig.defaultLoggers))));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "language", GeneralCompatConfig.language));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "amsUpdateSuppressionCrashFix", GeneralCompatConfig.amsUpdateSuppressionCrashFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "yeetUpdateSuppressionCrash", GeneralCompatConfig.yeetUpdateSuppressionCrash));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "dustTrapdoorReintroduced", GeneralCompatConfig.dustTrapdoorReintroduced));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "shulkerBoxCCEReintroduced", GeneralCompatConfig.shulkerBoxCCEReintroduced));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "instantBlockUpdaterReintroduced", GeneralCompatConfig.instantBlockUpdaterReintroduced));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "commandTick", GeneralCompatConfig.commandTick));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "creativeNoClip", GeneralCompatConfig.creativeNoClip));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedDragonRespawn", GeneralCompatConfig.optimizedDragonRespawn));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "antiSpamDisabled", GeneralCompatConfig.antiSpamDisabled));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "blockPlacementIgnoreEntity", GeneralCompatConfig.blockPlacementIgnoreEntity));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "creativeOpenContainerForcibly", GeneralCompatConfig.creativeOpenContainerForcibly));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "creativeOneHitKill", GeneralCompatConfig.creativeOneHitKill));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "observerNoDetection", GeneralCompatConfig.observerNoDetection));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "bambooModelNoOffset", GeneralCompatConfig.bambooModelNoOffset));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "creativeNoItemCooldown", GeneralCompatConfig.creativeNoItemCooldown));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "ctrlQCraftingFix", GeneralCompatConfig.ctrlQCraftingFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "carpetAlwaysSetDefault", GeneralCompatConfig.carpetAlwaysSetDefault));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "placementRotationFix", GeneralCompatConfig.placementRotationFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "tntDoNotUpdate", GeneralCompatConfig.tntDoNotUpdate));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "totallyNoBlockUpdate", GeneralCompatConfig.totallyNoBlockUpdate));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tiscmNetworkProtocol", GeneralCompatConfig.tiscmNetworkProtocol));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetorgaddition", "hopperNoItemCost", GeneralCompatConfig.hopperNoItemCost));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "explosionNoBlockDamage", GeneralCompatConfig.explosionNoBlockDamage));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedTNTHighPriority", GeneralCompatConfig.optimizedTNTHighPriority));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "tntPrimerMomentumRemoved", GeneralCompatConfig.tntPrimerMomentumRemoved));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tntIgnoreRedstoneSignal", GeneralCompatConfig.tntIgnoreRedstoneSignal));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tntDupingFix", GeneralCompatConfig.tntDupingFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "interactionUpdates", GeneralCompatConfig.interactionUpdates));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "xpNoCooldown", GeneralCompatConfig.xpNoCooldown));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "powerfulExpMending", GeneralCompatConfig.powerfulExpMending));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "clientSettingsLostOnRespawnFix", GeneralCompatConfig.clientSettingsLostOnRespawnFix));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "sensibleEnderman", GeneralCompatConfig.sensibleEnderman));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "entityInstantDeathRemoval", GeneralCompatConfig.entityInstantDeathRemoval));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "farmlandTrampledDisabled", GeneralCompatConfig.farmlandTrampledDisabled));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "shulkerGolem", GeneralCompatConfig.shulkerGolem));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "preventEndSpikeRespawn", GeneralCompatConfig.preventEndSpikeRespawn));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "yeetOutOfOrderChatKick", GeneralCompatConfig.yeetOutOfOrderChatKick));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "betterCraftableBoneBlock", GeneralCompatConfig.betterCraftableBoneBlock));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "betterCraftableDispenser", GeneralCompatConfig.betterCraftableDispenser));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "viewDistance", GeneralCompatConfig.viewDistance));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tickCommandPermission", GeneralCompatConfig.normalizedTickCommandPermission()));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tickFreezeCommandToggleable", GeneralCompatConfig.tickFreezeCommandToggleable));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "syncServerMsptMetricsData", GeneralCompatConfig.syncServerMsptMetricsData));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetorgaddition", "simpleInGameCalculator", GeneralCompatConfig.simpleInGameCalculator));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "microTiming", GeneralCompatConfig.microTiming));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "fastRedstoneDust", GeneralCompatConfig.fastRedstoneDust));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "lagFreeSpawning", GeneralCompatConfig.lagFreeSpawning));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedFastEntityMovement", GeneralCompatConfig.optimizedFastEntityMovement));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "optimizedHardHitBoxEntityCollision", GeneralCompatConfig.optimizedHardHitBoxEntityCollision));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "tntFuseDuration", GeneralCompatConfig.normalizedTntFuseDuration()));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "defaultLoggers", CarpetLoggerProtocol.serializeConfiguredDefaults(sanitizeDefaultLoggers(GeneralCompatConfig.defaultLoggers))));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "commandBot", FakeplayerConfig.enable));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "commandPlayer", FakePlayerCompatConfig.commandPlayer));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerResident", FakePlayerCompatConfig.fakePlayerResident));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "openFakePlayerInventory", FakePlayerCompatConfig.openFakePlayerInventory));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "fakePlayerTicksLikeRealPlayer", FakePlayerCompatConfig.fakePlayerTicksLikeRealPlayer));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "fakePlayerDefaultSurvivalMode", FakePlayerCompatConfig.fakePlayerDefaultSurvivalMode));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "fakePlayerInteractLikeClient", FakePlayerCompatConfig.fakePlayerInteractLikeClient));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerAutoReplaceTool", FakePlayerCompatConfig.fakePlayerAutoReplaceTool));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerAutoReplenishment", FakePlayerCompatConfig.fakePlayerAutoReplenishment));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "fakePlayerAutoReplenishmentFormShulkerBox", FakePlayerCompatConfig.fakePlayerAutoReplenishmentFormShulkerBox));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerAutoFish", FakePlayerCompatConfig.fakePlayerAutoFish));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerReloadAction", FakePlayerCompatConfig.fakePlayerReloadAction));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "commandBot", FakeplayerConfig.enable));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "commandPlayer", FakePlayerCompatConfig.commandPlayer));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerResident", FakePlayerCompatConfig.fakePlayerResident));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "openFakePlayerInventory", FakePlayerCompatConfig.openFakePlayerInventory));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "fakePlayerTicksLikeRealPlayer", FakePlayerCompatConfig.fakePlayerTicksLikeRealPlayer));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "fakePlayerDefaultSurvivalMode", FakePlayerCompatConfig.fakePlayerDefaultSurvivalMode));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "fakePlayerInteractLikeClient", FakePlayerCompatConfig.fakePlayerInteractLikeClient));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerAutoReplaceTool", FakePlayerCompatConfig.fakePlayerAutoReplaceTool));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerAutoReplenishment", FakePlayerCompatConfig.fakePlayerAutoReplenishment));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpetamsaddition", "fakePlayerAutoReplenishmentFormShulkerBox", FakePlayerCompatConfig.fakePlayerAutoReplenishmentFormShulkerBox));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerAutoFish", FakePlayerCompatConfig.fakePlayerAutoFish));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("lophine", "fakePlayerReloadAction", FakePlayerCompatConfig.fakePlayerReloadAction));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "hopperCounters", WoolHopperCounterConfig.hopperCounters));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "hopperCountersUnlimitedSpeed", WoolHopperCounterConfig.hopperCountersUnlimitedSpeed));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpet", "hopperCounters", WoolHopperCounterConfig.hopperCounters));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("carpettisaddition", "hopperCountersUnlimitedSpeed", WoolHopperCounterConfig.hopperCountersUnlimitedSpeed));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("pca", "pcaSyncProtocol", PcaSyncProtocolConfig.enabled));
CarpetServerProtocol.CarpetRules.register(CarpetServerProtocol.CarpetRule.of("pca", "pcaSyncPlayerEntity", PcaSyncProtocolConfig.syncPlayerEntity));
} finally {
CarpetServerProtocol.CarpetRules.endBatch();
}
}
}
@@ -1,162 +0,0 @@
package fun.bm.lophine.carpet;
import fun.bm.lophine.carpet.config.modules.GeneralCompatConfig;
import fun.bm.lophine.carpet.config.modules.WoolHopperCounterConfig;
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
import me.earthme.luminol.config.ConfigManager;
import me.earthme.luminol.config.ConfigsInstance;
public class RedirectedConfigs {
public static void redirect() {
updateSuppressionCrashFix();
commandTick();
optimizedDragonRespawn();
woolHopperCounter();
fakeplayer();
creativeFlyNoClip();
redstoneChanges();
}
private static void updateSuppressionCrashFix() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
try {
boolean updateSuppressionCrashFixEnabled = config.getConfigOrigin("fixes.update-suppression-crash-fix.enabled");
if (updateSuppressionCrashFixEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.amsUpdateSuppressionCrashFix = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "amsUpdateSuppressionCrashFix"}, true);
GeneralCompatConfig.yeetUpdateSuppressionCrash = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "yeetUpdateSuppressionCrash"}, true);
}
config.removeConfig(new String[]{"fixes", "update-suppression-crash-fix", "enabled"});
} catch (Exception ignored) {
}
}
private static void commandTick() {
try {
boolean shouldEnabled = false;
// first check lophine
try {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
shouldEnabled = config.getConfigOrigin("experiment.command.tick_command_enabled");
config.removeConfig(new String[]{"experiment", "command", "tick_command_enabled"});
} catch (Exception ignored) {
}
// then check luminol
try {
ConfigsInstance config = ConfigManager.getConfigs("luminol");
shouldEnabled = shouldEnabled || (boolean) config.getConfigOrigin("experiment.command.enable_tick_command");
config.removeConfig(new String[]{"experiment", "command", "enable_tick_command"});
} catch (Exception ignored) {
}
if (shouldEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.commandTick = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "commandTick"}, true);
}
} catch (Exception ignored) {
}
}
private static void optimizedDragonRespawn() {
ConfigsInstance config = ConfigManager.getConfigs("luminol");
try {
boolean optimizedDragonRespawnEnabled = config.getConfigOrigin("optimizations.end_dragon.optimized_dragon_respawn");
if (optimizedDragonRespawnEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.optimizedDragonRespawn = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "optimizedDragonRespawn"}, true);
}
config.removeConfig(new String[]{"optimizations", "end_dragon", "optimized_dragon_respawn"});
} catch (Exception ignored) {
}
}
private static void woolHopperCounter() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
try {
boolean woolHopperCounterEnabled = config.getConfigOrigin("function.wool-hopper-counter.enabled");
if (woolHopperCounterEnabled) {
WoolHopperCounterConfig.hopperCounters = true;
carpetConfig.setConfig(new String[]{"carpet", "hopper_counter", "hopperCounters"}, true);
}
config.removeConfig(new String[]{"function", "wool-hopper-counter", "enabled"});
} catch (Exception ignored) {
}
try {
boolean woolHopperCounterUnlimitedSpeed = config.getConfigOrigin("function.wool-hopper-counter.unlimited-speed");
if (woolHopperCounterUnlimitedSpeed) {
WoolHopperCounterConfig.hopperCountersUnlimitedSpeed = true;
carpetConfig.setConfig(new String[]{"carpet", "hopper_counter", "hopperCountersUnlimitedSpeed"}, true);
}
config.removeConfig(new String[]{"function", "wool-hopper-counter", "unlimited-speed"});
} catch (Exception ignored) {
}
}
private static void fakeplayer() {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
try {
boolean bot = carpetConfig.getConfigOrigin("carpet.fakeplayer.commandBot");
if (bot) {
try {
ConfigsInstance lophineConfig = ConfigManager.getConfigs("lophine");
FakeplayerConfig.enable = true;
lophineConfig.setConfig(new String[]{"function", "fakeplayer", "enable"}, true);
} catch (Exception ignored) {
}
}
} catch (Exception ignored) {
}
carpetConfig.removeConfig(new String[]{"carpet", "fakeplayer", "commandBot"});
}
private static void creativeFlyNoClip() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
try {
boolean creativeFlyNoClipEnabled = config.getConfigOrigin("function.creative_fly_no_clip.enabled");
if (creativeFlyNoClipEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.creativeNoClip = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "creativeNoClip"}, true);
}
config.removeConfig(new String[]{"function", "creative_fly_no_clip", "enabled"});
} catch (Exception ignored) {
}
}
private static void redstoneChanges() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
try {
boolean dustTrapdoorReintroduced = config.getConfigOrigin("experiment.redstone.redstone-ignore-upwards-update");
if (dustTrapdoorReintroduced) {
GeneralCompatConfig.dustTrapdoorReintroduced = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "dustTrapdoorReintroduced"}, true);
}
config.removeConfig(new String[]{"experiment", "redstone", "redstone-ignore-upwards-update"});
} catch (Exception ignored) {
}
try {
boolean shulkerBoxCCEReintroduced = config.getConfigOrigin("experiment.redstone.cce-update-suppression");
if (shulkerBoxCCEReintroduced) {
GeneralCompatConfig.shulkerBoxCCEReintroduced = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "shulkerBoxCCEReintroduced"}, true);
}
config.removeConfig(new String[]{"experiment", "redstone", "cce-update-suppression"});
} catch (Exception ignored) {
}
try {
boolean instantBlockUpdaterReintroduced = config.getConfigOrigin("experiment.redstone.instant-block-updater");
if (instantBlockUpdaterReintroduced) {
GeneralCompatConfig.instantBlockUpdaterReintroduced = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "instantBlockUpdaterReintroduced"}, true);
}
config.removeConfig(new String[]{"experiment", "redstone", "instant-block-updater"});
} catch (Exception ignored) {
}
}
}
@@ -70,7 +70,7 @@ public class FakePlayerCompatConfig implements IConfigModule {
@Override
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> exs) {
if (commandPlayer) {
if (commandPlayer && command == null) {
command = new BotCommand("player");
command.register();
}
@@ -1,11 +1,9 @@
package fun.bm.lophine.carpet.config.modules;
import fun.bm.lophine.carpet.CarpetCompatSync;
import fun.bm.lophine.carpet.RedirectedConfigs;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
import java.util.List;
@@ -19,7 +17,6 @@ import java.util.List;
Only rules that already have a working server-side implementation are exposed here."""
)
public class GeneralCompatConfig implements IConfigModule {
@TransformedConfig(name = "language", directory = {"carpet", "general"}, transformComments = false)
@ConfigInfo(name = "language", comments = """
Carpet language value.
ATTENTION: This config will not update in Lophine global now!""")
@@ -269,10 +266,7 @@ public class GeneralCompatConfig implements IConfigModule {
@Override
public void beforeFinalLoad() {
// Should remove in next Minecraft version update
RedirectedConfigs.redirect();
// after all config updated, send changes to client
// send changes to client
CarpetCompatSync.apply();
}
}
@@ -3,12 +3,10 @@ package fun.bm.lophine.carpet.config.modules;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(category = EnumConfigCategory.REMOVED, name = "removed_config")
public class RemovedConfig implements IConfigModule {
@TransformedConfig(name = "enabled", directory = {"carpet", "core"})
@ConfigInfo(name = "removed", comments =
"""
RemovedConfig redirect to here, no any function.""")
@@ -1,27 +1,67 @@
package fun.bm.lophine.config.modules.experiment;
import fun.bm.lophine.enums.GlobalEntitiesCounterType;
import me.earthme.luminol.config.ConfigManager;
import me.earthme.luminol.config.ConfigsInstance;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.DoNotLoad;
import me.earthme.luminol.config.flags.HotReloadUnsupported;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(name = "global_entities_counter", category = EnumConfigCategory.EXPERIMENT)
public class GlobalEntitiesCounter implements IConfigModule {
@HotReloadUnsupported
@ConfigInfo(name = "enabled", comments = """
Enable global entities counter.
@ConfigInfo(name = "version", comments = """
DISABLED
DEFAULT_SYNC: Enable global entities counter origin version with sync counter module.
DEFAULT_ASYNC: Enable global entities counter origin version with async counter module.
PRECISE: Enable precise mob cap calculation with incremental counting. Replaces the periodic full-scan with event-driven real-time updates.
You need to set per-player-mob-spawns to false on paper-world-defaults.yml or paper-world.yml""")
public static boolean enabled = false;
public static GlobalEntitiesCounterType type = GlobalEntitiesCounterType.DISABLED;
@HotReloadUnsupported
@ConfigInfo(name = "async", comments = "Enable Asynchronous(maybe cause bugs)")
public static boolean async = false;
@DoNotLoad
private static boolean enabled;
@DoNotLoad
private static boolean async;
@DoNotLoad
private static boolean defaultModule;
@HotReloadUnsupported
@ConfigInfo(name = "always_count", comments = """
Always count entities.
If you want to count entities loaded by chunk loader,
you must to enabled it.""")
public static boolean alwaysCount = false;
public static boolean isEnabled() {
return enabled;
}
public static boolean isAsync() {
return async;
}
public static boolean isDefaultModule() {
return defaultModule;
}
@Override
public void beforeFinalLoad() {
ConfigsInstance configsInstance = ConfigManager.getConfigs("lophine");
try {
Boolean enabled0 = configsInstance.getConfigOrigin("experiment.global_entities_counter.enabled");
Boolean async0 = configsInstance.getConfigOrigin("experiment.global_entities_counter.async");
if (enabled0 != null) {
if (enabled0) {
if (async0 != null && async0) {
type = GlobalEntitiesCounterType.DEFAULT_ASYNC;
} else {
type = GlobalEntitiesCounterType.DEFAULT_SYNC;
}
}
}
configsInstance.removeConfig("experiment.global_entities_counter.enabled");
configsInstance.removeConfig("experiment.global_entities_counter.async");
} catch (Exception ignored) {
}
enabled = type != GlobalEntitiesCounterType.DISABLED;
async = type == GlobalEntitiesCounterType.DEFAULT_ASYNC;
defaultModule = type == GlobalEntitiesCounterType.DEFAULT_SYNC || type == GlobalEntitiesCounterType.DEFAULT_ASYNC;
}
}
@@ -11,7 +11,6 @@ import me.earthme.luminol.enums.EnumConfigCategory;
*/
@ConfigClassInfo(category = EnumConfigCategory.EXPERIMENT, name = "redstone")
public class RedStoneConfig implements IConfigModule {
@ConfigInfo(name = "old-block-remove-behaviour")
public static boolean oldBlockRemoveBehaviour = false;
}
@@ -0,0 +1,13 @@
package fun.bm.lophine.config.modules.fixes;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(category = EnumConfigCategory.FIXES, name = "vanilla-like-experience")
public class VanillaLikeExperienceConfig implements IConfigModule {
@ConfigInfo(name = "enabled", comments = """
Restore a more vanilla-like technical gameplay experience by bypassing some Paper safety and behavior changes.""")
public static boolean enabled = false;
}
@@ -95,7 +95,7 @@ public class FakeplayerConfig implements IConfigModule {
@Override
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> exs) {
if (enable) {
if (enable && command == null) {
command = new BotCommand("bot");
command.register();
}
@@ -12,7 +12,7 @@ public class LanguageConfig implements IConfigModule {
@ConfigInfo(name = "lang", comments = """
Please use the key from https://minecraft.wiki/w/Language
Sample of format: en_us zh_cn zh_hk zh_tw
ATTENTION: If you want to edit language for carpet ststem,
ATTENTION: If you want to edit language for carpet system,
please edit it in carpet config file.""")
public static String lang = "en_us";
@@ -13,6 +13,9 @@ public class OldFeatureConfig implements IConfigModule {
@ConfigInfo(name = "old_zombie_reinforcement")
public static boolean oldZombieReinforcement = false;
@ConfigInfo(name = "old_leader_zombie_health")
public static boolean oldLeaderZombieHealth = false;
@ConfigInfo(name = "old_explosion_damage_calculator")
public static boolean oldExplosionDamageCalculator = false;
@@ -0,0 +1,43 @@
package fun.bm.lophine.config.modules.function.protocol;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import fun.bm.lophine.carpet.CarpetCompatSync;
import fun.bm.lophine.enums.PcaPlayerEntityType;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.protocol.PcaSyncProtocol;
import java.util.Set;
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "pca", directory = {"protocol"})
public class PcaSyncProtocolConfig implements IConfigModule {
private static boolean lastEnabled = false;
@TransformedConfig(name = "pca-sync-protocol", directory = {"protocol"})
@ConfigInfo(name = "enabled", comments = """
Enable PCA sync protocol support""")
public static boolean enabled = false;
@TransformedConfig(name = "pca-sync-player-entity", directory = {"protocol"})
@ConfigInfo(name = "sync-player-entity", comments = """
Controls which player entities can be watched through the PCA sync protocol.
NOBODY: never sync player entities
BOT: only sync Lophine fake players
OPS: sync fake players and allow operators to sync real players
OPS_AND_SELF: sync fake players, operators, and a player's own entity
EVERYONE: allow all player entities""")
public static PcaPlayerEntityType syncPlayerEntity = PcaPlayerEntityType.OPS;
@Override
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> e) {
if (lastEnabled != enabled) {
PcaSyncProtocol.onConfigModify(enabled);
lastEnabled = enabled;
}
CarpetCompatSync.apply();
}
}
@@ -3,12 +3,10 @@ package fun.bm.lophine.config.modules.removed;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(category = EnumConfigCategory.REMOVED, name = "removed_config")
public class RemovedConfig implements IConfigModule {
@TransformedConfig(name = "enabled", directory = {"misc", "auto_update"})
@ConfigInfo(name = "removed", comments =
"""
RemovedConfig redirect to here, no any function.""")
@@ -0,0 +1,8 @@
package fun.bm.lophine.enums;
public enum GlobalEntitiesCounterType {
DISABLED,
DEFAULT_SYNC,
DEFAULT_ASYNC,
PRECISE
}
@@ -0,0 +1,9 @@
package fun.bm.lophine.enums;
public enum PcaPlayerEntityType {
NOBODY,
BOT,
OPS,
OPS_AND_SELF,
EVERYONE
}
@@ -137,7 +137,7 @@ public class CarpetLoggerProtocol implements LeavesProtocol {
private static net.minecraft.network.chat.Component buildTpsLine(MinecraftServer server) {
ServerTickRateManager tickManager = server.tickRateManager();
ca.spottedleaf.moonrise.common.time.TickData.TickReportData tickData = TickRegionScheduler.getCurrentRegion().getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
ca.spottedleaf.common.time.TickData.TickReportData tickData = TickRegionScheduler.getCurrentRegion().getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
final double tps = tickData.tpsData().segmentAll().average();
final double mspt = tickData.timePerTickData().segmentAll().average() / 1.0E6;
@@ -6,6 +6,7 @@ import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.mojang.logging.LogUtils;
import fun.bm.lophine.config.modules.experiment.GlobalEntitiesCounter;
import fun.bm.lophine.config.modules.fixes.VanillaLikeExperienceConfig;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
@@ -24,10 +25,10 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import static net.minecraft.world.level.NaturalSpawner.getRoughBiome;
import java.util.concurrent.atomic.AtomicInteger;
public class EntitiesCounterUtil {
// global entities counter
private static final Map<ServerLevel, Cache<Integer, ReferenceList<Entity>>> globalLoadedEntities = new ConcurrentHashMap<>();
private static final Map<ServerLevel, Object2IntOpenHashMap<MobCategory>> mobsMap = Collections.synchronizedMap(new WeakHashMap<>());
private static final Map<ServerLevel, Cache<Integer, PositionCountingAreaMap<ServerPlayer>>> mobsAreaMap = new ConcurrentHashMap<>();
@@ -35,6 +36,9 @@ public class EntitiesCounterUtil {
private static final Map<ServerLevel, CompletableFuture<Void>> tasks = new ConcurrentHashMap<>();
private static final Set<Integer> UniqueIds = ConcurrentHashMap.newKeySet();
// precise mob counter extra
private static final Map<ServerLevel, EnumMap<MobCategory, AtomicInteger>> globalMobCounts = new ConcurrentHashMap<>();
private static int lastUsedId = 0;
private static final int CLEANUP_INTERVAL = 200; // each 200 ids used
@@ -104,94 +108,193 @@ public class EntitiesCounterUtil {
}
public static void tick(ServerLevel level) {
Runnable task = () -> {
try {
Cache<Integer, ReferenceList<Entity>> data0 = globalLoadedEntities.get(level);
if (data0 == null) return;
if (GlobalEntitiesCounter.isDefaultModule()) {
Runnable task = () -> {
try {
Cache<Integer, ReferenceList<Entity>> data0 = globalLoadedEntities.get(level);
if (data0 == null) return;
Object2IntOpenHashMap<MobCategory> map = new Object2IntOpenHashMap<>();
Collection<ReferenceList<Entity>> snapshot = data0.asMap().values();
Object2IntOpenHashMap<MobCategory> map = new Object2IntOpenHashMap<>();
Collection<ReferenceList<Entity>> snapshot = data0.asMap().values();
for (ReferenceList<Entity> data : snapshot) {
if (data == null) continue;
for (Entity entity : GlobalEntitiesCounter.async ? data.copy() : data) {
if (entity == null || entity.isRemoved() || !entity.isAlive()) continue;
// Lophine start - Copy from net/minecraft/world/level/NaturalSpawner
MobCategory category = entity.getType().getCategory();
if (category != MobCategory.MISC) {
// Paper start - Only count natural spawns
if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
!(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL ||
entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
continue;
for (ReferenceList<Entity> data : snapshot) {
if (data == null) continue;
for (Entity entity : GlobalEntitiesCounter.isAsync() ? data.copy() : data) {
if (entity == null || entity.isRemoved() || !entity.isAlive()) continue;
// Lophine start - Copy from net/minecraft/world/level/NaturalSpawner
MobCategory category = entity.getType().getCategory();
if (category != MobCategory.MISC) {
// Paper start - Only count natural spawns
if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
!(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL ||
entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
continue;
}
// Paper end - Only count natural spawns
map.addTo(category, 1);
}
// Paper end - Only count natural spawns
map.addTo(category, 1);
}
// Lophine end - Copy from net/minecraft/world/level/NaturalSpawner
}
// Lophine end - Copy from net/minecraft/world/level/NaturalSpawner
}
mobsMap.put(level, map);
mobsMap.put(level, map);
Cache<Integer, PositionCountingAreaMap<ServerPlayer>> collection = mobsAreaMap.get(level);
if (collection != null) {
int count = 0;
for (PositionCountingAreaMap<ServerPlayer> areaMap : collection.asMap().values()) {
if (areaMap != null) {
count += areaMap.getTotalPositions();
Cache<Integer, PositionCountingAreaMap<ServerPlayer>> collection = mobsAreaMap.get(level);
if (collection != null) {
int count = 0;
for (PositionCountingAreaMap<ServerPlayer> areaMap : collection.asMap().values()) {
if (areaMap != null) {
count += areaMap.getTotalPositions();
}
}
spawnableChunkCount.put(level, count);
}
spawnableChunkCount.put(level, count);
} catch (Exception e) {
LogUtils.getClassLogger().error("Failed to run task", e);
}
} catch (Exception e) {
LogUtils.getClassLogger().error("Failed to run task", e);
};
if (GlobalEntitiesCounter.isAsync()) {
tasks.put(level, CompletableFuture.runAsync(task).exceptionally(ex -> {
LogUtils.getClassLogger().error("Failed to run task", ex);
return null;
}));
} else {
task.run();
}
};
if (GlobalEntitiesCounter.async) {
tasks.put(level, CompletableFuture.runAsync(task).exceptionally(ex -> {
LogUtils.getClassLogger().error("Failed to run task", ex);
return null;
}));
} else {
task.run();
Cache<Integer, PositionCountingAreaMap<ServerPlayer>> cache = mobsAreaMap.get(level);
if (cache == null) return;
int total = 0;
for (PositionCountingAreaMap<ServerPlayer> map : cache.asMap().values()) {
if (map != null) {
total += map.getTotalPositions();
}
}
spawnableChunkCount.put(level, total);
}
}
public static NaturalSpawner.SpawnState runRemainingTasks(
public static NaturalSpawner.SpawnState createSpawnState(
ServerLevel level, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkGetter, LocalMobCapCalculator calculator, final boolean countMobs
) {
Object2IntOpenHashMap<MobCategory> map = getMobsMap(level);
if (map == null) return null; // skip if no data
// Lophine start - Copy from net/minecraft/world/level/NaturalSpawner
PotentialCalculator potentialCalculator = new PotentialCalculator();
for (Entity entity : entities) {
if (entity == null || entity.isRemoved() || !entity.isAlive()) continue;
// Paper start - Only count natural spawns
if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
!(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL ||
entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
continue;
if (GlobalEntitiesCounter.isDefaultModule()) {
Object2IntOpenHashMap<MobCategory> map = getMobsMap(level);
if (map == null) return null; // skip if no data
// Lophine start - Copy from net/minecraft/world/level/NaturalSpawner
PotentialCalculator potentialCalculator = new PotentialCalculator();
for (Entity entity : entities) {
if (entity == null || entity.isRemoved() || !entity.isAlive()) continue;
// Paper start - Only count natural spawns
if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning &&
!(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL ||
entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
continue;
}
// Paper end - Only count natural spawns
BlockPos blockPos = entity.blockPosition();
chunkGetter.query(ChunkPos.pack(blockPos), chunk -> {
MobSpawnSettings.MobSpawnCost mobSpawnCost = NaturalSpawner.getRoughBiome(blockPos, chunk).getMobSettings().getMobSpawnCost(entity.getType());
if (mobSpawnCost != null) {
potentialCalculator.addCharge(entity.blockPosition(), mobSpawnCost.charge());
}
if (calculator != null && entity instanceof Mob) { // Paper - Optional per player mob spawns
calculator.addMob(chunk.getPos(), entity.getType().getCategory());
}
// Paper start - Optional per player mob spawns
if (countMobs) {
((ServerLevel) chunk.getLevel()).getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
}
// Paper end - Optional per player mob spawns
});
}
// Paper end - Only count natural spawns
BlockPos blockPos = entity.blockPosition();
chunkGetter.query(ChunkPos.pack(blockPos), chunk -> {
MobSpawnSettings.MobSpawnCost mobSpawnCost = getRoughBiome(blockPos, chunk).getMobSettings().getMobSpawnCost(entity.getType());
if (mobSpawnCost != null) {
potentialCalculator.addCharge(entity.blockPosition(), mobSpawnCost.charge());
}
return new NaturalSpawner.SpawnState(getTotalChunkCount(level), map, potentialCalculator, calculator);
// Lophine end - Copy from net/minecraft/world/level/NaturalSpawner
} else {
int chunkCount = getSpawnableChunkCount(level);
if (chunkCount == 0) return null;
if (calculator != null && entity instanceof Mob) { // Paper - Optional per player mob spawns
calculator.addMob(chunk.getPos(), entity.getType().getCategory());
}
Object2IntOpenHashMap<MobCategory> globalCounts = getGlobalCounts(level);
// Paper start - Optional per player mob spawns
if (countMobs) {
chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
}
// Paper end - Optional per player mob spawns
});
PotentialCalculator potentialCalculator = new PotentialCalculator();
for (Entity entity : entities) {
if (entity == null || entity.isRemoved() || !entity.isAlive()) continue;
if (!shouldCount(entity)) continue;
BlockPos pos = entity.blockPosition();
chunkGetter.query(ChunkPos.pack(pos), chunk -> {
MobSpawnSettings.MobSpawnCost mobSpawnCost = NaturalSpawner.getRoughBiome(pos, chunk).getMobSettings().getMobSpawnCost(entity.getType());
if (mobSpawnCost != null) {
potentialCalculator.addCharge(entity.blockPosition(), mobSpawnCost.charge());
}
if (calculator != null && entity instanceof Mob) {
calculator.addMob(chunk.getPos(), entity.getType().getCategory());
}
});
}
return new NaturalSpawner.SpawnState(chunkCount, globalCounts, potentialCalculator, calculator);
}
}
public static Object2IntOpenHashMap<MobCategory> getGlobalCounts(ServerLevel level) {
EnumMap<MobCategory, AtomicInteger> counts = globalMobCounts.get(level);
Object2IntOpenHashMap<MobCategory> result = new Object2IntOpenHashMap<>();
if (counts != null) {
for (Map.Entry<MobCategory, AtomicInteger> entry : counts.entrySet()) {
result.put(entry.getKey(), entry.getValue().get());
}
}
return result;
}
public static int getSpawnableChunkCount(ServerLevel level) {
Integer value = spawnableChunkCount.get(level);
return value != null ? value : 0;
}
public static void onWorldUnload(ServerLevel level) {
globalMobCounts.remove(level);
mobsAreaMap.remove(level);
spawnableChunkCount.remove(level);
}
public static void onEntityTrackingStart(ServerLevel level, Entity entity) {
if (!shouldCount(entity)) return;
MobCategory category = entity.getType().getCategory();
getOrCreateCounts(level).computeIfAbsent(category, k -> new AtomicInteger(0)).incrementAndGet();
}
public static boolean shouldCount(Entity entity) {
MobCategory category = entity.getType().getCategory();
if (category == MobCategory.MISC) return false;
if (entity instanceof Mob mob && (mob.isPersistenceRequired() || mob.requiresCustomPersistence())) {
return false;
}
if (VanillaLikeExperienceConfig.enabled || entity.level().paperConfig().entities.spawning.countAllMobsForSpawning) {
return true;
}
return entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL
|| entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN;
}
private static EnumMap<MobCategory, AtomicInteger> getOrCreateCounts(ServerLevel level) {
return globalMobCounts.computeIfAbsent(level, _ -> new EnumMap<>(MobCategory.class));
}
public static void onEntityTrackingEnd(ServerLevel level, Entity entity) {
if (!shouldCount(entity)) return;
MobCategory category = entity.getType().getCategory();
EnumMap<MobCategory, AtomicInteger> counts = getOrCreateCounts(level);
AtomicInteger counter = counts.get(category);
if (counter != null) {
counter.updateAndGet(v -> Math.max(0, v - 1));
}
return new NaturalSpawner.SpawnState(getTotalChunkCount(level), map, potentialCalculator, calculator);
// Lophine end - Copy from net/minecraft/world/level/NaturalSpawner
}
}
@@ -204,7 +204,7 @@ public class BotList {
this.server.server.getPluginManager().callEvent(event);
location = event.getSpawnLocation();
bot.spawnIn(world);
bot.setServerLevel(world);
bot.gameMode.setLevel(bot.level());
bot.setPosRaw(location.getX(), location.getY(), location.getZ());
@@ -329,11 +329,11 @@ public class ServerBot extends ServerPlayer {
}
@Override
public void knockback(double strength, double x, double z, @Nullable Entity attacker, EntityKnockbackEvent.@NotNull Cause eventCause) {
public void knockback(double power, double xd, double zd, final DamageSource source, final float damage, final boolean comesFromEffect, @Nullable Entity attacker, EntityKnockbackEvent.Cause eventCause) {
if (!this.hurtMarked) {
return;
}
super.knockback(strength, x, z, attacker, eventCause);
super.knockback(power, xd, zd, source, damage, comesFromEffect, attacker, eventCause);
}
@Override
@@ -21,9 +21,9 @@ import com.mojang.brigadier.arguments.BoolArgumentType;
import fun.bm.lophine.LophineLogger;
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
import me.earthme.luminol.config.modules.experiment.CommandConfig;
import me.earthme.luminol.utils.FoliaServerWaypointManager;
import me.earthme.luminol.utils.NullPlugin;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.waypoints.ServerWaypointManager;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.command.CommandContext;
@@ -53,7 +53,7 @@ public class LocatorBarConfig extends AbstractBotConfig<Boolean, LocatorBarConfi
}
if (this.bot != null) {
this.value = value;
FoliaServerWaypointManager manager = this.bot.level().getWaypointManager(); // Lophine - waypoint for adapt of luminol ver
ServerWaypointManager manager = this.bot.level().getWaypointManager(); // Lophine - waypoint for adapt of luminol ver
if (value) {
manager.trackWaypoint(this.bot);
} else {
@@ -27,10 +27,11 @@ import org.leavesmc.leaves.command.bot.subcommands.*;
import static org.leavesmc.leaves.command.CommandUtils.registerPermissions;
public class BotCommand extends RootNode {
private static final String PERM_BASE = "bukkit.command.bot";
private static final String PERM_BASE_BOT = "bukkit.command.bot";
private static final String PERM_BASE_PLAYER = "bukkit.command.player";
public BotCommand(String key) {
super(key, PERM_BASE);
super(key, getPermBase(key));
this.children(
ListCommand::new,
ConfigCommand::new,
@@ -44,15 +45,26 @@ public class BotCommand extends RootNode {
@Override
protected ArgumentBuilder<CommandSourceStack, ?> compile() {
registerPermissions(PERM_BASE, this.children);
registerPermissions(getPermBase(this.getName()), this.children);
return super.compile();
}
public static boolean hasPermission(@NotNull CommandSender sender) {
return sender.hasPermission(PERM_BASE);
return sender.hasPermission(PERM_BASE_BOT) || sender.hasPermission(PERM_BASE_PLAYER);
}
public static boolean hasPermission(@NotNull CommandSender sender, String subcommand) {
return sender.hasPermission(PERM_BASE) || sender.hasPermission(PERM_BASE + "." + subcommand);
return sender.hasPermission(PERM_BASE_BOT) || sender.hasPermission(PERM_BASE_BOT + "." + subcommand)
|| sender.hasPermission(PERM_BASE_PLAYER) || sender.hasPermission(PERM_BASE_PLAYER + "." + subcommand);
}
public static String getPermBase(String key) {
if (key.equals("bot")) {
return PERM_BASE_BOT;
}
if (key.equals("player")) {
return PERM_BASE_PLAYER;
}
throw new IllegalArgumentException("Invalid key: " + key);
}
}
@@ -56,11 +56,13 @@ public class StartCommand extends LiteralNode {
ServerBot bot = getBot(context);
CommandSender sender = context.getSender();
action.loadCommand(context);
if (bot.addBotAction(action, sender)) {
// Create a new instance of the action to avoid sharing state between multiple actions
AbstractBotAction<?> newAction = action.create();
newAction.loadCommand(context);
if (bot.addBotAction(newAction, sender)) {
sender.sendMessage(join(spaces(),
text("Action", GRAY),
text(action.getName(), AQUA).hoverEvent(showText(text(action.getActionDataString()))),
text(newAction.getName(), AQUA).hoverEvent(showText(text(newAction.getActionDataString()))),
text("has been issued to", GRAY),
asAdventure(bot.getDisplayName())
));
@@ -141,13 +141,13 @@ public class StopCommand extends LiteralNode {
if (canceled.isEmpty()) {
sender.sendMessage(join(spaces(),
asAdventure(bot.getDisplayName()).append(text("'s", GRAY)),
text("'s action list cleared", GRAY)
text("action list cleared", GRAY)
));
} else {
sender.sendMessage(join(spaces(),
text("Tried to clear", GRAY),
asAdventure(bot.getDisplayName()).append(text("'s", GRAY)),
text("'s action list, but following actions' stop was canceled by plugin:", GRAY)
text("action list, but following actions' stop was canceled by plugin:", GRAY)
));
for (AbstractBotAction<?> action : canceled) {
context.getSender().sendMessage(
@@ -86,8 +86,8 @@ public class BBORProtocol implements LeavesProtocol {
ServerLevel overworld = MinecraftServer.getServer().overworld();
ProtocolUtils.sendBytebufPacket(player, INITIALIZE_CLIENT, buf -> {
buf.writeLong(overworld.getSeed());
buf.writeInt(overworld.levelData.getRespawnData().pos().getX());
buf.writeInt(overworld.levelData.getRespawnData().pos().getZ());
buf.writeInt(overworld.getLevelData().getRespawnData().pos().getX());
buf.writeInt(overworld.getLevelData().getRespawnData().pos().getZ());
});
sendStructureList(player);
}
@@ -6,18 +6,22 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.Identifier;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
import org.slf4j.Logger;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@LeavesProtocol.Register(namespace = "carpet")
public class CarpetServerProtocol implements LeavesProtocol {
@@ -28,6 +32,9 @@ public class CarpetServerProtocol implements LeavesProtocol {
private static final String HI = "69";
private static final String HELLO = "420";
private static final Set<UUID> activePlayers = ConcurrentHashMap.newKeySet();
private static boolean batchingRules = false;
private static boolean rulesDirty = false;
@Contract("_ -> new")
public static Identifier id(String path) {
@@ -44,21 +51,68 @@ public class CarpetServerProtocol implements LeavesProtocol {
@ProtocolHandler.PayloadReceiver(payload = CarpetPayload.class)
private static void handleHello(@NotNull ServerPlayer player, @NotNull CarpetServerProtocol.CarpetPayload payload) {
if (payload.nbt.contains(HELLO)) {
LOGGER.info("Player {} joined with carpet {}", player.getScoreboardName(), payload.nbt.getString(HELLO).orElse("Unknown"));
CompoundTag data = new CompoundTag();
CarpetRules.write(data);
ProtocolUtils.sendPayloadPacket(player, new CarpetPayload(data));
UUID playerId = player.getUUID();
String carpetVersion = payload.nbt.getString(HELLO).orElse("Unknown");
player.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> {
ServerPlayer onlinePlayer = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (onlinePlayer == null) {
return;
}
LOGGER.info("Player {} joined with carpet {}", onlinePlayer.getScoreboardName(), carpetVersion);
sendServerData(onlinePlayer);
activePlayers.add(playerId);
}, null, 1L);
}
}
@ProtocolHandler.PlayerLeave
public static void onPlayerLeave(ServerPlayer player) {
activePlayers.remove(player.getUUID());
}
@Override
public boolean isActive() {
return CarpetRules.hasRules();
}
private static void sendServerData(ServerPlayer player) {
sendServerData(player.getUUID());
}
private static void sendServerData(UUID playerId) {
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (player == null) {
activePlayers.remove(playerId);
return;
}
CompoundTag data = new CompoundTag();
CarpetRules.write(data);
player.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> {
ServerPlayer onlinePlayer = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (onlinePlayer != null) {
ProtocolUtils.sendPayloadPacket(onlinePlayer, new CarpetPayload(data));
}
}, null, 1L);
}
public static class CarpetRules {
private static final Map<String, CarpetRule> rules = new HashMap<>();
private static final Map<String, CarpetRule> rules = new ConcurrentHashMap<>();
public static void beginBatch() {
batchingRules = true;
rulesDirty = false;
}
public static void endBatch() {
batchingRules = false;
if (rulesDirty) {
activePlayers.forEach(CarpetServerProtocol::sendServerData);
rulesDirty = false;
}
}
public static void write(@NotNull CompoundTag tag) {
CompoundTag rulesNbt = new CompoundTag();
@@ -69,15 +123,25 @@ public class CarpetServerProtocol implements LeavesProtocol {
public static void register(CarpetRule rule) {
rules.put(rule.name, rule);
markDirty();
}
public static void clear() {
rules.clear();
markDirty();
}
public static boolean hasRules() {
return !rules.isEmpty();
}
private static void markDirty() {
if (batchingRules) {
rulesDirty = true;
} else {
activePlayers.forEach(CarpetServerProtocol::sendServerData);
}
}
}
public record CarpetRule(String identifier, String name, String value) {
@@ -0,0 +1,483 @@
/*
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
*
* Leaves is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Leaves is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
*/
package org.leavesmc.leaves.protocol;
import ca.spottedleaf.moonrise.common.util.TickThread;
import fun.bm.lophine.config.modules.function.protocol.PcaSyncProtocolConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.Identifier;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.ChestType;
import net.minecraft.world.level.chunk.LevelChunk;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
import org.leavesmc.leaves.util.TagUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@LeavesProtocol.Register(namespace = "pca")
public class PcaSyncProtocol implements LeavesProtocol {
public static final String PROTOCOL_ID = "pca";
private static final Identifier ENABLE_PCA_SYNC_PROTOCOL = id("enable_pca_sync_protocol");
private static final Identifier DISABLE_PCA_SYNC_PROTOCOL = id("disable_pca_sync_protocol");
private static final ConcurrentMap<UUID, Pair<Identifier, BlockPos>> playerWatchBlockPos = new ConcurrentHashMap<>();
private static final ConcurrentMap<UUID, Pair<Identifier, UUID>> playerWatchEntity = new ConcurrentHashMap<>();
private static final ConcurrentMap<Pair<Identifier, BlockPos>, Set<UUID>> blockPosWatchPlayerSet = new ConcurrentHashMap<>();
private static final ConcurrentMap<Pair<Identifier, UUID>, Set<UUID>> entityWatchPlayerSet = new ConcurrentHashMap<>();
@Contract("_ -> new")
public static Identifier id(String path) {
return Identifier.fromNamespaceAndPath(PROTOCOL_ID, path);
}
@ProtocolHandler.PlayerJoin
private static void onJoin(ServerPlayer player) {
if (PcaSyncProtocolConfig.enabled) {
enablePcaSyncProtocol(player);
}
}
@ProtocolHandler.PlayerLeave
private static void onLeave(ServerPlayer player) {
clearPlayerWatchData(player);
}
@ProtocolHandler.BytebufReceiver(key = "cancel_sync_block_entity")
private static void cancelSyncBlockEntityHandler(ServerPlayer player, FriendlyByteBuf buf) {
clearPlayerWatchBlock(player);
}
@ProtocolHandler.BytebufReceiver(key = "cancel_sync_entity")
private static void cancelSyncEntityHandler(ServerPlayer player, FriendlyByteBuf buf) {
clearPlayerWatchEntity(player);
}
@ProtocolHandler.PayloadReceiver(payload = SyncBlockEntityPayload.class)
private static void syncBlockEntityHandler(ServerPlayer player, SyncBlockEntityPayload payload) {
if (!PcaSyncProtocolConfig.enabled) {
return;
}
UUID playerId = player.getUUID();
player.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> {
ServerPlayer onlinePlayer = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (!PcaSyncProtocolConfig.enabled || onlinePlayer == null || onlinePlayer.hasDisconnected() || !TickThread.isTickThreadFor(onlinePlayer)) {
return;
}
ServerLevel world = onlinePlayer.level();
BlockPos pos = payload.pos;
Bukkit.getRegionScheduler().execute(MinecraftInternalPlugin.INSTANCE, world.getWorld(), pos.getX() >> 4, pos.getZ() >> 4, () -> {
if (!PcaSyncProtocolConfig.enabled || MinecraftServer.getServer().getPlayerList().getPlayer(playerId) == null || !TickThread.isTickThreadFor(world, pos)) {
return;
}
BlockState blockState = world.getBlockState(pos);
clearPlayerWatchData(playerId);
BlockEntity blockEntityAdj = null;
if (blockState.getBlock() instanceof ChestBlock && blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
BlockPos posAdj = pos.relative(ChestBlock.getConnectedDirection(blockState));
if (TickThread.isTickThreadFor(world, posAdj)) {
blockEntityAdj = getLoadedBlockEntity(world, posAdj);
} else {
scheduleBlockEntityUpdate(playerId, world, posAdj);
}
}
if (blockEntityAdj != null) {
updateBlockEntity(playerId, blockEntityAdj);
}
BlockEntity blockEntity = getLoadedBlockEntity(world, pos);
if (blockEntity != null) {
updateBlockEntity(playerId, blockEntity);
}
Pair<Identifier, BlockPos> pair = new ImmutablePair<>(world.dimension().identifier(), pos);
playerWatchBlockPos.put(playerId, pair);
blockPosWatchPlayerSet.computeIfAbsent(pair, ignored -> ConcurrentHashMap.newKeySet()).add(playerId);
});
}, null, 1L);
}
@ProtocolHandler.PayloadReceiver(payload = SyncEntityPayload.class)
private static void syncEntityHandler(ServerPlayer player, SyncEntityPayload payload) {
if (!PcaSyncProtocolConfig.enabled) {
return;
}
UUID playerId = player.getUUID();
player.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> {
ServerPlayer onlinePlayer = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (!PcaSyncProtocolConfig.enabled || onlinePlayer == null || onlinePlayer.hasDisconnected() || !TickThread.isTickThreadFor(onlinePlayer)) {
return;
}
ServerLevel world = onlinePlayer.level();
Entity entity = world.getEntity(payload.entityId);
if (entity == null) {
return;
}
boolean viewerIsOp = MinecraftServer.getServer().getPlayerList().isOp(onlinePlayer.nameAndId());
if (TickThread.isTickThreadFor(entity)) {
syncEntityForWatcher(playerId, viewerIsOp, entity);
} else {
entity.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> syncEntityForWatcher(playerId, viewerIsOp, entity), null, 1L);
}
}, null, 1L);
}
public static void onConfigModify(boolean enable) {
if (enable) {
enablePcaSyncProtocolGlobal();
} else {
disablePcaSyncProtocolGlobal();
}
}
public static void enablePcaSyncProtocol(@NotNull ServerPlayer player) {
sendEmptyPacket(player.getUUID(), ENABLE_PCA_SYNC_PROTOCOL);
}
public static void disablePcaSyncProtocol(@NotNull ServerPlayer player) {
sendEmptyPacket(player.getUUID(), DISABLE_PCA_SYNC_PROTOCOL);
}
public static void updateEntity(@NotNull ServerPlayer player, @NotNull Entity entity) {
updateEntity(player.getUUID(), entity);
}
private static void updateEntity(@NotNull UUID playerId, @NotNull Entity entity) {
if (!TickThread.isTickThreadFor(entity) || entity.isRemoved()) {
return;
}
CompoundTag nbt = TagUtil.saveEntity(entity);
sendPayloadPacket(playerId, new UpdateEntityPayload(entity.level().dimension().identifier(), entity.getId(), nbt));
}
public static void updateBlockEntity(@NotNull ServerPlayer player, @NotNull BlockEntity blockEntity) {
updateBlockEntity(player.getUUID(), blockEntity);
}
private static void updateBlockEntity(@NotNull UUID playerId, @NotNull BlockEntity blockEntity) {
Level world = blockEntity.getLevel();
if (world == null || world.isClientSide() || !TickThread.isTickThreadFor(world, blockEntity.getBlockPos())) {
return;
}
sendPayloadPacket(playerId, new UpdateBlockEntityPayload(world.dimension().identifier(), blockEntity.getBlockPos(), blockEntity.saveWithoutMetadata(world.registryAccess())));
}
public static boolean syncEntityToClient(@NotNull Entity entity) {
if (!PcaSyncProtocolConfig.enabled || entity.level().isClientSide() || !TickThread.isTickThreadFor(entity) || entity.isRemoved()) {
return false;
}
Pair<Identifier, UUID> pair = new ImmutablePair<>(entity.level().dimension().identifier(), entity.getUUID());
Set<UUID> playerIds = entityWatchPlayerSet.get(pair);
if (playerIds == null || playerIds.isEmpty()) {
return false;
}
ArrayList<UUID> stalePlayers = new ArrayList<>();
boolean ret = false;
for (UUID playerId : playerIds) {
if (MinecraftServer.getServer().getPlayerList().getPlayer(playerId) == null) {
stalePlayers.add(playerId);
continue;
}
updateEntity(playerId, entity);
ret = true;
}
stalePlayers.forEach(playerIds::remove);
if (playerIds.isEmpty()) {
entityWatchPlayerSet.remove(pair, playerIds);
}
return ret;
}
public static boolean syncBlockEntityToClient(@NotNull BlockEntity blockEntity) {
Level world = blockEntity.getLevel();
if (!PcaSyncProtocolConfig.enabled || world == null || world.isClientSide() || !TickThread.isTickThreadFor(world, blockEntity.getBlockPos())) {
return false;
}
BlockPos pos = blockEntity.getBlockPos();
BlockState blockState = world.getBlockState(pos);
Set<UUID> playerIds = collectWatchers(world, pos);
if (blockState.getBlock() instanceof ChestBlock && blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
BlockPos posAdj = pos.relative(ChestBlock.getConnectedDirection(blockState));
playerIds.addAll(collectWatchers(world, posAdj));
}
if (playerIds.isEmpty()) {
return false;
}
boolean ret = false;
for (UUID playerId : playerIds) {
if (MinecraftServer.getServer().getPlayerList().getPlayer(playerId) == null) {
removePlayerFromWatchers(playerId);
continue;
}
updateBlockEntity(playerId, blockEntity);
ret = true;
}
return ret;
}
public static void disablePcaSyncProtocolGlobal() {
playerWatchBlockPos.clear();
playerWatchEntity.clear();
blockPosWatchPlayerSet.clear();
entityWatchPlayerSet.clear();
for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
disablePcaSyncProtocol(player);
}
}
public static void enablePcaSyncProtocolGlobal() {
for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
enablePcaSyncProtocol(player);
}
}
public static void clearPlayerWatchData(ServerPlayer player) {
clearPlayerWatchData(player.getUUID());
}
private static void clearPlayerWatchData(UUID playerId) {
clearPlayerWatchBlock(playerId);
clearPlayerWatchEntity(playerId);
}
private static void clearPlayerWatchEntity(ServerPlayer player) {
clearPlayerWatchEntity(player.getUUID());
}
private static void clearPlayerWatchEntity(UUID playerId) {
Pair<Identifier, UUID> pair = playerWatchEntity.remove(playerId);
if (pair != null) {
removeFromSet(entityWatchPlayerSet, pair, playerId);
}
}
private static void clearPlayerWatchBlock(ServerPlayer player) {
clearPlayerWatchBlock(player.getUUID());
}
private static void clearPlayerWatchBlock(UUID playerId) {
Pair<Identifier, BlockPos> pair = playerWatchBlockPos.remove(playerId);
if (pair != null) {
removeFromSet(blockPosWatchPlayerSet, pair, playerId);
}
}
private static void removePlayerFromWatchers(UUID playerId) {
Pair<Identifier, BlockPos> blockPair = playerWatchBlockPos.remove(playerId);
if (blockPair != null) {
removeFromSet(blockPosWatchPlayerSet, blockPair, playerId);
}
Pair<Identifier, UUID> entityPair = playerWatchEntity.remove(playerId);
if (entityPair != null) {
removeFromSet(entityWatchPlayerSet, entityPair, playerId);
}
}
private static <K> void removeFromSet(ConcurrentMap<K, Set<UUID>> map, K key, UUID playerId) {
Set<UUID> playerSet = map.get(key);
if (playerSet != null) {
playerSet.remove(playerId);
if (playerSet.isEmpty()) {
map.remove(key, playerSet);
}
}
}
private static Set<UUID> collectWatchers(@NotNull Level world, @NotNull BlockPos blockPos) {
Set<UUID> playerIds = blockPosWatchPlayerSet.get(new ImmutablePair<>(world.dimension().identifier(), blockPos));
return playerIds == null ? new HashSet<>() : new HashSet<>(playerIds);
}
private static @org.jetbrains.annotations.Nullable BlockEntity getLoadedBlockEntity(ServerLevel world, BlockPos pos) {
LevelChunk chunk = world.getChunkIfLoaded(pos);
return chunk == null ? null : chunk.getBlockEntity(pos);
}
private static void scheduleBlockEntityUpdate(UUID playerId, ServerLevel world, BlockPos pos) {
Bukkit.getRegionScheduler().execute(MinecraftInternalPlugin.INSTANCE, world.getWorld(), pos.getX() >> 4, pos.getZ() >> 4, () -> {
if (!PcaSyncProtocolConfig.enabled || MinecraftServer.getServer().getPlayerList().getPlayer(playerId) == null || !TickThread.isTickThreadFor(world, pos)) {
return;
}
BlockEntity blockEntity = getLoadedBlockEntity(world, pos);
if (blockEntity != null) {
updateBlockEntity(playerId, blockEntity);
}
});
}
private static void syncEntityForWatcher(UUID playerId, boolean viewerIsOp, Entity entity) {
if (!PcaSyncProtocolConfig.enabled || MinecraftServer.getServer().getPlayerList().getPlayer(playerId) == null || !TickThread.isTickThreadFor(entity) || entity.isRemoved()) {
return;
}
if (entity instanceof Player && !maySyncPlayerEntity(playerId, viewerIsOp, entity)) {
return;
}
clearPlayerWatchData(playerId);
updateEntity(playerId, entity);
Pair<Identifier, UUID> pair = new ImmutablePair<>(entity.level().dimension().identifier(), entity.getUUID());
playerWatchEntity.put(playerId, pair);
entityWatchPlayerSet.computeIfAbsent(pair, ignored -> ConcurrentHashMap.newKeySet()).add(playerId);
}
private static boolean maySyncPlayerEntity(UUID viewerId, boolean viewerIsOp, Entity entity) {
return switch (PcaSyncProtocolConfig.syncPlayerEntity) {
case NOBODY -> false;
case BOT -> entity instanceof ServerBot;
case OPS -> entity instanceof ServerBot || viewerIsOp;
case OPS_AND_SELF -> entity instanceof ServerBot || viewerIsOp || entity.getUUID().equals(viewerId);
case EVERYONE -> true;
};
}
private static void sendEmptyPacket(UUID playerId, Identifier id) {
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (player == null) {
removePlayerFromWatchers(playerId);
return;
}
player.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> {
ServerPlayer onlinePlayer = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (onlinePlayer != null) {
ProtocolUtils.sendEmptyPacket(onlinePlayer, id);
}
}, null, 1L);
}
private static void sendPayloadPacket(UUID playerId, CustomPacketPayload payload) {
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (player == null) {
removePlayerFromWatchers(playerId);
return;
}
player.getBukkitEntity().getScheduler().execute(MinecraftInternalPlugin.INSTANCE, () -> {
ServerPlayer onlinePlayer = MinecraftServer.getServer().getPlayerList().getPlayer(playerId);
if (onlinePlayer != null) {
ProtocolUtils.sendPayloadPacket(onlinePlayer, payload);
}
}, null, 1L);
}
@Override
public boolean isActive() {
return PcaSyncProtocolConfig.enabled;
}
public record UpdateEntityPayload(Identifier dimension, int entityId,
CompoundTag tag) implements LeavesCustomPayload {
@ID
public static final Identifier UPDATE_ENTITY = PcaSyncProtocol.id("update_entity");
@Codec
public static final StreamCodec<FriendlyByteBuf, UpdateEntityPayload> CODEC = StreamCodec.composite(
Identifier.STREAM_CODEC,
UpdateEntityPayload::dimension,
ByteBufCodecs.INT,
UpdateEntityPayload::entityId,
ByteBufCodecs.COMPOUND_TAG,
UpdateEntityPayload::tag,
UpdateEntityPayload::new
);
}
public record UpdateBlockEntityPayload(Identifier dimension, BlockPos blockPos,
CompoundTag tag) implements LeavesCustomPayload {
@ID
private static final Identifier UPDATE_BLOCK_ENTITY = PcaSyncProtocol.id("update_block_entity");
@Codec
private static final StreamCodec<FriendlyByteBuf, UpdateBlockEntityPayload> CODEC = StreamCodec.composite(
Identifier.STREAM_CODEC,
UpdateBlockEntityPayload::dimension,
BlockPos.STREAM_CODEC,
UpdateBlockEntityPayload::blockPos,
ByteBufCodecs.COMPOUND_TAG,
UpdateBlockEntityPayload::tag,
UpdateBlockEntityPayload::new
);
}
public record SyncBlockEntityPayload(BlockPos pos) implements LeavesCustomPayload {
@ID
public static final Identifier SYNC_BLOCK_ENTITY = PcaSyncProtocol.id("sync_block_entity");
@Codec
private static final StreamCodec<FriendlyByteBuf, SyncBlockEntityPayload> CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, SyncBlockEntityPayload::pos, SyncBlockEntityPayload::new
);
}
public record SyncEntityPayload(int entityId) implements LeavesCustomPayload {
@ID
public static final Identifier SYNC_ENTITY = PcaSyncProtocol.id("sync_entity");
@Codec
private static final StreamCodec<FriendlyByteBuf, SyncEntityPayload> CODEC = StreamCodec.composite(
ByteBufCodecs.INT, SyncEntityPayload::entityId, SyncEntityPayload::new
);
}
}
@@ -295,7 +295,8 @@ public class LeavesProtocolManager {
}
public static void handleTick() {
long currentTime = System.currentTimeMillis() / MinecraftServer.getServer().tickRateManager().nanosecondsPerTick();
float interval = MinecraftServer.getServer().tickRateManager().millisecondsPerTick();
long currentTime = interval >= 1 ? System.currentTimeMillis() / (long) MinecraftServer.getServer().tickRateManager().millisecondsPerTick() : (long) (System.currentTimeMillis() / MinecraftServer.getServer().tickRateManager().millisecondsPerTick());
if (currentTime == lastAcceptTime) return;
lastAcceptTime = currentTime;
for (var tickerInfo : TICKERS) {
@@ -46,7 +46,7 @@ public class ProtocolUtils {
private static final byte[] EMPTY = new byte[0];
public static String buildProtocolVersion(String protocol) {
return protocol + "-leaves-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE);
return protocol + "-lophine-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE);
}
public static void sendEmptyPacket(ServerPlayer player, Identifier id) {
@@ -18,7 +18,7 @@
package org.leavesmc.leaves.protocol.jade.util;
import com.google.common.collect.Lists;
import net.minecraft.advancements.criterion.ItemPredicate;
import net.minecraft.advancements.predicates.ItemPredicate;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.registries.BuiltInRegistries;
@@ -184,7 +184,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
private static void putWorldData(@NotNull CompoundTag metadata) {
ServerLevel level = MinecraftServer.getServer().overworld();
BlockPos spawnPos = level.levelData.getRespawnData().pos();
BlockPos spawnPos = level.getLevelData().getRespawnData().pos();
metadata.putInt("spawnPosX", spawnPos.getX());
metadata.putInt("spawnPosY", spawnPos.getY());
metadata.putInt("spawnPosZ", spawnPos.getZ());
@@ -345,7 +345,8 @@ public class ServuxStructuresProtocol implements LeavesProtocol {
PACKET_C2S_STRUCTURES_UNREGISTER(4),
PACKET_S2C_STRUCTURE_DATA_START(5),
PACKET_S2C_SPAWN_METADATA(10),
PACKET_C2S_REQUEST_SPAWN_METADATA(11);
PACKET_C2S_REQUEST_SPAWN_METADATA(11),
PACKET_S2C_WEATHER_DATA(12);
public final int type;

Some files were not shown because too many files have changed in this diff Show More