Compare commits

...

39 Commits

Author SHA1 Message Date
MrHua269
f51216d01d Revert RegionizedTaskQueue referent counter changes 2025-03-20 23:20:39 +08:00
Kercute
3ef35a1b4b Add force the data command to be enabled config 2025-03-17 00:36:49 +08:00
Creeam
c06b8444aa [ci skip] Update CONTRIBUTING_EN.md 2025-03-16 12:59:34 +08:00
Creeam
3e96017ed6 [ci skip] Update EN contributing guide 2025-03-16 12:52:10 +08:00
Helvetica Volubi
85e32d5d03 [ci skip] Update CONTRIBUTING guide (#57)
* misc: fixup count of patch

* ci: update ncipollo/release-action to 1.16.0

* docs: update CONTRIBUTING.md

* docs: update CONTRIBUTING files

* docs: update CONTRIBUTING files

* Update CONTRIBUTING.md

* docs: sync zh_cn's update to en

* docs: correct grammar errors

* docs: fixup jdk version to 21

---------

Co-authored-by: xiaoxijun <A3167717663@hotmail.com>
2025-03-16 12:41:54 +08:00
xiaoxijun
778c82ee0a Merge pull request #54 from Suisuroru/suisuroru/revert-raid-changes
feat: Merge Revert-raid-changes of Leaves to Luminol
2025-03-15 23:08:06 +08:00
HaHaWTH
14146549a8 Updated Upstream (Folia) 2025-03-12 05:24:37 +14:00
MrHua269
064898cddf Do not search the block out of current region & Ported some micro optimizations from Leaf 2025-03-09 11:40:56 +08:00
Kercute
c829110cf3 0019-Skip-collision-check-if-the-block-is-not-belong-to-c.patch 2025-03-09 00:32:54 +08:00
Kercute
08cc27a648 Updated Upstream (Folia) 2025-03-08 23:09:59 +08:00
MrHua269
531d824a55 [ci skip] Use --global flag to configure git 2025-03-08 20:11:22 +08:00
MrHua269
0f6e3ac870 Add experiment config for entity to clean memory value which is not belong to current tickregion & Fix a series issue around entity memory typed GlobalPos 2025-03-08 09:58:16 +08:00
xiaoxijun
93e956372b Updated Upstream (Folia) 2025-03-07 13:17:09 +08:00
Dreeam
0bf38e65cf Updated Upstream (Folia) 2025-02-28 04:36:57 -05:00
Kercute
e5b2276a8d Updated Upstream (Folia) 2025-02-25 18:30:10 +08:00
HaHaWTH
589c263bac Configurable tripwire dupe
梦梦辛苦辽
2025-02-24 06:07:29 -08:00
M2ke4U
5d3d2271bc Merge pull request #55 from Suisuroru/suisuroru/descriptions-fix
Fix some syntax errors in configuration file descriptions and submit comments on container extension settings
2025-02-23 10:29:01 +08:00
Suisuroru
3361b9db14 feat(config): corrected words in some configuration descriptions 2025-02-23 02:17:42 +08:00
Suisuroru
3550274e82 feat(config): optimize configuration description of raid config 2025-02-23 02:13:46 +08:00
MrHua269
f6ca4cc24a [ci skip] Removed useless parts 2025-02-22 19:37:24 +08:00
MrHua269
85ffaa1156 Fix wrong upper-cased file name 2025-02-22 18:43:01 +08:00
MrHua269
6c48c27b7d Fixed end portal teleportation and added jenkins file 2025-02-22 18:38:44 +08:00
Dreeam
41770b069e Updated Upstream (Folia) 2025-02-22 03:48:09 -05:00
Suisuroru
e24d0fffdf feat: Merge Revert-raid-changes of Leaves to Luminol 2025-02-21 00:04:36 +08:00
Suisuroru
d4c1790f94 Purpur: barrels and enderchests 6 rows
Merge Barrels-and-enderchests-6-rows of Purpur to luminol - #50
2025-02-20 22:35:02 +08:00
Creeam
4346983b7d [ci skip] Don't create release for PR jars 2025-02-20 15:25:17 +08:00
HaHaWTH
720e02e944 Updated Upstream (Folia) 2025-02-17 21:30:17 -08:00
HaHaWTH
f035a3bd8e Updated Upstream (Folia) 2025-02-17 09:08:35 -08:00
HaHaWTH
365a5252a9 Make SIMD actually work 2025-02-15 07:19:20 -08:00
Dreeam
5746a0e01c Updated Upstream (Folia) 2025-02-14 01:41:38 -05:00
MrHua269
8bce97d0bb Fix uncorrected death check of folia 2025-02-11 13:36:54 +08:00
MrHua269
8817720b5a Removed mis-added files 2025-02-11 12:25:24 +08:00
MrHua269
525b5ccfba Clean patches 2025-02-11 12:06:21 +08:00
MrHua269
821c69804d 1 2025-02-11 10:47:34 +08:00
MrHua269
cc840886f3 Updated Upstream(Folia) 2025-02-11 09:23:11 +08:00
MrHua269
70257fa22b [ci skip]Diff 2025-02-08 15:25:47 +08:00
MrHua269
40242ad8de Leaves Fix Incorrect Collision Behavior for Block Shape 2025-02-08 14:27:27 +08:00
Dreeam
08cf5d6179 Fix build time showed in version command 2025-02-07 11:11:04 -05:00
MrHua269
88eb84f82d Do not store tick count for living entities 2025-02-07 23:07:33 +08:00
151 changed files with 4225 additions and 3533 deletions

View File

@@ -31,6 +31,7 @@ jobs:
- name: CreateJar - name: CreateJar
run: ./gradlew createMojmapPaperclipJar run: ./gradlew createMojmapPaperclipJar
- name: Publish to repo - name: Publish to repo
if: github.event_name != 'pull_request'
continue-on-error: true continue-on-error: true
run: | run: |
export MAVEN_REPO_USER=${{ secrets.MAVEN_REPO_USER }} export MAVEN_REPO_USER=${{ secrets.MAVEN_REPO_USER }}
@@ -42,10 +43,11 @@ jobs:
name: "${{ env.project_id_b }} CI Artifacts" name: "${{ env.project_id_b }} CI Artifacts"
path: "luminol-server/build/libs/*.jar" path: "luminol-server/build/libs/*.jar"
- name: SetENV - name: SetENV
if: github.event_name != 'pull_request'
run: sh scripts/SetENV.sh run: sh scripts/SetENV.sh
- name: Create Release - name: Create Release
if: "!contains(github.event.commits[0].message, '[release skip]')" if: github.event_name != 'pull_request'
uses: ncipollo/release-action@v1.14.0 uses: ncipollo/release-action@v1.16.0
with: with:
tag: ${{ env.tag }} tag: ${{ env.tag }}
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }} name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}

3
.gitignore vendored
View File

@@ -10,9 +10,8 @@ build
/luminol-api/build.gradle.kts /luminol-api/build.gradle.kts
/folia-server/build.gradle.kts /folia-server/build.gradle.kts
/folia-server/src/minecraft /folia-server/src/minecraft
/paper-server
/folia-api/build.gradle.kts /folia-api/build.gradle.kts
/paper-server
/paper-api /paper-api
/paper-api-generator
.idea/ .idea/

48
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,48 @@
pipeline {
agent any
stages {
stage('Configure git') {
steps {
script {
sh 'git config --global user.name "luminolmc"'
sh 'git config --global user.email "luminolmc@noreply.github.com"'
}
}
}
stage('Apply patches') {
steps {
script {
sh 'chmod +x gradlew'
sh './gradlew applyAllPatches'
}
}
}
stage('Build paperclip jar') {
steps {
script {
sh './gradlew createMojmapPaperclipJar'
}
}
}
stage('Upload artifacts') {
steps {
script {
archiveArtifacts(
artifacts: "luminol-server/build/libs/*.jar",
allowEmptyArchive: false
)
}
}
}
}
post {
always {
cleanWs()
}
}
}

View File

@@ -21,23 +21,24 @@
在开始开发之前,您首先需要拥有以下软件作为开发环境: 在开始开发之前,您首先需要拥有以下软件作为开发环境:
- `git` - `git`
- `JDK 17 或更高版本` - `JDK 21 或更高版本`
## 了解补丁Patches ## 了解补丁Patches
Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的修改分成了两个目录: Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的修改分成了两个目录:
- `luminol-api` - 对 `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit` 进行的修改。 - `luminol-api` - 对 `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit` 进行的修改。
- `luminol-server` - 对 Minecraft 标准服务器原有逻辑进行的修改。
补丁系统是基于 git 的,你可以在这里了解 git 的基本内容: <https://git-scm.com/docs/gittutorial> 补丁系统是基于 git 的,你可以在这里了解 git 的基本内容: <https://git-scm.com/docs/gittutorial>
如果你已经 Fork 了主储存库,那么下面你应该这么做: 如果你已经 Fork 了主储存库,那么下面你应该这么做:
1. 将你的仓库 clone 到本地; 1. 将你的仓库 clone 到本地;
2. 在你的 IDE 或 终端 内执行 Gradle 的 `applyPatches` 任务,如果是在终端内,你可以执行 `./gradlew applyPatches` 2. 在你的 IDE 或 终端 内执行 Gradle 的 `applyAllPatches` 任务,如果是在终端内,你可以执行 `./gradlew applyAllPatches`
3. 进入 `luminol-api` 文件夹进行修改。 3. 进入 仓库根目录下的 `luminol-api``luminol-server` 文件夹进行修改。
顺便一提,`luminol-api` 并不是正常的 git 仓库: 顺便一提,仓库根目录下的 `luminol-api``luminol-server` 并不是正常的 git 仓库:
- 在应用补丁前,基点将会指向未被更改的源码 - 在应用补丁前,基点将会指向未被更改的源码
- 在基点后的每一个提交都是一个补丁 - 在基点后的每一个提交都是一个补丁
@@ -47,11 +48,12 @@ Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的
按照以下步骤增加一个补丁是非常简单的: 按照以下步骤增加一个补丁是非常简单的:
1.`luminol-api` 进行修改; 1.`luminol-api``luminol-server` 进行修改;
2. 使用 git 添加你的修改,比如 `git add .` 2. 使用 git 添加你的修改,比如 `git add .`(不要提交新建的文件的修改)
3. 使用 `git commit -m <提交信息>` 进行提交; 3. 使用 `git commit -m <提交信息>` 进行提交;
4. 运行 Gradle 任务 `rebuildPatches` 将你的提交转化为一个补丁; 4. 运行 Gradle 任务 `rebuildAllServerPatches` 将你的提交转化为一个补丁;
5. 将你生成的补丁文件进行推送。 5. 运行 Gradle 任务 `fixupPaperApiFilePatches` 生成新建文件的补丁文件(注意不要提交);
6. 将你生成的补丁文件进行推送。
这样做以后,你就可以将你的补丁文件进行 PR 提交。 这样做以后,你就可以将你的补丁文件进行 PR 提交。
@@ -60,8 +62,9 @@ Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的
你可以使用以下方法来修改一个补丁的内容: 你可以使用以下方法来修改一个补丁的内容:
1. 在 HEAD 上直接进行修改; 1. 在 HEAD 上直接进行修改;
2. 使用 `git commit -a --fixup <hash>` 来进行一个更正提交; 2. 使用 `git commit -a --fixup <hash>` 来进行一个更正提交;不要提交对在luminol新建文件的修改
- 如果你想要更改提交信息,你也可以用 `--squash` 来代替 `--fixup` - 如果你想要更改提交信息,你也可以用 `--squash` 来代替 `--fixup`
3. 使用 `git rebase -i --autosquash base` 来进行自动变基,你只需要输入 `:q` 来关闭确认页面即可; 3. 使用 `git rebase -i --autosquash base` 来进行自动变基,你只需要输入 `:q` 来关闭确认页面即可;
4. 运行 Gradle 任务 `rebuildPatches` 来修改已被修改的补丁; 4. 运行 Gradle 任务 `rebuildAllServerPatches` 来修改已被修改的补丁;
5. 将修改后的补丁 PR 发回储存库。 5. 运行 Gradle 任务 `fixupPaperApiFilePatches` 来修改已被修改的在luminol新建文件的补丁注意不要提交
6. 将修改后的补丁 PR 发回储存库。

View File

@@ -10,20 +10,20 @@ And if you can follow the rules below, we can complete the review faster.
## Please fork using your personal account ## Please fork using your personal account
We regularly merge existing PRs. We regularly merge existing PRs.
If there're some small problems, we'll help you solve them by editing your PR. If there are some small problems, we'll help you solve them by editing your PR.
But, if your PR is from a organization, we can NOT edit your PR, so we must merge your PR manually. But, if your PR is from an organization, we can NOT edit your PR, so we must merge your PR manually.
So, don't use orgnization accounts for fork! So, don't use organization accounts for fork!
See also [This issue](https://github.com/isaacs/github/issues/1681), and then you'll know why we can't edit PRs from organizations. See also [This issue](https://github.com/isaacs/github/issues/1681), and then you'll know why we can't edit PRs from organizations.
## Development Environment ## Development Environment
Before coding, you need these softwares / tools as Dev Environment. Before coding, you need these pieces of software / tools as Dev Environment.
- `git` - `git`
- `JDK 17 or higher` - `JDK 21 or higher`
## Understanding "Patches" ## Understanding "Patches"
@@ -31,40 +31,43 @@ Luminol uses as the same patching system as Paper,
and has been divided into two directories for the purpose of modifying different parts of it: and has been divided into two directories for the purpose of modifying different parts of it:
- `luminol-api` - Modifications to `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit`. - `luminol-api` - Modifications to `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit`.
- `luminol-server` - Modifications to Minecraft Official Server's source logic.
The patching system is based on git, and you can learn about it at here: <https://git-scm.com/docs/gittutorial> The patching system is based on git, and you can learn about it at here: <https://git-scm.com/docs/gittutorial>
If you have forked the main repository, then you should follow the steps below: If you have forked the main repository, then you should follow the steps below:
1. Clone your repository to local 1. Clone your repository to local
2. Run Gradle's `applyPatches` task in your IDE or terminal (You can run `./gradlew applyPatches` directly in terminal.) 2. Run Gradle's `applyAllPatches` task in your IDE or terminal (You can run `./gradlew applyAllPatches` directly in terminal.)
3. Enter `luminol-api` directory to carry out modifications. 3. Enter `luminol-api` and `luminol-server` directory to carry out modifications.
BTW, `luminol-api` and are not normal git repositories. BTW, `luminol-api` and `luminol-server` and are not normal git repositories.
- Before applying patches, the base will point to unmodified source code. - Before applying patches, the base will point to unmodified source code.
- Every commit after the base is a patch. - Every commit after the base is a patch.
- Only commits after the last commit of Paper will be considered Luminol' patches. - Only commits after the last commit of Paper will be considered as Luminol patches.
## Adding new patches ## Adding new patches
It's very easy to to add patches by following the steps below: It's very easy to add patches by following the steps below:
1. Modify the code of `luminol-api` 1. Modify the code of `luminol-api` and `luminol-server`
2. Add these changes to the local git repository (For example, `git add .`) 2. Add these changes to the local git repository (For example, `git add .`)
3. Commit these changes using `git commit -m <Commit Message>` 3. Commit these changes using `git commit -m <Commit Message>` (PS: do not commit new-created files)
4. Run Gradle's task `rebuildPatches` to convert your commits to a new patch 4. Run Gradle's task `rebuildAllServerPatches` to convert your commits to a new patch
5. Push your patches to your repository 5. Run Gradle's task `fixupPaperApiFilePatches` to generate newly created files to new patches (PS: do not commit again before you run this task)
6. Push your patches to your repository
After pushing, you can open a PR to submit your patches. After pushing, you can open a PR to submit your patches.
## Modifying patches ## Modifying patches
You can modify a existing patch by following the steps below: You can modify an existing patch by following the steps below:
1. Modify code at HEAD 1. Modify code at HEAD
2. Run `git commit -a --fixup <hash>` in your terminal to make a fix-up commit 2. Run `git commit -a --fixup <hash>` in your terminal to make a fix-up commit (PS: do not commit changes of luminol-created files)
- If you want to edit the commit message, replace `--fixup` with `--squash`. - If you want to edit the commit message, replace `--fixup` with `--squash`.
3. Run `git rebase -i --autosquash base` to rebase automatically, then just type `:q` to close the confirm page 3. Run `git rebase -i --autosquash base` to rebase automatically, then just type `:q` to close the confirm page
4. Run Gradle's task `rebuildPatches` to modify existing patches 4. Run Gradle's task `rebuildAllServerPatches` to modify existing patches
5. Push and PR again 5. Run Gradle's task `fixupPaperApiFilePatches` to regenerate luminol-created files to patches (PS: do not commit again before you run this task)
6. Push and PR again

View File

@@ -2,7 +2,7 @@ group = me.earthme.luminol
version=1.21.4-R0.1-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT
mcVersion=1.21.4 mcVersion=1.21.4
foliaRef=3af04d9c6a98d24032bf8c99ad5446b0f381e320 foliaRef=d3969cdc419b84e2d94c13854d4eb94ae2e0b7be
org.gradle.configuration-cache=true org.gradle.configuration-cache=true
org.gradle.caching=true org.gradle.caching=true

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com> From: MrHua269 <wangxyper@163.com>
Date: Wed, 29 Jan 2025 09:50:53 +0800 Date: Tue, 11 Feb 2025 09:16:49 +0800
Subject: [PATCH] KioCG Chunk API Subject: [PATCH] KioCG Chunk API
@@ -16,13 +16,13 @@ index d434277342b2db19f98e032d3a316b27d728b840..e188353ad193f6203533790ae52fafc0
+ long getChunkHotAvg(); // KioCG + long getChunkHotAvg(); // KioCG
} }
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index dd043851687283f48af899d069d732425c794afd..ac5b7d030cbe3aae908fb2a0130cdf04d4924c18 100644 index 494dca2ee48a03953d47050b178496df12bc48c5..a65d64b1ef64cf1cf213cec00e7f73cc7ad2b79c 100644
--- a/src/main/java/org/bukkit/entity/Player.java --- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java
@@ -3928,4 +3928,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM @@ -3918,4 +3918,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @return the result of this method, holding leftovers and spawned items. * @param score New death screen score of player
*/ */
@NotNull PlayerGiveResult give(@NotNull Collection<@NotNull ItemStack> items, boolean dropIfFull); void setDeathScreenScore(int score);
+ +
+ long getNearbyChunkHot(); // KioCG + long getNearbyChunkHot(); // KioCG
} }

View File

@@ -6,10 +6,10 @@ Subject: [PATCH] Pufferfish SIMD Utilities
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9b5b32cd9 index 0000000000000000000000000000000000000000..856de1331b15542c00e01990f471fa5152722c11
--- /dev/null --- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java +++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
@@ -0,0 +1,39 @@ @@ -0,0 +1,35 @@
+package gg.pufferfish.pufferfish.simd; +package gg.pufferfish.pufferfish.simd;
+ +
+import jdk.incubator.vector.FloatVector; +import jdk.incubator.vector.FloatVector;
@@ -26,9 +26,6 @@ index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9
+ @Deprecated + @Deprecated
+ public static boolean canEnable(Logger logger) { + public static boolean canEnable(Logger logger) {
+ try { + try {
+ if (SIMDDetection.getJavaVersion() < 17 || SIMDDetection.getJavaVersion() > 21) {
+ return false;
+ } else {
+ SIMDDetection.testRun = true; + SIMDDetection.testRun = true;
+ +
+ VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED; + VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED;
@@ -43,7 +40,6 @@ index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9
+ } + }
+ +
+ return true; + return true;
+ }
+ } catch (NoClassDefFoundError | Exception ignored) {} // Basically, we don't do anything. This lets us detect if it's not functional and disable it. + } catch (NoClassDefFoundError | Exception ignored) {} // Basically, we don't do anything. This lets us detect if it's not functional and disable it.
+ return false; + return false;
+ } + }
@@ -51,10 +47,10 @@ index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9
+} +}
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..cd953435a6179eaae7c9cc250a791cae26c5567b index 0000000000000000000000000000000000000000..0a64cd0e88083ac4af6674ad0fb07b771109c737
--- /dev/null --- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java +++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
@@ -0,0 +1,35 @@ @@ -0,0 +1,34 @@
+package gg.pufferfish.pufferfish.simd; +package gg.pufferfish.pufferfish.simd;
+ +
+import org.slf4j.Logger; +import org.slf4j.Logger;
@@ -63,7 +59,6 @@ index 0000000000000000000000000000000000000000..cd953435a6179eaae7c9cc250a791cae
+public class SIMDDetection { +public class SIMDDetection {
+ +
+ public static boolean isEnabled = false; + public static boolean isEnabled = false;
+ public static boolean versionLimited = false;
+ public static boolean testRun = false; + public static boolean testRun = false;
+ +
+ @Deprecated + @Deprecated
@@ -90,3 +85,118 @@ index 0000000000000000000000000000000000000000..cd953435a6179eaae7c9cc250a791cae
+ } + }
+ +
+} +}
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/VectorMapPalette.java b/src/main/java/gg/pufferfish/pufferfish/simd/VectorMapPalette.java
new file mode 100644
index 0000000000000000000000000000000000000000..c26dcaaa2e85882730c854099df80d69eec70f33
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/VectorMapPalette.java
@@ -0,0 +1,84 @@
+package gg.pufferfish.pufferfish.simd;
+
+import jdk.incubator.vector.FloatVector;
+import jdk.incubator.vector.IntVector;
+import jdk.incubator.vector.VectorMask;
+import jdk.incubator.vector.VectorSpecies;
+import org.bukkit.map.MapPalette;
+
+import java.awt.*;
+
+@Deprecated
+public class VectorMapPalette {
+
+ private static final VectorSpecies<Integer> I_SPEC = IntVector.SPECIES_PREFERRED;
+ private static final VectorSpecies<Float> F_SPEC = FloatVector.SPECIES_PREFERRED;
+
+ @Deprecated
+ public static void matchColorVectorized(int[] in, byte[] out) {
+ int speciesLength = I_SPEC.length();
+ int i;
+ for (i = 0; i < in.length - speciesLength; i += speciesLength) {
+ float[] redsArr = new float[speciesLength];
+ float[] bluesArr = new float[speciesLength];
+ float[] greensArr = new float[speciesLength];
+ int[] alphasArr = new int[speciesLength];
+
+ for (int j = 0; j < speciesLength; j++) {
+ alphasArr[j] = (in[i + j] >> 24) & 0xFF;
+ redsArr[j] = (in[i + j] >> 16) & 0xFF;
+ greensArr[j] = (in[i + j] >> 8) & 0xFF;
+ bluesArr[j] = (in[i + j] >> 0) & 0xFF;
+ }
+
+ IntVector alphas = IntVector.fromArray(I_SPEC, alphasArr, 0);
+ FloatVector reds = FloatVector.fromArray(F_SPEC, redsArr, 0);
+ FloatVector greens = FloatVector.fromArray(F_SPEC, greensArr, 0);
+ FloatVector blues = FloatVector.fromArray(F_SPEC, bluesArr, 0);
+ IntVector resultIndex = IntVector.zero(I_SPEC);
+ VectorMask<Integer> modificationMask = VectorMask.fromLong(I_SPEC, 0xffffffff);
+
+ modificationMask = modificationMask.and(alphas.lt(128).not());
+ FloatVector bestDistances = FloatVector.broadcast(F_SPEC, Float.MAX_VALUE);
+
+ for (int c = 4; c < MapPalette.colors.length; c++) {
+ // We're using 32-bit floats here because it's 2x faster and nobody will know the difference.
+ // For correctness, the original algorithm uses 64-bit floats instead. Completely unnecessary.
+ FloatVector compReds = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getRed());
+ FloatVector compGreens = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getGreen());
+ FloatVector compBlues = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getBlue());
+
+ FloatVector rMean = reds.add(compReds).div(2.0f);
+ FloatVector rDiff = reds.sub(compReds);
+ FloatVector gDiff = greens.sub(compGreens);
+ FloatVector bDiff = blues.sub(compBlues);
+
+ FloatVector weightR = rMean.div(256.0f).add(2);
+ FloatVector weightG = FloatVector.broadcast(F_SPEC, 4.0f);
+ FloatVector weightB = FloatVector.broadcast(F_SPEC, 255.0f).sub(rMean).div(256.0f).add(2.0f);
+
+ FloatVector distance = weightR.mul(rDiff).mul(rDiff).add(weightG.mul(gDiff).mul(gDiff)).add(weightB.mul(bDiff).mul(bDiff));
+
+ // Now we compare to the best distance we've found.
+ // This mask contains a "1" if better, and a "0" otherwise.
+ VectorMask<Float> bestDistanceMask = distance.lt(bestDistances);
+ bestDistances = bestDistances.blend(distance, bestDistanceMask); // Update the best distances
+
+ // Update the result array
+ // We also AND with the modification mask because we don't want to interfere if the alpha value isn't large enough.
+ resultIndex = resultIndex.blend(c, bestDistanceMask.cast(I_SPEC).and(modificationMask)); // Update the results
+ }
+
+ for (int j = 0; j < speciesLength; j++) {
+ int index = resultIndex.lane(j);
+ out[i + j] = (byte) (index < 128 ? index : -129 + (index - 127));
+ }
+ }
+
+ // For the final ones, fall back to the regular method
+ for (; i < in.length; i++) {
+ out[i] = MapPalette.matchColor(new Color(in[i], true));
+ }
+ }
+
+}
diff --git a/src/main/java/org/bukkit/map/MapPalette.java b/src/main/java/org/bukkit/map/MapPalette.java
index 6995f9cc08d162e3adcd3a28f6bfa6d329661999..83ea70a16b4090a8c628784f2807cd16e7065103 100644
--- a/src/main/java/org/bukkit/map/MapPalette.java
+++ b/src/main/java/org/bukkit/map/MapPalette.java
@@ -45,7 +45,7 @@ public final class MapPalette {
}
@NotNull
- static final Color[] colors = {
+ public static final Color[] colors = { // Luminol - package-private -> public
c(0, 0, 0, 0), c(0, 0, 0, 0), c(0, 0, 0, 0), c(0, 0, 0, 0),
c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29),
c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86),
@@ -216,9 +216,11 @@ public final class MapPalette {
temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth());
byte[] result = new byte[temp.getWidth() * temp.getHeight()];
+ if ((mapColorCache != null && mapColorCache.isCached()) || !gg.pufferfish.pufferfish.simd.SIMDDetection.isEnabled) { // Luminol - Pufferfish - vectorized map color conversion
for (int i = 0; i < pixels.length; i++) {
result[i] = matchColor(new Color(pixels[i], true));
}
+ } else gg.pufferfish.pufferfish.simd.VectorMapPalette.matchColorVectorized(pixels, result); // Luminol - Pufferfish - vectorized map color conversion
return result;
}

View File

@@ -186,10 +186,10 @@ index 0000000000000000000000000000000000000000..ecde4462b08d701b8bff9f26902f1775
+ RegionStats getRegionStats(); + RegionStats getRegionStats();
+} +}
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 8784842d14bbbe7dbde181e86782a0955be66924..f998f6f0d3017767aa4dde45a7e8aea5dd36fe99 100644 index 015d852d5a0c01042a2153a6916d408660356c59..c7b6f3f6c42746297816c0650571990f565d5e68 100644
--- a/src/main/java/org/bukkit/World.java --- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java
@@ -4407,4 +4407,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @@ -4432,4 +4432,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
} }
} }
} }

View File

@@ -67,8 +67,8 @@
implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("ca.spottedleaf:concurrentutil:0.0.3")
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
@@ -200,6 +_,13 @@ @@ -201,26 +_,33 @@
implementation("me.lucko:spark-paper:1.10.119-SNAPSHOT") implementation("me.lucko:spark-paper:1.10.119-20241121.092015-1")
} }
+// Pufferfish Start +// Pufferfish Start
@@ -81,7 +81,13 @@
tasks.jar { tasks.jar {
manifest { manifest {
val git = Git(rootProject.layout.projectDirectory.path) val git = Git(rootProject.layout.projectDirectory.path)
@@ -212,14 +_,14 @@ val mcVersion = rootProject.providers.gradleProperty("mcVersion").get()
val build = System.getenv("BUILD_NUMBER") ?: null
- val buildTime = if (build != null) Instant.now() else Instant.EPOCH
+ val buildTime = Instant.now() // Always use current as build time
val gitHash = git.exec(providers, "rev-parse", "--short=7", "HEAD").get().trim()
val implementationVersion = "$mcVersion-${build ?: "DEV"}-$gitHash"
val date = git.exec(providers, "show", "-s", "--format=%ci", gitHash).get().trim()
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim() val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
attributes( attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main", "Main-Class" to "org.bukkit.craftbukkit.Main",
@@ -101,10 +107,11 @@
"Build-Number" to (build ?: ""), "Build-Number" to (build ?: ""),
"Build-Time" to buildTime.toString(), "Build-Time" to buildTime.toString(),
"Git-Branch" to gitBranch, "Git-Branch" to gitBranch,
@@ -350,3 +_,9 @@ @@ -351,3 +_,10 @@
classpath(tasks.createReobfPaperclipJar.flatMap { it.outputZip }) classpath(tasks.createReobfPaperclipJar.flatMap { it.outputZip })
mainClass.set(null as String?) mainClass.set(null as String?)
} }
+
+// Pufferfish Start +// Pufferfish Start
+tasks.withType<JavaCompile> { +tasks.withType<JavaCompile> {
+ val compilerArgs = options.compilerArgs + val compilerArgs = options.compilerArgs

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:15:52 +0800
Subject: [PATCH] Add luminol config framework
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
index 9aa664537cc37e44db46d5a2a64ae3116938c681..8d6a6534a134e99e5ee2652d7b0c858d538e69bd 100644
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -108,6 +108,7 @@ public class Main {
JvmProfiler.INSTANCE.start(Environment.SERVER);
}
+ me.earthme.luminol.config.LuminolConfig.preLoadConfig(); // Luminol - Luminol config
io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
Bootstrap.bootStrap();
Bootstrap.validate();
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 341e400f789e0eda29827e2c45c483a470d2e982..8f348d140ab98e23ee0debe4bacac51fee49c35e 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -212,6 +212,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
// Paper end - initialize global and world-defaults configuration
+ me.earthme.luminol.config.LuminolConfig.finalizeLoadConfig(); //Luminol - load config file
+ me.earthme.luminol.config.LuminolConfig.setupLatch(); //Luminol - load config file
this.server.spark.enableEarlyIfRequested(); // Paper - spark
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
if (this.convertOldUsers()) {

View File

@@ -27,7 +27,7 @@ index 1fa5e6a12b943e889bde566038a632a6adcf319e..c1f6a3b3a8fa990b8e9b052341ab31bd
} }
} }
diff --git a/net/minecraft/world/level/block/EndPortalBlock.java b/net/minecraft/world/level/block/EndPortalBlock.java diff --git a/net/minecraft/world/level/block/EndPortalBlock.java b/net/minecraft/world/level/block/EndPortalBlock.java
index 177735cf744e564081e4c140a0f8210c3a07e037..7274f2d7df9228f34305a21abde6d114a495c1cb 100644 index 554d75ac1374d7d93977a10e06fcf51259830c97..17c1ce4397c5953bb92aaa3b56c179b7c24a0736 100644
--- a/net/minecraft/world/level/block/EndPortalBlock.java --- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java +++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -67,6 +67,11 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { @@ -67,6 +67,11 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Add config for vanilla random
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 597520a680bc1a54055b99f93724682a4d940458..4cfc228a60a147409b8afc4cb138ce6437a9b667 100644 index 2cd2ce1060f567be6c72b7bc9d02651ec7166203..f69fd922fa67cd366dbb93c34fa15659ba76c844 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -255,7 +255,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -255,7 +255,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess

View File

@@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com> From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 11:29:49 +0800 Date: Sun, 12 Jan 2025 10:27:31 +0800
Subject: [PATCH] KioCG Chunk API and display of chunkhot in tpsbar Subject: [PATCH] Add tpsbar with chunkhot membar and regionbar
diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
@@ -17,10 +17,10 @@ index 8d67b4629c69d3039b199aaad45533d1acde114e..f7bfeca4b11b9860241d5eb80b6df420
((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
} }
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index ff71466ec0848d16121e351e30c31bb419af8b99..330af9f4de1c72387326816065350e71fe546efe 100644 index 46375fa81b36b89b79c22f0a7ac6d610ab1183d4..f2124edb487b1d5f6bdc7fa086814f870724363a 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -1666,7 +1666,44 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1665,7 +1665,44 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia end - region threading // Folia end - region threading
//this.tickCount++; // Folia - region threading //this.tickCount++; // Folia - region threading
//this.tickRateManager.tick(); // Folia - region threading //this.tickRateManager.tick(); // Folia - region threading
@@ -65,11 +65,25 @@ index ff71466ec0848d16121e351e30c31bb419af8b99..330af9f4de1c72387326816065350e71
if (false && nanos - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) { // Folia - region threading if (false && nanos - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) { // Folia - region threading
this.lastServerStatus = nanos; this.lastServerStatus = nanos;
this.status = this.buildServerStatus(); this.status = this.buildServerStatus();
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 375f4a59333ee1d75fb1acb8c2cbada7866bd48e..3abe2881e8a80bd6c128e96b976deebe3ada4678 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -766,6 +766,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
+ me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
+ me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
+ me.earthme.luminol.functions.GlobalServerRegionBar.cancelBarUpdateTask(); //Luminol - Region bar
super.stopServer();
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
SkullBlockEntity.clear();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b14d6f62f 100644 index f2d2ddfd964bff914e41c0b4150fe1aad7866ebf..7defcd15c44601bfd2f7f55046038693264defee 100644
--- a/net/minecraft/server/level/ServerLevel.java --- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java
@@ -1347,6 +1347,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1339,6 +1339,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId; final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
profiler.startTimer(timerId); profiler.startTimer(timerId);
@@ -78,7 +92,7 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
try { try {
// Folia end - profiler // Folia end - profiler
if (isActive) { // Paper - EAR 2 if (isActive) { // Paper - EAR 2
@@ -1364,6 +1366,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1356,6 +1358,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
} else {entity.inactiveTick();} // Paper - EAR 2 } else {entity.inactiveTick();} // Paper - EAR 2
profilerFiller.pop(); profilerFiller.pop();
} finally { profiler.stopTimer(timerId); } // Folia - profiler } finally { profiler.stopTimer(timerId); } // Folia - profiler
@@ -86,7 +100,7 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
for (Entity entity1 : entity.getPassengers()) { for (Entity entity1 : entity.getPassengers()) {
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
@@ -1383,6 +1386,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1375,6 +1378,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
final int timerId = isActive ? passengerEntity.getType().tickTimerId : passengerEntity.getType().inactiveTickTimerId; final int timerId = isActive ? passengerEntity.getType().tickTimerId : passengerEntity.getType().inactiveTickTimerId;
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
profiler.startTimer(timerId); profiler.startTimer(timerId);
@@ -95,7 +109,7 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
try { try {
// Folia end - profiler // Folia end - profiler
passengerEntity.setOldPosAndRot(); passengerEntity.setOldPosAndRot();
@@ -1416,6 +1421,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1409,6 +1414,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2 this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2
} }
} finally { profiler.stopTimer(timerId); } // Folia - profiler } finally { profiler.stopTimer(timerId); } // Folia - profiler
@@ -104,10 +118,21 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
} }
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index f1239f1a7b6b8fd958333df8092359eea7197fc0..9fd3fe181df2ce6dbe695f6463d3940ac4c01167 100644 index 423534a1ff02bd0d0f9baacfe2428f45c7d9acb9..9fd3fe181df2ce6dbe695f6463d3940ac4c01167 100644
--- a/net/minecraft/server/level/ServerPlayer.java --- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1008,7 +1008,34 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc @@ -393,7 +393,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
-
+ public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
+ public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
+ public volatile boolean isRegionBarVisible = false; //Luminol - Region bar
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
@@ -1006,8 +1008,35 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.trackEnteredOrExitedLavaOnVehicle(); this.trackEnteredOrExitedLavaOnVehicle();
this.updatePlayerAttributes(); this.updatePlayerAttributes();
this.advancements.flushDirty(this); this.advancements.flushDirty(this);
@@ -117,8 +142,8 @@ index f1239f1a7b6b8fd958333df8092359eea7197fc0..9fd3fe181df2ce6dbe695f6463d3940a
+ this.nearbyChunkHot = this.refreshNearbyChunkHot(); + this.nearbyChunkHot = this.refreshNearbyChunkHot();
+ } + }
+ // KioCG end + // KioCG end
+ } }
+
+ // KioCG start - ChunkHot + // KioCG start - ChunkHot
+ private volatile long nearbyChunkHot = 0; + private volatile long nearbyChunkHot = 0;
+ +
@@ -136,12 +161,13 @@ index f1239f1a7b6b8fd958333df8092359eea7197fc0..9fd3fe181df2ce6dbe695f6463d3940a
+ } + }
+ } + }
+ return total; + return total;
} + }
+ // KioCG end + // KioCG end
+ +
+
private void updatePlayerAttributes() { private void updatePlayerAttributes() {
AttributeInstance attribute = this.getAttribute(Attributes.BLOCK_INTERACTION_RANGE); AttributeInstance attribute = this.getAttribute(Attributes.BLOCK_INTERACTION_RANGE);
if (attribute != null) {
diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java
index 23b342cc31c7e72ade0e1ccad86a9ccf34380f13..249cb7326c8e4012dcffdb6bbb7bfc1f1eeb7b33 100644 index 23b342cc31c7e72ade0e1ccad86a9ccf34380f13..249cb7326c8e4012dcffdb6bbb7bfc1f1eeb7b33 100644
--- a/net/minecraft/world/entity/AreaEffectCloud.java --- a/net/minecraft/world/entity/AreaEffectCloud.java
@@ -159,10 +185,10 @@ index 23b342cc31c7e72ade0e1ccad86a9ccf34380f13..249cb7326c8e4012dcffdb6bbb7bfc1f
+ // KioCG end + // KioCG end
} }
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 5979893976ab8c59a17e306cd91c9a4f5cd3738e..4f0ea00cd601c62926220400c8e3597815dc4d15 100644 index f69fd922fa67cd366dbb93c34fa15659ba76c844..cc8efa162fbe7ce6a91629239bf18d7b6b096a8a 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -5967,4 +5967,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -5919,4 +5919,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition()); return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition());
} }
// Paper end - Expose entity id counter // Paper end - Expose entity id counter
@@ -186,10 +212,10 @@ index f003a65b34027dff14455860815c7d719c5289fa..6f9f8e52d2311343a0c0c3900a466c6a
+ // KioCG end + // KioCG end
} }
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index 6394b0899095b047ca9266135fc44aa0c32467cf..af7dbb0f2df0ec42c2c16bc58ba16b6c65d3ebcb 100644 index da922d4c0ffa0f40d5e8dd69487bf30dbbbeed87..94a7b95f41c2954561f9c3cb0f61210c0c058f1d 100644
--- a/net/minecraft/world/entity/Mob.java --- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java
@@ -1720,4 +1720,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @@ -1722,4 +1722,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
public float[] getArmorDropChances() { public float[] getArmorDropChances() {
return this.armorDropChances; return this.armorDropChances;
} }
@@ -234,10 +260,10 @@ index 6655d06e2011e20e7346dfe57527795269094d8a..48aa6fcb5c16fdbb4ae902cbb72c6b8e
+ // KioCG end + // KioCG end
} }
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 7635b16cf82577a4822a5057aa5319d4c23e2168..0e020dfebe06dce4c19beb10c961ea9e8a35a415 100644 index e70919757dee4b02384ded3551c8f580d289584a..ae049c5c3593525b991d865fec695c00ad408a59 100644
--- a/net/minecraft/world/entity/player/Player.java --- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java
@@ -1544,6 +1544,13 @@ public abstract class Player extends LivingEntity { @@ -1546,6 +1546,13 @@ public abstract class Player extends LivingEntity {
return true; return true;
} }

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:27:31 +0800
Subject: [PATCH] Add a simple tpsbar
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 8f348d140ab98e23ee0debe4bacac51fee49c35e..852d598fc11a9640a20b093839707c3a5a96e057 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -764,6 +764,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
+ me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
super.stopServer();
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
SkullBlockEntity.clear();
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index ca3770e9f77e583dfa6cef8ca884eaf6a43f5ffa..465f20e5f24a8b37fb31393bcedd3807896666c7 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -393,7 +393,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
-
+ public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();

View File

@@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:28:03 +0800
Subject: [PATCH] Add a simple membar
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 852d598fc11a9640a20b093839707c3a5a96e057..cc80198a5d5f4e9188ef35944d077200f03ac43b 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -765,6 +765,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
+ me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
super.stopServer();
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
SkullBlockEntity.clear();
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 465f20e5f24a8b37fb31393bcedd3807896666c7..b4a4eec6029f1aee5f3b0da6938a9b23db36d5f9 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -394,6 +394,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
+ public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Add config for offline mode warning
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index c6490516215ad94323174de81771f258cecc7742..ff2de692d397bf658fc7c8af0c6ce7697d1076a7 100644 index 3abe2881e8a80bd6c128e96b976deebe3ada4678..a0a8b0c7d091f63f023f15a2620b03ae2126782e 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java --- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -285,7 +285,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -285,7 +285,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface

View File

@@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: adabugra <57899270+adabugra@users.noreply.github.com>
Date: Fri, 31 Jan 2025 01:21:44 +0300
Subject: [PATCH] Add a simple regionbar
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index cc80198a5d5f4e9188ef35944d077200f03ac43b..c6490516215ad94323174de81771f258cecc7742 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -766,6 +766,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
public void stopServer() {
me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
+ me.earthme.luminol.functions.GlobalServerRegionBar.cancelBarUpdateTask(); //Luminol - Region bar
super.stopServer();
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
SkullBlockEntity.clear();
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index a07e02132bdda2693686440b9932992641cb6957..f1239f1a7b6b8fd958333df8092359eea7197fc0 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -395,6 +395,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
+ public volatile boolean isRegionBarVisible = false; //Luminol - Region bar
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();

View File

@@ -17,16 +17,3 @@ index 41a9cc693183e96c83837692e93b177a521d6789..f4a2d1a2d467808b9cb75fc32765ddc2
throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE, org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PUBLIC_KEY_SIGNATURE); // Paper - kick event causes throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE, org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PUBLIC_KEY_SIGNATURE); // Paper - kick event causes
} else { } else {
return new ProfilePublicKey(data); return new ProfilePublicKey(data);
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index 6a7e5a642e2eaf7d5dffadb81738f7385a38c0af..f16500a50904aade3d984b908b11b8edd9c05ba1 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -215,7 +215,7 @@ public class TripWireHookBlock extends Block {
BlockState blockState2 = blockStates[i2];
if (blockState2 != null) {
BlockState blockState3 = level.getBlockState(blockPos1);
- if (blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) {
+ if (me.earthme.luminol.config.modules.misc.TripwireConfig.enabled || blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) { // Luminol - Add config for tripwire dupe
level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3);
}
}

View File

@@ -55,7 +55,7 @@ index 51c126735ace8fdde89ad97b5cab62f244212db0..c7d4d944eb198ac53a3eeae717a25c7d
+ public void moonrise$write(final abomination.IRegionFile regionFile) throws IOException; // Luminol - Configurable region file format + public void moonrise$write(final abomination.IRegionFile regionFile) throws IOException; // Luminol - Configurable region file format
} }
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 46375fa81b36b89b79c22f0a7ac6d610ab1183d4..c00378ba258647787bb9138e319b0f6a0b00e1ed 100644 index f2124edb487b1d5f6bdc7fa086814f870724363a..ed00a29daccfee1d631bef27c0a3a4ae83140018 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -986,10 +986,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -986,10 +986,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View File

@@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sat, 8 Mar 2025 09:56:15 +0800
Subject: [PATCH] Add experiment config for entity to clean memory value which
is not belong to current tickregion
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index 65b2b3ece213d901cdd585093e2fafcd2ef4a7cd..d61fba01feecce3610cd390f490d3097c5db19c4 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -399,7 +399,7 @@ public class Brain<E extends LivingEntity> {
}
public void tick(ServerLevel level, E entity) {
- this.forgetOutdatedMemories();
+ this.forgetOutdatedMemories(entity); // Luminol - Add config to force clean entity memory that don't belong to current tick region
this.tickSensors(level, entity);
this.startEachNonRunningBehavior(level, entity);
this.tickEachRunningBehavior(level, entity);
@@ -411,10 +411,31 @@ public class Brain<E extends LivingEntity> {
}
}
- private void forgetOutdatedMemories() {
+ private void forgetOutdatedMemories(E owner) { // Luminol - Add config to force clean entity memory that don't belong to current tick region
for (Entry<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> entry : this.memories.entrySet()) {
if (entry.getValue().isPresent()) {
ExpirableValue<?> expirableValue = (ExpirableValue<?>)entry.getValue().get();
+ // Luminol start - Add config to force clean entity memory that don't belong to current tick region
+ final Object value = expirableValue.getValue();
+ final net.minecraft.world.level.Level ownerLevel = owner.level();
+
+ // type: entity
+ if (me.earthme.luminol.config.modules.experiment.ForceCleanupEntityBrainMemoryConfig.enabledForEntity && value instanceof LivingEntity entity) {
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(entity)) {
+ this.eraseMemory(entry.getKey());
+ continue;
+ }
+ }
+
+ // type: block_pos
+ if (me.earthme.luminol.config.modules.experiment.ForceCleanupEntityBrainMemoryConfig.enabledForBlockPos && value instanceof net.minecraft.core.BlockPos blockPos) {
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(ownerLevel, blockPos)) {
+ this.eraseMemory(entry.getKey());
+ continue;
+ }
+ }
+ // Luminol end
+
if (expirableValue.hasExpired()) {
this.eraseMemory(entry.getKey());
}

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Teleport async if entity was moving to another region at once
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index c9730114f1d5dc1ecd6a38dbc7e5e936065dd92b..1868cb351d030d1997b5c81a184657085261c2f3 100644 index cc8efa162fbe7ce6a91629239bf18d7b6b096a8a..4026d465687604965f105ded21a8206fd52bd375 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -1099,6 +1099,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -1100,6 +1100,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
// Paper end - detailed watchdog information // Paper end - detailed watchdog information
@@ -19,7 +19,7 @@ index c9730114f1d5dc1ecd6a38dbc7e5e936065dd92b..1868cb351d030d1997b5c81a18465708
public void move(MoverType type, Vec3 movement) { public void move(MoverType type, Vec3 movement) {
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
// Paper start - detailed watchdog information // Paper start - detailed watchdog information
@@ -1109,6 +1113,32 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -1110,6 +1114,32 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.moveStartZ = this.getZ(); this.moveStartZ = this.getZ();
this.moveVector = movement; this.moveVector = movement;
} }

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Force disable builtin spark plugin
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index c00378ba258647787bb9138e319b0f6a0b00e1ed..ff71466ec0848d16121e351e30c31bb419af8b99 100644 index ed00a29daccfee1d631bef27c0a3a4ae83140018..330af9f4de1c72387326816065350e71fe546efe 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -783,8 +783,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -783,8 +783,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -65,7 +65,7 @@ index c00378ba258647787bb9138e319b0f6a0b00e1ed..ff71466ec0848d16121e351e30c31bb4
new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper - Server Tick Events // Folia - region threading new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper - Server Tick Events // Folia - region threading
// Folia start - region threading // Folia start - region threading
if (region != null) { if (region != null) {
@@ -1706,7 +1707,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1743,7 +1744,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
long remaining = scheduledEnd - endTime; // Folia - region ticking long remaining = scheduledEnd - endTime; // Folia - region ticking
new com.destroystokyo.paper.event.server.ServerTickEndEvent((int)io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(), ((double)(endTime - startTime) / 1000000D), remaining).callEvent(); // Folia - region ticking new com.destroystokyo.paper.event.server.ServerTickEndEvent((int)io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(), ((double)(endTime - startTime) / 1000000D), remaining).callEvent(); // Folia - region ticking
// Paper end - Server Tick Events // Paper end - Server Tick Events
@@ -75,7 +75,7 @@ index c00378ba258647787bb9138e319b0f6a0b00e1ed..ff71466ec0848d16121e351e30c31bb4
} }
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index ff2de692d397bf658fc7c8af0c6ce7697d1076a7..5973e6f327d3557ca95f504fe7b1a6c227a3e15f 100644 index a0a8b0c7d091f63f023f15a2620b03ae2126782e..d7c922540b46e289395aeed514c98e43dc298e7b 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java --- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -214,7 +214,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -214,7 +214,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface

View File

@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 11 Feb 2025 13:34:47 +0800
Subject: [PATCH] Fix uncorrected death check of folia
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
index 50af953a4698a3c6e16b840fab764dd733b3fbc9..a9c058238819f3631d94ac306185e909821caf35 100644
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -679,7 +679,7 @@ public abstract class AbstractContainerMenu {
}
private static void dropOrPlaceInInventory(Player player, ItemStack stack) {
- boolean flag = player.isRemoved() && player.getRemovalReason() != Entity.RemovalReason.CHANGED_DIMENSION;
+ boolean flag = !player.isAlive(); //player.isRemoved() && player.getRemovalReason() != Entity.RemovalReason.CHANGED_DIMENSION; // Luminol - Fix uncorrected death check of folia
boolean flag1 = player instanceof ServerPlayer serverPlayer && serverPlayer.hasDisconnected();
if (flag || flag1) {
player.drop(stack, false);

View File

@@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sat, 8 Mar 2025 09:55:40 +0800
Subject: [PATCH] Fix a series issue around entity memory typed GlobalPos and
WalkTarget
diff --git a/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java b/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java
index 2664d72c3b6906d0505df2e63c0e5075eba9461b..f03c3c512ea48c2a89eebae62484922d28e4f831 100644
--- a/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java
@@ -69,6 +69,11 @@ public class BehaviorUtils {
}
public static void setWalkAndLookTargetMemories(LivingEntity entity, PositionTracker positionTracker, float speedModifier, int closeEnoughDist) {
+ // Luminol - Do not set walk target if target position is out of current tick region
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(entity.level(), positionTracker.currentBlockPosition())) {
+ return;
+ }
+ // Luminol end
WalkTarget walkTarget = new WalkTarget(positionTracker, speedModifier, closeEnoughDist);
entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, positionTracker);
entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, walkTarget);
diff --git a/net/minecraft/world/entity/ai/behavior/SleepInBed.java b/net/minecraft/world/entity/ai/behavior/SleepInBed.java
index bc6a5cacd67d46e0beb97adf30d98c1034be1a44..dd35eef062c36a409b6d3e701664db504c4c7631 100644
--- a/net/minecraft/world/entity/ai/behavior/SleepInBed.java
+++ b/net/minecraft/world/entity/ai/behavior/SleepInBed.java
@@ -42,6 +42,12 @@ public class SleepInBed extends Behavior<LivingEntity> {
}
}
+ // Luminol - Prevent off-tick-region chunk operations
+ final net.minecraft.world.level.Level currentLevel = owner.level();
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(currentLevel, globalPos.pos())) {
+ return false;
+ }
+ // Luminol -end
BlockState blockState = level.getBlockStateIfLoaded(globalPos.pos()); // Paper - Prevent sync chunk loads when villagers try to find beds
if (blockState == null) { return false; } // Paper - Prevent sync chunk loads when villagers try to find beds
return globalPos.pos().closerToCenterThan(owner.position(), 2.0) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED);
diff --git a/net/minecraft/world/entity/animal/allay/AllayAi.java b/net/minecraft/world/entity/animal/allay/AllayAi.java
index 36a9887f8be04c5c3fda6d926d819a9e5b2a79f2..5681592bdeb050d875c4c5d0dfaf6e015beb1c74 100644
--- a/net/minecraft/world/entity/animal/allay/AllayAi.java
+++ b/net/minecraft/world/entity/animal/allay/AllayAi.java
@@ -114,6 +114,17 @@ public class AllayAi {
Optional<GlobalPos> memory = brain.getMemory(MemoryModuleType.LIKED_NOTEBLOCK_POSITION);
if (memory.isPresent()) {
GlobalPos globalPos = memory.get();
+ // Luminol start - Do not like item if they were out of current tickregion
+ final Level targetLevel = entity.level().getServer().getLevel(globalPos.dimension());
+ final BlockPos targetPos = globalPos.pos();
+
+ // thread checks
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(targetLevel, targetPos)) {
+ brain.eraseMemory(MemoryModuleType.LIKED_NOTEBLOCK_POSITION); // The memory value is not being belong to current tick region anymore
+ return Optional.empty();
+ }
+ // Luminol end
+
if (shouldDepositItemsAtLikedNoteblock(entity, brain, globalPos)) {
return Optional.of(new BlockPosTracker(globalPos.pos().above()));
}
diff --git a/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
index 62ca7871d1e5d0fe611948ad43e44c23fdc2d3f8..cd0fc85fbefce4669b4cb637ec3b2628da57adbf 100644
--- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -257,7 +257,17 @@ public class Sniffer extends Animal {
private boolean canDig(BlockPos pos) {
return this.level().getBlockState(pos).is(BlockTags.SNIFFER_DIGGABLE_BLOCK)
- && this.getExploredPositions().noneMatch(globalPos -> GlobalPos.of(this.level().dimension(), pos).equals(globalPos))
+ && this.getExploredPositions().noneMatch(globalPos -> { // Luminol start - Do not pathfind out of tickregion
+ // thread checks
+ final Level targetLevel = net.minecraft.server.MinecraftServer.getServer().getLevel(globalPos.dimension());
+ final BlockPos targetPos = globalPos.pos();
+
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(targetLevel, targetPos)) {
+ return false;
+ }
+
+ return GlobalPos.of(this.level().dimension(), pos).equals(globalPos); // Original logic
+ }) // Luminol end
&& Optional.ofNullable(this.getNavigation().createPath(pos, 1)).map(Path::canReach).orElse(false);
}

View File

@@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sun, 9 Mar 2025 11:39:01 +0800
Subject: [PATCH] Do not search the block out of current region
diff --git a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
index 61887e6b052bca715c90dff5d9cd657e0b3f6a78..95e2dff6782bf7767ecb1a23e618862919ea71aa 100644
--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -422,6 +422,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
if (i != 0 || i1 != 0 || allowBedrock) {
for (int y = level.getMaxY(); y > (blockPos == null ? level.getMinY() : blockPos.getY()); y--) {
BlockPos blockPos1 = new BlockPos(pos.getX() + i, y, pos.getZ() + i1);
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((Level) level, blockPos1)) continue; // Luminol - Do not search the block out of current region as we might be at the edge of the tickregion
BlockState blockState = level.getBlockState(blockPos1);
if (blockState.isCollisionShapeFullBlock(level, blockPos1) && (allowBedrock || !blockState.is(Blocks.BEDROCK))) {
blockPos = blockPos1;

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Wed, 29 Jan 2025 14:57:20 +0800
Subject: [PATCH] Skip collision check if the block is not belong to current
tick region
A temporary fix of these issues:
https://github.com/PaperMC/Folia/issues/311
Due to that mojang won't ignore the blocks the entity passed by, and sometimes the old position may not be updated and it points to a block that we don't own it, and it will access it during applyEffectsFromBlocks.So the best way to fix that is to skip the collision check of that block because it was already not owned by us and it's not necessary to check it
Related to mojang's bug fix:
https://bugs.mojang.com/browse/MC-92875
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index aa4337942b4b9b7dd746b9b9c5a052d626b1e72c..61814607a6c8e4ce8d07645f005ea8d53f624c95 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1675,6 +1675,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return;
}
+ // Luminol start - Try fixing folia's old position issue
+ if(!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.level, blockPos) && me.earthme.luminol.config.modules.fixes.FoliaOldPositionIssueFixConfig.enabled) {
+ continue;
+ }
+ // Luminol end
+
BlockState blockState = this.level().getBlockState(blockPos);
if (!blockState.isAir() && set.add(blockPos.asLong())) {
try {

View File

@@ -0,0 +1,381 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Thu, 20 Mar 2025 23:12:30 +0800
Subject: [PATCH] Revert RegionizedTaskQueue referent counter changes
diff --git a/io/papermc/paper/threadedregions/RegionizedTaskQueue.java b/io/papermc/paper/threadedregions/RegionizedTaskQueue.java
index 745ab870310733b569681f5280895bb9798620a4..9b8d06c77aa71acbe25151d82777e5dfa4e4a5f7 100644
--- a/io/papermc/paper/threadedregions/RegionizedTaskQueue.java
+++ b/io/papermc/paper/threadedregions/RegionizedTaskQueue.java
@@ -24,7 +24,7 @@ public final class RegionizedTaskQueue {
public PrioritisedExecutor.PrioritisedTask createChunkTask(final ServerLevel world, final int chunkX, final int chunkZ,
final Runnable run) {
- return this.createChunkTask(world, chunkX, chunkZ, run, Priority.NORMAL);
+ return new PrioritisedQueue.ChunkBasedPriorityTask(world.taskQueueRegionData, chunkX, chunkZ, true, run, Priority.NORMAL);
}
public PrioritisedExecutor.PrioritisedTask createChunkTask(final ServerLevel world, final int chunkX, final int chunkZ,
@@ -34,7 +34,7 @@ public final class RegionizedTaskQueue {
public PrioritisedExecutor.PrioritisedTask createTickTaskQueue(final ServerLevel world, final int chunkX, final int chunkZ,
final Runnable run) {
- return this.createTickTaskQueue(world, chunkX, chunkZ, run, Priority.NORMAL);
+ return new PrioritisedQueue.ChunkBasedPriorityTask(world.taskQueueRegionData, chunkX, chunkZ, false, run, Priority.NORMAL);
}
public PrioritisedExecutor.PrioritisedTask createTickTaskQueue(final ServerLevel world, final int chunkX, final int chunkZ,
@@ -73,7 +73,7 @@ public final class RegionizedTaskQueue {
public static final class WorldRegionTaskData {
private final ServerLevel world;
private final MultiThreadedQueue<Runnable> globalChunkTask = new MultiThreadedQueue<>();
- private final ConcurrentLong2ReferenceChainedHashTable<ReferenceCountData> referenceCounters = new ConcurrentLong2ReferenceChainedHashTable<>();
+ private final ConcurrentLong2ReferenceChainedHashTable<AtomicLong> referenceCounters = new ConcurrentLong2ReferenceChainedHashTable<>();
public WorldRegionTaskData(final ServerLevel world) {
this.world = world;
@@ -99,7 +99,7 @@ public final class RegionizedTaskQueue {
private PrioritisedQueue getQueue(final boolean synchronise, final int chunkX, final int chunkZ, final boolean isChunkTask) {
final ThreadedRegionizer<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> regioniser = this.world.regioniser;
final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region
- = synchronise ? regioniser.getRegionAtSynchronised(chunkX, chunkZ) : regioniser.getRegionAtUnsynchronised(chunkX, chunkZ);
+ = synchronise ? regioniser.getRegionAtSynchronised(chunkX, chunkZ) : regioniser.getRegionAtUnsynchronised(chunkX, chunkZ);
if (region == null) {
return null;
}
@@ -109,13 +109,13 @@ public final class RegionizedTaskQueue {
private void removeTicket(final long coord) {
this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.removeTicketAtLevel(
- TASK_QUEUE_TICKET, coord, ChunkHolderManager.MAX_TICKET_LEVEL, Unit.INSTANCE
+ TASK_QUEUE_TICKET, coord, ChunkHolderManager.MAX_TICKET_LEVEL, Unit.INSTANCE
);
}
private void addTicket(final long coord) {
this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.addTicketAtLevel(
- TASK_QUEUE_TICKET, coord, ChunkHolderManager.MAX_TICKET_LEVEL, Unit.INSTANCE
+ TASK_QUEUE_TICKET, coord, ChunkHolderManager.MAX_TICKET_LEVEL, Unit.INSTANCE
);
}
@@ -123,95 +123,96 @@ public final class RegionizedTaskQueue {
this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.processTicketUpdates(CoordinateUtils.getChunkX(coord), CoordinateUtils.getChunkZ(coord));
}
- // note: only call on acquired referenceCountData
- private void ensureTicketAdded(final long coord, final ReferenceCountData referenceCountData) {
- if (!referenceCountData.addedTicket) {
- // fine if multiple threads do this, no removeTicket may be called for this coord due to reference count inc
- this.addTicket(coord);
- this.processTicketUpdates(coord);
- referenceCountData.addedTicket = true;
+ private void decrementReference(final AtomicLong reference, final long coord) {
+ final long val = reference.decrementAndGet();
+ if (val == 0L) {
+ final int chunkX = CoordinateUtils.getChunkX(coord);
+ final int chunkZ = CoordinateUtils.getChunkZ(coord);
+ final ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock.Node ticketLock = this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.ticketLockArea.lock(chunkX, chunkZ);
+ try {
+ if (this.referenceCounters.remove(coord, reference) == reference) {
+ WorldRegionTaskData.this.removeTicket(coord);
+ } // else: race condition, something replaced our reference - not our issue anymore
+ } finally {
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.ticketLockArea.unlock(ticketLock);
+ }
+ } else if (val < 0L) {
+ throw new IllegalStateException("Reference count < 0: " + val);
}
}
- private void decrementReference(final ReferenceCountData referenceCountData, final long coord) {
- if (!referenceCountData.decreaseReferenceCount()) {
- return;
- } // else: need to remove ticket
-
- // note: it is possible that another thread increments and then removes the reference before we can, so
- // use ifPresent
- this.referenceCounters.computeIfPresent(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> {
- if (valueInMap.referenceCount.get() != 0L) {
- return valueInMap;
- }
-
- // note: valueInMap may not be referenceCountData
-
- // possible to invoke this outside of the compute call, but not required and requires additional logic
- WorldRegionTaskData.this.removeTicket(keyInMap);
+ private AtomicLong incrementReference(final long coord) {
+ final AtomicLong ret = this.referenceCounters.get(coord);
+ if (ret != null) {
+ // try to fast acquire counter
+ int failures = 0;
+ for (long curr = ret.get();;) {
+ if (curr == 0L) {
+ // failed to fast acquire as reference expired
+ break;
+ }
- return null;
- });
- }
+ for (int i = 0; i < failures; ++i) {
+ ConcurrentUtil.backoff();
+ }
- private ReferenceCountData incrementReference(final long coord) {
- ReferenceCountData referenceCountData = this.referenceCounters.get(coord);
+ if (curr == (curr = ret.compareAndExchange(curr, curr + 1L))) {
+ return ret;
+ }
- if (referenceCountData != null && referenceCountData.addCount()) {
- this.ensureTicketAdded(coord, referenceCountData);
- return referenceCountData;
+ ++failures;
+ }
}
- referenceCountData = this.referenceCounters.compute(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> {
+ // slow acquire
+ final int chunkX = CoordinateUtils.getChunkX(coord);
+ final int chunkZ = CoordinateUtils.getChunkZ(coord);
+ final ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock.Node ticketLock = this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.ticketLockArea.lock(chunkX, chunkZ);
+ final AtomicLong ret2;
+ final boolean processTicketUpdates;
+ try {
+ final AtomicLong replace = new AtomicLong(1L);
+ final AtomicLong valueInMap = this.referenceCounters.putIfAbsent(coord, replace);
if (valueInMap == null) {
- // sets reference count to 1
- return new ReferenceCountData();
- }
- // OK if we add from 0, the remove call will use compute() and catch this race condition
- valueInMap.referenceCount.getAndIncrement();
-
- return valueInMap;
- });
-
- this.ensureTicketAdded(coord, referenceCountData);
-
- return referenceCountData;
- }
- }
-
- private static final class ReferenceCountData {
-
- public final AtomicLong referenceCount = new AtomicLong(1L);
- public volatile boolean addedTicket;
+ // replaced, we should usually be here
+ this.addTicket(coord);
+ ret2 = replace;
+ processTicketUpdates = true;
+ } else {
+ processTicketUpdates = false;
+ int failures = 0;
+ for (long curr = valueInMap.get();;) {
+ if (curr == 0L) {
+ // don't need to add ticket here, since ticket is only removed during the lock
+ // we just need to replace the value in the map so that the thread removing fails and doesn't
+ // remove the ticket (see decrementReference)
+ this.referenceCounters.put(coord, replace);
+ ret2 = replace;
+ break;
+ }
- // returns false if reference count is 0, otherwise increments ref count
- public boolean addCount() {
- int failures = 0;
- for (long curr = this.referenceCount.get();;) {
- for (int i = 0; i < failures; ++i) {
- Thread.onSpinWait();
- }
+ for (int i = 0; i < failures; ++i) {
+ ConcurrentUtil.backoff();
+ }
- if (curr == 0L) {
- return false;
- }
+ if (curr == (curr = valueInMap.compareAndExchange(curr, curr + 1L))) {
+ // acquired
+ ret2 = valueInMap;
+ break;
+ }
- if (curr == (curr = this.referenceCount.compareAndExchange(curr, curr + 1L))) {
- return true;
+ ++failures;
+ }
}
-
- ++failures;
+ } finally {
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.ticketLockArea.unlock(ticketLock);
}
- }
- // returns true if new reference count is 0
- public boolean decreaseReferenceCount() {
- final long res = this.referenceCount.decrementAndGet();
- if (res >= 0L) {
- return res == 0L;
- } else {
- throw new IllegalStateException("Negative reference count");
+ if (processTicketUpdates) {
+ this.processTicketUpdates(coord);
}
+
+ return ret2;
}
}
@@ -240,10 +241,10 @@ public final class RegionizedTaskQueue {
void split(final ThreadedRegionizer<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> regioniser,
final Long2ReferenceOpenHashMap<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>> into) {
this.tickTaskQueue.split(
- false, regioniser, into
+ false, regioniser, into
);
this.chunkQueue.split(
- true, regioniser, into
+ true, regioniser, into
);
}
@@ -340,7 +341,7 @@ public final class RegionizedTaskQueue {
final ThreadedRegionizer<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> regioniser,
final Long2ReferenceOpenHashMap<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>> into) {
final Reference2ReferenceOpenHashMap<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>, ArrayDeque<ChunkBasedPriorityTask>[]>
- split = new Reference2ReferenceOpenHashMap<>();
+ split = new Reference2ReferenceOpenHashMap<>();
final int shift = regioniser.sectionChunkShift;
synchronized (this) {
this.isDestroyed = true;
@@ -356,7 +357,7 @@ public final class RegionizedTaskQueue {
final int sectionZ = task.chunkZ >> shift;
final long sectionKey = CoordinateUtils.getChunkKey(sectionX, sectionZ);
final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>
- region = into.get(sectionKey);
+ region = into.get(sectionKey);
if (region == null) {
throw new IllegalStateException();
}
@@ -378,7 +379,7 @@ public final class RegionizedTaskQueue {
iterator = split.reference2ReferenceEntrySet().fastIterator();
iterator.hasNext();) {
final Reference2ReferenceMap.Entry<ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData>, ArrayDeque<ChunkBasedPriorityTask>[]>
- entry = iterator.next();
+ entry = iterator.next();
final RegionTaskQueueData taskQueueData = entry.getKey().getData().getTaskQueueData();
mergeInto(isChunkData ? taskQueueData.chunkQueue : taskQueueData.tickTaskQueue, entry.getValue());
}
@@ -408,7 +409,7 @@ public final class RegionizedTaskQueue {
final ArrayDeque<ChunkBasedPriorityTask>[] queues = this.queues;
final int max = Priority.IDLE.priority;
ChunkBasedPriorityTask task = null;
- ReferenceCountData referenceCounter = null;
+ AtomicLong referenceCounter = null;
synchronized (this) {
if (this.isDestroyed) {
throw new IllegalStateException("Attempting to poll from dead queue");
@@ -440,10 +441,9 @@ public final class RegionizedTaskQueue {
private static final class ChunkBasedPriorityTask implements PrioritisedExecutor.PrioritisedTask {
- private static final ReferenceCountData REFERENCE_COUNTER_NOT_SET = new ReferenceCountData();
- static {
- REFERENCE_COUNTER_NOT_SET.referenceCount.set((long)Integer.MIN_VALUE);
- }
+ private static final AtomicLong REFERENCE_COUNTER_NOT_SET = new AtomicLong(-1L);
+
+
private final WorldRegionTaskData world;
private final int chunkX;
@@ -451,8 +451,8 @@ public final class RegionizedTaskQueue {
private final long sectionLowerLeftCoord; // chunk coordinate
private final boolean isChunkTask;
- private volatile ReferenceCountData referenceCounter;
- private static final VarHandle REFERENCE_COUNTER_HANDLE = ConcurrentUtil.getVarHandle(ChunkBasedPriorityTask.class, "referenceCounter", ReferenceCountData.class);
+ private volatile AtomicLong referenceCounter;
+ private static final VarHandle REFERENCE_COUNTER_HANDLE = ConcurrentUtil.getVarHandle(ChunkBasedPriorityTask.class, "referenceCounter", AtomicLong.class);
private Runnable run;
private volatile Priority priority;
private static final VarHandle PRIORITY_HANDLE = ConcurrentUtil.getVarHandle(ChunkBasedPriorityTask.class, "priority", Priority.class);
@@ -489,16 +489,16 @@ public final class RegionizedTaskQueue {
return (Priority)PRIORITY_HANDLE.compareAndExchange(this, expect, update);
}
- private void setReferenceCounterPlain(final ReferenceCountData value) {
+ private void setReferenceCounterPlain(final AtomicLong value) {
REFERENCE_COUNTER_HANDLE.set(this, value);
}
- private ReferenceCountData getReferenceCounterVolatile() {
- return (ReferenceCountData)REFERENCE_COUNTER_HANDLE.get(this);
+ private AtomicLong getReferenceCounterVolatile() {
+ return (AtomicLong)REFERENCE_COUNTER_HANDLE.get(this);
}
- private ReferenceCountData compareAndExchangeReferenceCounter(final ReferenceCountData expect, final ReferenceCountData update) {
- return (ReferenceCountData)REFERENCE_COUNTER_HANDLE.compareAndExchange(this, expect, update);
+ private AtomicLong compareAndExchangeReferenceCounter(final AtomicLong expect, final AtomicLong update) {
+ return (AtomicLong)REFERENCE_COUNTER_HANDLE.compareAndExchange(this, expect, update);
}
private void executeInternal() {
@@ -515,7 +515,7 @@ public final class RegionizedTaskQueue {
private boolean tryComplete(final boolean cancel) {
int failures = 0;
- for (ReferenceCountData curr = this.getReferenceCounterVolatile();;) {
+ for (AtomicLong curr = this.getReferenceCounterVolatile();;) {
if (curr == null) {
return false;
}
@@ -564,7 +564,7 @@ public final class RegionizedTaskQueue {
return false;
}
- final ReferenceCountData referenceCounter = this.world.incrementReference(this.sectionLowerLeftCoord);
+ final AtomicLong referenceCounter = this.world.incrementReference(this.sectionLowerLeftCoord);
if (this.compareAndExchangeReferenceCounter(REFERENCE_COUNTER_NOT_SET, referenceCounter) != REFERENCE_COUNTER_NOT_SET) {
// we don't expect race conditions here, so it is OK if we have to needlessly reference count
this.world.decrementReference(referenceCounter, this.sectionLowerLeftCoord);
@@ -614,7 +614,7 @@ public final class RegionizedTaskQueue {
}
}
- private ReferenceCountData trySetCompleting(final int minPriority) {
+ private AtomicLong trySetCompleting(final int minPriority) {
// first, try to set priority to EXECUTING
for (Priority curr = this.getPriorityVolatile();;) {
if (curr.isLowerPriority(minPriority)) {
@@ -626,7 +626,7 @@ public final class RegionizedTaskQueue {
} // else: continue
}
- for (ReferenceCountData curr = this.getReferenceCounterVolatile();;) {
+ for (AtomicLong curr = this.getReferenceCounterVolatile();;) {
if (curr == null) {
// something acquired before us
return null;
@@ -639,7 +639,6 @@ public final class RegionizedTaskQueue {
if (curr != (curr = this.compareAndExchangeReferenceCounter(curr, null))) {
continue;
}
-
return curr;
}
}
@@ -647,7 +646,7 @@ public final class RegionizedTaskQueue {
private void updatePriorityInQueue() {
boolean synchronise = false;
for (;;) {
- final ReferenceCountData referenceCount = this.getReferenceCounterVolatile();
+ final AtomicLong referenceCount = this.getReferenceCounterVolatile();
if (referenceCount == REFERENCE_COUNTER_NOT_SET || referenceCount == null) {
// cancelled or not queued
return;

View File

@@ -5,24 +5,16 @@ Subject: [PATCH] Kaiiju Vanilla end portal teleportation
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 61814607a6c8e4ce8d07645f005ea8d53f624c95..5979893976ab8c59a17e306cd91c9a4f5cd3738e 100644 index 4026d465687604965f105ded21a8206fd52bd375..8ec2b94add58d64d9b83d632427923720ec74990 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -110,6 +110,7 @@ import net.minecraft.world.level.block.Rotation; @@ -4275,14 +4275,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.border.WorldBorder;
+import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.entity.EntityAccess;
import net.minecraft.world.level.entity.EntityInLevelCallback;
import net.minecraft.world.level.gameevent.DynamicGameEventListener;
@@ -4280,13 +4281,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
targetPos, 16, // load 16 blocks to be safe from block physics targetPos, 16, // load 16 blocks to be safe from block physics
ca.spottedleaf.concurrentutil.util.Priority.HIGH, ca.spottedleaf.concurrentutil.util.Priority.HIGH,
(chunks) -> { (chunks) -> {
- net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, targetPos.below(), true, null); - net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, targetPos.below(), true, null);
-
+ //net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, targetPos.below(), true, null); // Kaiiju - Vanilla end teleportation - moved down + //net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, targetPos.below(), true, null); // Kaiiju - Vanilla end teleportation - moved down
+ // Kaiiju start - Vanilla end teleportation + // Kaiiju start - Vanilla end teleportation
+ Vec3 finalPos; + Vec3 finalPos;
+ if (this instanceof Player) finalPos = Vec3.atBottomCenterOf(targetPos.below()); + if (this instanceof Player) finalPos = Vec3.atBottomCenterOf(targetPos.below());
@@ -32,23 +24,43 @@ index 61814607a6c8e4ce8d07645f005ea8d53f624c95..5979893976ab8c59a17e306cd91c9a4f
// on the obsidian, we need to spawn at targetPos.y - 1 // on the obsidian, we need to spawn at targetPos.y - 1
portalInfoCompletable.complete( portalInfoCompletable.complete(
new net.minecraft.world.level.portal.TeleportTransition( new net.minecraft.world.level.portal.TeleportTransition(
- destination, Vec3.atBottomCenterOf(targetPos.below()), Vec3.ZERO, 90.0f, 0.0f, - destination, Vec3.atBottomCenterOf(targetPos.below()), Vec3.ZERO, Direction.WEST.toYRot(), 0.0f,
+ destination, finalPos, this.getDeltaMovement(), 90.0f, 0.0f, // Kaiiju - Vanilla end teleportation - Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)),
+ destination, finalPos, this.getDeltaMovement(), Direction.WEST.toYRot(), 0.0f, // Kaiiju - Vanilla end teleportation
+ //Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)), // Kaiiju - Vanilla end teleportation
TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET),
org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL
) )
@@ -4482,6 +4488,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4297,11 +4301,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
ca.spottedleaf.concurrentutil.util.Priority.HIGH,
(chunks) -> {
BlockPos adjustedSpawn = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, spawnPos);
-
+ // Kaiiju start - Vanilla end teleportation
+ Vec3 finalPos;
+ if (this instanceof Player) finalPos = Vec3.atBottomCenterOf(adjustedSpawn.below());
+ else finalPos = Vec3.atBottomCenterOf(adjustedSpawn);
+ // Kaiiju end
// done
portalInfoCompletable.complete(
new net.minecraft.world.level.portal.TeleportTransition(
- destination, Vec3.atBottomCenterOf(adjustedSpawn), Vec3.ZERO, 0.0f, 0.0f,
+ destination, finalPos, this.getDeltaMovement(), 0.0f, 0.0f, // Kaiiju - Vanilla end teleportation
Relative.union(Relative.DELTA, Relative.ROTATION),
TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET),
org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL
@@ -4479,6 +4487,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (!this.canPortalAsync(destination, takePassengers)) { if (!this.canPortalAsync(destination, takePassengers)) {
return false; return false;
} }
+ // Kaiiju start - sync end platform spawning & entity teleportation + // Kaiiju start - sync end platform spawning & entity teleportation
+ final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == LevelStem.END ? + final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END ?
+ e -> net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null) : teleportComplete; + e -> net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null) : teleportComplete;
+ // Kaiiju end + // Kaiiju end
Vec3 initialPosition = this.position(); Vec3 initialPosition = this.position();
ChunkPos initialPositionChunk = new ChunkPos( ChunkPos initialPositionChunk = new ChunkPos(
@@ -4546,9 +4556,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4543,9 +4555,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
info.postTeleportTransition().onTransition(teleported); info.postTeleportTransition().onTransition(teleported);
} }

View File

@@ -17,7 +17,7 @@ index c6e487a4c14e6b82533881d01f32349b9ae28728..2c747cb8a724cd25c9d724908f92b320
// block ticking // block ticking
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>(); private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index d34ad333b6ea3855a24a58fcd80ccf19b2bbf41c..ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8 100644 index 7defcd15c44601bfd2f7f55046038693264defee..5a87825606047f058df8de84bf933d216b5878b0 100644
--- a/net/minecraft/server/level/ServerLevel.java --- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java
@@ -808,6 +808,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -808,6 +808,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Petal Reduce sensor work
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index af7dbb0f2df0ec42c2c16bc58ba16b6c65d3ebcb..53e78475e721a05e9757235d0849eae3878007cd 100644 index 94a7b95f41c2954561f9c3cb0f61210c0c058f1d..dbe0fc0c46f66c61a2f286d521302719b28917c1 100644
--- a/net/minecraft/world/entity/Mob.java --- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java
@@ -866,11 +866,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @@ -866,11 +866,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab

View File

@@ -18,7 +18,7 @@ index c260741a87513b89a5cc62c543fb9f990f86491e..beb9b3b3cd5ca60bd2cdada937bff8a1
} }
if (entity instanceof final Mob mob && mob.getTarget() != null) { if (entity instanceof final Mob mob && mob.getTarget() != null) {
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index d50aef6307fb854c8d4f66bb622cdafc43dce0ae..b6c820ebdc42edc1f3ce5c18eee5bff2e3822437 100644 index 6258b008ad3e00d41e9f3014572d6f7a06b1847c..2293c3db45e9ecce4e0d4b2f87b8e90228e44d94 100644
--- a/net/minecraft/world/entity/LivingEntity.java --- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java
@@ -2044,6 +2044,20 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -2044,6 +2044,20 @@ public abstract class LivingEntity extends Entity implements Attackable {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Gale Skip entity move if movement is zero
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 4f0ea00cd601c62926220400c8e3597815dc4d15..a826320496a7a211cc07518adedfec9bdf8728b8 100644 index 8ec2b94add58d64d9b83d632427923720ec74990..3ad00cc095588574218ca6d729ead119403202e0 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -1104,7 +1104,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -1104,7 +1104,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -23,7 +23,7 @@ index 4f0ea00cd601c62926220400c8e3597815dc4d15..a826320496a7a211cc07518adedfec9b
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
// Paper start - detailed watchdog information // Paper start - detailed watchdog information
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main");
@@ -5046,6 +5053,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -5045,6 +5052,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
public final void setBoundingBox(AABB bb) { public final void setBoundingBox(AABB bb) {

View File

@@ -62,7 +62,7 @@ index ac06b8a4813716a8d136be5731cbd96113976a7e..82d95005fc67336458b50c47d44ec404
} }
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 887a12b0b33a24f77e3dc118688f9e5b14d6f62f..12f6c929c0168ea5b3242ff7139f1eac8b4e3a4b 100644 index 5a87825606047f058df8de84bf933d216b5878b0..d8e1febfa14be1c0f4869ae647bd17113660432b 100644
--- a/net/minecraft/server/level/ServerLevel.java --- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java
@@ -620,6 +620,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -620,6 +620,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sat, 8 Mar 2025 21:14:53 +0800
Subject: [PATCH] Leaf Remove useless creating stats json bases on player name
logic
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 548f7a2b0b020ff7fff27396942cc0bc9e755afe..9bf6e8240bf15f08b037b18cfeae15ebb8ea934d 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1411,6 +1411,8 @@ public abstract class PlayerList {
if (serverStatsCounter == null) {
File file = this.server.getWorldPath(LevelResource.PLAYER_STATS_DIR).toFile();
File file1 = new File(file, uuid + ".json");
+ // Leaf start - Remove useless creating stats json bases on player name logic
+ /*
if (!file1.exists()) {
File file2 = new File(file, displayName + ".json"); // CraftBukkit
Path path = file2.toPath();
@@ -1418,6 +1420,8 @@ public abstract class PlayerList {
file2.renameTo(file1);
}
}
+ */
+ // Leaf end - Remove useless creating stats json bases on player name logic
serverStatsCounter = new ServerStatsCounter(this.server, file1);
// this.stats.put(uuid, serverStatsCounter); // CraftBukkit

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sat, 8 Mar 2025 21:20:11 +0800
Subject: [PATCH] Leaf Replace brain maps with optimized collection
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index d61fba01feecce3610cd390f490d3097c5db19c4..67b71145e4feb4835a79a6007b04511a2c3b938a 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -45,14 +45,14 @@ public class Brain<E extends LivingEntity> {
static final Logger LOGGER = LogUtils.getLogger();
private final Supplier<Codec<Brain<E>>> codec;
private static final int SCHEDULE_UPDATE_DELAY = 20;
- private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newHashMap();
- private final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
+ private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // Leaf - Replace brain maps with optimized collection
+ private final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // Leaf - Replace brain maps with optimized collection
private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
private Schedule schedule = Schedule.EMPTY;
- private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
- private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = Maps.newHashMap();
- private Set<Activity> coreActivities = Sets.newHashSet();
- private final Set<Activity> activeActivities = Sets.newHashSet();
+ private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // Leaf - Replace brain maps with optimized collection
+ private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // Leaf - Replace brain maps with optimized collection
+ private Set<Activity> coreActivities = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(); // Leaf - Replace brain maps with optimized collection
+ private final Set<Activity> activeActivities = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(); // Leaf - Replace brain maps with optimized collection
private Activity defaultActivity = Activity.IDLE;
private long lastScheduleUpdate = -9999L;

View File

@@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sat, 8 Mar 2025 21:21:11 +0800
Subject: [PATCH] Leaf Paper PR: Prevent zombie reinforcements loading chunks
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
index cf231380febd6d316eb902d43c636135ee0d7fa4..731473610e068a613d67efaee08ded810fe86cf0 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -348,6 +348,13 @@ public class Zombie extends Monster {
int i2 = floor1 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
int i3 = floor2 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
BlockPos blockPos = new BlockPos(i1, i2, i3);
+
+ // Paper start - Prevent reinforcement checks from loading chunks
+ if (this.level().getChunkIfLoadedImmediately(blockPos.getX() >> 4, blockPos.getZ() >> 4) == null) {
+ continue;
+ }
+ // Paper end - Prevent reinforcement checks from loading chunks
+
if (SpawnPlacements.isSpawnPositionOk(type, level, blockPos)
&& SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.REINFORCEMENT, blockPos, level.random)) {
zombie.setPos(i1, i2, i3);

View File

@@ -19,10 +19,10 @@ index 9fd3fe181df2ce6dbe695f6463d3940ac4c01167..822d401150d3764004b2570da828b4f6
); );
}); });
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4 100644 index 3ad00cc095588574218ca6d729ead119403202e0..ccf1914b4f48ecc0f4fe980510f42d5415ec1daa 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -4166,6 +4166,31 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4160,6 +4160,31 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
// TODO any events that can modify go HERE // TODO any events that can modify go HERE
@@ -54,7 +54,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
// check for same region // check for same region
if (destination == this.level()) { if (destination == this.level()) {
@@ -4282,7 +4307,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4276,7 +4301,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// we just select the spawn position // we just select the spawn position
case END: { case END: {
if (destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END) { if (destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END) {
@@ -74,7 +74,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
// need to load chunks so we can create the platform // need to load chunks so we can create the platform
destination.moonrise$loadChunksAsync( destination.moonrise$loadChunksAsync(
targetPos, 16, // load 16 blocks to be safe from block physics targetPos, 16, // load 16 blocks to be safe from block physics
@@ -4307,7 +4343,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4301,7 +4337,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
); );
} else { } else {
@@ -94,7 +94,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
// need to load chunk for heightmap // need to load chunk for heightmap
destination.moonrise$loadChunksAsync( destination.moonrise$loadChunksAsync(
spawnPos, 0, spawnPos, 0,
@@ -4357,8 +4404,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4356,8 +4403,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
WorldBorder destinationBorder = destination.getWorldBorder(); WorldBorder destinationBorder = destination.getWorldBorder();
double dimensionScale = net.minecraft.world.level.dimension.DimensionType.getTeleportationScale(origin.dimensionType(), destination.dimensionType()); double dimensionScale = net.minecraft.world.level.dimension.DimensionType.getTeleportationScale(origin.dimensionType(), destination.dimensionType());
@@ -114,7 +114,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
ca.spottedleaf.concurrentutil.completable.CallbackCompletable<BlockUtil.FoundRectangle> portalFound ca.spottedleaf.concurrentutil.completable.CallbackCompletable<BlockUtil.FoundRectangle> portalFound
= new ca.spottedleaf.concurrentutil.completable.CallbackCompletable<>(); = new ca.spottedleaf.concurrentutil.completable.CallbackCompletable<>();
@@ -4495,9 +4552,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4494,9 +4551,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (!this.canPortalAsync(destination, takePassengers)) { if (!this.canPortalAsync(destination, takePassengers)) {
return false; return false;
} }
@@ -128,13 +128,13 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
+ } + }
+ // Luminol end + // Luminol end
// Kaiiju start - sync end platform spawning & entity teleportation // Kaiiju start - sync end platform spawning & entity teleportation
final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == LevelStem.END ? final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END ?
- e -> net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null) : teleportComplete; - e -> net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null) : teleportComplete;
+ e -> { if (new me.earthme.luminol.api.portal.EndPlatformCreateEvent().callEvent() && ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(e.level, ServerLevel.END_SPAWN_POINT.below())) net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null); } : teleportComplete; // Luminol - Add missing teleportation events & Fix teleportation api threading issue + e -> { if (new me.earthme.luminol.api.portal.EndPlatformCreateEvent().callEvent() && ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(e.level, ServerLevel.END_SPAWN_POINT.below())) net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null); } : teleportComplete; // Luminol - Add missing teleportation events & Fix teleportation api threading issue
// Kaiiju end // Kaiiju end
Vec3 initialPosition = this.position(); Vec3 initialPosition = this.position();
@@ -4571,6 +4637,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4570,6 +4636,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
tpComplete.accept(teleported); tpComplete.accept(teleported);
} }
// Kaiiju end // Kaiiju end
@@ -145,7 +145,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
); );
}); });
diff --git a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java diff --git a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
index 61887e6b052bca715c90dff5d9cd657e0b3f6a78..4f18340a99b141e15f74595282155bbd9632fb86 100644 index 95e2dff6782bf7767ecb1a23e618862919ea71aa..386c38273e21ba6b48f9fad67fddc39255138e14 100644
--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java --- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -193,6 +193,18 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -193,6 +193,18 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {

View File

@@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Suisuroru <qwertyuiop14077@qq.com>
Date: Thu, 20 Feb 2025 23:56:44 +0800
Subject: [PATCH] Leaves-Revert-raid-changes
diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java
index 80f17f33f670018240c854df589cf90cdeab6e70..7976b9ae6688b9a07b2ad19d1af3670fe06a0b63 100644
--- a/net/minecraft/world/effect/BadOmenMobEffect.java
+++ b/net/minecraft/world/effect/BadOmenMobEffect.java
@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect {
&& !serverPlayer.isSpectator()
&& level.getDifficulty() != Difficulty.PEACEFUL
&& level.isVillage(serverPlayer.blockPosition())) {
+ // Leaves start - Revert raid changes
+ if (me.earthme.luminol.config.modules.misc.RaidChangesConfig.trigger) {
+ return level.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) != null;
+ }
+ // Leaves end - Revert raid changes
Raid raidAt = level.getRaidAt(serverPlayer.blockPosition());
if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) {
serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier));
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
index 7c385baae81b9a987c0e1e4deb017884600331bc..c2afe945d6a9780ba5f8ac5d6f0b4b2d692fdd51 100644
--- a/net/minecraft/world/entity/raid/Raider.java
+++ b/net/minecraft/world/entity/raid/Raider.java
@@ -125,6 +125,43 @@ public abstract class Raider extends PatrollingMonster {
currentRaid.removeFromRaid(this, false);
}
+
+ // Leaves start - Revert raid changes
+ if (this.level() instanceof ServerLevel serverLevel) {
+ if (me.earthme.luminol.config.modules.misc.RaidChangesConfig.effect && raid == null && serverLevel.getRaidAt(this.blockPosition()) == null) {
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
+ net.minecraft.world.entity.player.Player entityhuman = null;
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
+ entityhuman = player;
+ } else if (entity instanceof net.minecraft.world.entity.animal.Wolf wolf) {
+ LivingEntity entityliving = wolf.getOwner();
+ if (wolf.isTame() && entityliving instanceof net.minecraft.world.entity.player.Player player) {
+ entityhuman = player;
+ }
+ }
+
+ if (entityhuman != null && !itemstack.isEmpty() && this.isCaptain()) {
+ net.minecraft.world.effect.MobEffectInstance mobeffect = entityhuman.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN);
+ int i = 1;
+
+ if (mobeffect != null) {
+ i += mobeffect.getAmplifier();
+ entityhuman.removeEffectNoUpdate(net.minecraft.world.effect.MobEffects.BAD_OMEN);
+ } else {
+ --i;
+ }
+
+ i = net.minecraft.util.Mth.clamp(i, 0, 4);
+ net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true);
+
+ if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_DISABLE_RAIDS)) {
+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit
+ }
+ this.setPatrolLeader(false);
+ }
+ }
+ }
+ // Leaves end - Revert raid changes
}
super.die(cause);

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Disable moved wrongly threshold
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 8c822dffc114b6aa6ddf2443606a1f9dc9262c45..60d8e9aca76614ca4ed235e96e0e9867a40e8bf5 100644 index a2fe9286d432909ba0cb3731a166514af768dc37..d60721767f94336eaba09b9bdb12a1420c264e49 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -579,7 +579,7 @@ public class ServerGamePacketListenerImpl @@ -581,7 +581,7 @@ public class ServerGamePacketListenerImpl
return; return;
} }
// Paper end - Prevent moving into unloaded chunks // Paper end - Prevent moving into unloaded chunks
@@ -17,7 +17,7 @@ index 8c822dffc114b6aa6ddf2443606a1f9dc9262c45..60d8e9aca76614ca4ed235e96e0e9867
// CraftBukkit end // CraftBukkit end
LOGGER.warn( LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5 "{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
@@ -609,7 +609,7 @@ public class ServerGamePacketListenerImpl @@ -611,7 +611,7 @@ public class ServerGamePacketListenerImpl
d5 = d2 - rootVehicle.getZ(); d5 = d2 - rootVehicle.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5; d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false; boolean flag2 = false;
@@ -26,7 +26,7 @@ index 8c822dffc114b6aa6ddf2443606a1f9dc9262c45..60d8e9aca76614ca4ed235e96e0e9867
flag2 = true; // Paper - diff on change, this should be moved wrongly flag2 = true; // Paper - diff on change, this should be moved wrongly
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7)); LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
} }
@@ -1434,7 +1434,7 @@ public class ServerGamePacketListenerImpl @@ -1437,7 +1437,7 @@ public class ServerGamePacketListenerImpl
if (this.shouldCheckPlayerMovement(isFallFlying)) { if (this.shouldCheckPlayerMovement(isFallFlying)) {
float f2 = isFallFlying ? 300.0F : 100.0F; float f2 = isFallFlying ? 300.0F : 100.0F;
@@ -35,7 +35,7 @@ index 8c822dffc114b6aa6ddf2443606a1f9dc9262c45..60d8e9aca76614ca4ed235e96e0e9867
// CraftBukkit end // CraftBukkit end
// Paper start - Add fail move event // Paper start - Add fail move event
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY,
@@ -1506,7 +1506,8 @@ public class ServerGamePacketListenerImpl @@ -1509,7 +1509,8 @@ public class ServerGamePacketListenerImpl
d5 = d2 - this.player.getZ(); d5 = d2 - this.player.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5; d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean movedWrongly = false; // Paper - Add fail move event; rename boolean movedWrongly = false; // Paper - Add fail move event; rename

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sat, 8 Feb 2025 14:25:16 +0800
Subject: [PATCH] Leaves Fix Incorrect Collision Behavior for Block Shape
diff --git a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
index 471b6d49d77e03665ffc269d17ab46f225e3ce1c..c574f9a23868a35ef694e432ba581d2f00e39da7 100644
--- a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
+++ b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
@@ -101,6 +101,14 @@ public final class CollisionUtil {
(box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON;
}
+ // Leaves start
+ public static boolean voxelShapeIntersectVanilla(final net.minecraft.world.phys.AABB box1, final net.minecraft.world.phys.AABB box2) {
+ return box1.minX < box2.maxX && box1.maxX > box2.minX &&
+ box1.minY < box2.maxY && box1.maxY > box2.minY &&
+ box1.minZ < box2.maxZ && box1.maxZ > box2.minZ;
+ }
+ // Leaves end
+
// assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON
public static double collideX(final AABB target, final AABB source, final double source_move) {
if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON &&
@@ -2026,7 +2034,10 @@ public final class CollisionUtil {
AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation();
if (singleAABB != null) {
singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ);
- if (!voxelShapeIntersect(aabb, singleAABB)) {
+ // Leaves start - Fix incorrect collision behavior for block shape
+ boolean isBlockShape = blockCollision == net.minecraft.world.phys.shapes.Shapes.block();
+ if (isBlockShape && !voxelShapeIntersectVanilla(aabb, singleAABB) || !isBlockShape && !voxelShapeIntersect(aabb, singleAABB)) {
+ // Leaves end - Fix incorrect collision behavior for block shape
continue;
}

View File

@@ -5,7 +5,6 @@ Subject: [PATCH] Raytracing tracker experiment
Based on the framework of EntityCulling((((((( Based on the framework of EntityCulling(((((((
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff717d9a86 100644 index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff717d9a86 100644
--- a/net/minecraft/server/level/ChunkMap.java --- a/net/minecraft/server/level/ChunkMap.java
@@ -20,10 +19,10 @@ index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1); double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
if (rangeY != -1) { if (rangeY != -1) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4..b1ded501047f75d2e7af775bf8866fd6a5400a91 100644 index ccf1914b4f48ecc0f4fe980510f42d5415ec1daa..ceca76a5791e319dd7cc4048c9860b1df065b95a 100644
--- a/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -136,7 +136,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
import net.minecraft.world.scores.Team; import net.minecraft.world.scores.Team;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -32,7 +31,7 @@ index 6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4..b1ded501047f75d2e7af775bf8866fd6
// CraftBukkit start // CraftBukkit start
private static final int CURRENT_LEVEL = 2; private static final int CURRENT_LEVEL = 2;
@@ -6050,4 +6050,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -6049,4 +6049,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper end - Expose entity id counter // Paper end - Expose entity id counter
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
@@ -94,7 +93,7 @@ index d9cc1d7e56c37d5ce92544edc10e89dbc89dd15d..39e7689be243b9c99b507d665f659135
public EntityType( public EntityType(
EntityType.EntityFactory<T> factory, EntityType.EntityFactory<T> factory,
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 0e020dfebe06dce4c19beb10c961ea9e8a35a415..49f927c20b84e47ed2b0e57beecb3aa746448f5a 100644 index ae049c5c3593525b991d865fec695c00ad408a59..ad34d0e1ab16fb269b3cec2842bfc2f2c29b452e 100644
--- a/net/minecraft/world/entity/player/Player.java --- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java
@@ -210,6 +210,25 @@ public abstract class Player extends LivingEntity { @@ -210,6 +210,25 @@ public abstract class Player extends LivingEntity {
@@ -150,7 +149,7 @@ index 0e020dfebe06dce4c19beb10c961ea9e8a35a415..49f927c20b84e47ed2b0e57beecb3aa7
this.noPhysics = this.isSpectator(); this.noPhysics = this.isSpectator();
if (this.isSpectator() || this.isPassenger()) { if (this.isSpectator() || this.isPassenger()) {
this.setOnGround(false); this.setOnGround(false);
@@ -1502,6 +1541,7 @@ public abstract class Player extends LivingEntity { @@ -1504,6 +1543,7 @@ public abstract class Player extends LivingEntity {
if (this.containerMenu != null && this.hasContainerOpen()) { if (this.containerMenu != null && this.hasContainerOpen()) {
this.doCloseContainer(); this.doCloseContainer();
} }

View File

@@ -0,0 +1,172 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Suisuroru <qwertyuiop14077@qq.com>
Date: Thu, 20 Feb 2025 01:00:28 +0800
Subject: [PATCH] Purpur-Barrels-and-enderchests-6-rows
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 9bf6e8240bf15f08b037b18cfeae15ebb8ea934d..79e7fcb7949fbc8e3794d481e41d5164dea0b273 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1103,6 +1103,10 @@ public abstract class PlayerList {
player.getBukkitEntity().recalculatePermissions(); // CraftBukkit
this.server.getCommands().sendCommands(player);
} // Paper - Add sendOpLevel API
+
+ // Purpur start - Barrels and enderchests 6 rows
+ player.enderChestSlotCount = me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27;
+ // Purpur end - Barrels and enderchests 6 rows
}
public boolean isWhiteListed(GameProfile profile) {
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index ad34d0e1ab16fb269b3cec2842bfc2f2c29b452e..40b91234fd2e4f4f134d309590ea6b605f764e83 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -200,6 +200,7 @@ public abstract class Player extends LivingEntity {
private int currentImpulseContextResetGraceTime;
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
+ public int enderChestSlotCount = -1; // Purpur - Barrels and enderchests 6 rows
// CraftBukkit start
public boolean fauxSleeping;
diff --git a/net/minecraft/world/inventory/ChestMenu.java b/net/minecraft/world/inventory/ChestMenu.java
index 280169afbd637eeb67ddf7eaeb4eecd464a128d5..461705345dd897c8304c884272531af836f8854f 100644
--- a/net/minecraft/world/inventory/ChestMenu.java
+++ b/net/minecraft/world/inventory/ChestMenu.java
@@ -66,10 +66,30 @@ public class ChestMenu extends AbstractContainerMenu {
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, 6);
}
+ // Purpur start - Barrels and enderchests 6 rows
+ public static ChestMenu oneRow(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x1, syncId, playerInventory, inventory, 1);
+ }
+
+ public static ChestMenu twoRows(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x2, syncId, playerInventory, inventory, 2);
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
public static ChestMenu threeRows(int containerId, Inventory playerInventory, Container container) {
return new ChestMenu(MenuType.GENERIC_9x3, containerId, playerInventory, container, 3);
}
+ // Purpur start - Barrels and enderchests 6 rows
+ public static ChestMenu fourRows(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x4, syncId, playerInventory, inventory, 4);
+ }
+
+ public static ChestMenu fiveRows(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x5, syncId, playerInventory, inventory, 5);
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
public static ChestMenu sixRows(int containerId, Inventory playerInventory, Container container) {
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
}
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
index a6a359bab2a727f4631b633a8bb370dd40decc75..5fab998cdec92a2bd965e6b48cc6189b195dc86d 100644
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
@@ -25,11 +25,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
}
public PlayerEnderChestContainer(Player owner) {
- super(27);
+ super(me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27);
this.owner = owner;
// CraftBukkit end
}
+ // Purpur start - Barrels and enderchests 6 rows
+ @Override
+ public int getContainerSize() {
+ return owner.enderChestSlotCount < 0 ? super.getContainerSize() : owner.enderChestSlotCount;
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
public void setActiveChest(EnderChestBlockEntity enderChestBlockEntity) {
this.activeChest = enderChestBlockEntity;
}
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
index f5533960708bdbaf2eacefbc7c7c3123b7d26502..bf9801f1370c8d5e6ca459207b221ef2e92dac9e 100644
--- a/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
@@ -85,8 +85,14 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
if (level instanceof ServerLevel serverLevel && player.openMenu(
new SimpleMenuProvider(
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
- )
+ (containerId, playerInventory, player1) -> switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
+ case 6 -> ChestMenu.sixRows(containerId, playerInventory, enderChestInventory);
+ case 5 -> ChestMenu.fiveRows(containerId, playerInventory, enderChestInventory);
+ case 4 -> ChestMenu.fourRows(containerId, playerInventory, enderChestInventory);
+ case 2 -> ChestMenu.twoRows(containerId, playerInventory, enderChestInventory);
+ case 1 -> ChestMenu.oneRow(containerId, playerInventory, enderChestInventory);
+ default -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory);
+ }, CONTAINER_TITLE) // Purpur - Barrels and enderchests 6 rows
).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 0f808855f58281578c2758513787f0f7330c9291..5b6ee21c21686dad86717b87c0033149cefad142 100644
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -55,7 +55,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
this.maxStack = i;
}
// CraftBukkit end
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
+ // Purpur start - Barrels and enderchests 6 rows
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ case 6 -> 54;
+ case 5 -> 45;
+ case 4 -> 36;
+ case 2 -> 18;
+ case 1 -> 9;
+ default -> 27;
+ }, ItemStack.EMPTY);
+ // Purpur end - Barrels and enderchests 6 rows
+
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
@Override
protected void onOpen(Level level, BlockPos pos, BlockState state) {
@@ -107,7 +117,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
@Override
public int getContainerSize() {
- return 27;
+ // Purpur start - Barrels and enderchests 6 rows
+ return switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ case 6 -> 54;
+ case 5 -> 45;
+ case 4 -> 36;
+ case 2 -> 18;
+ case 1 -> 9;
+ default -> 27;
+ };
+ // Purpur end - Barrels and enderchests 6 rows
}
@Override
@@ -127,7 +146,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
@Override
protected AbstractContainerMenu createMenu(int id, Inventory player) {
- return ChestMenu.threeRows(id, player, this);
+ // Purpur start - Barrels and enderchests 6 rows
+ return switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ case 6 -> ChestMenu.sixRows(id, player, this);
+ case 5 -> ChestMenu.fiveRows(id, player, this);
+ case 4 -> ChestMenu.fourRows(id, player, this);
+ case 2 -> ChestMenu.twoRows(id, player, this);
+ case 1 -> ChestMenu.oneRow(id, player, this);
+ default -> ChestMenu.threeRows(id, player, this);
+ };
+ // Purpur end - Barrels and enderchests 6 rows
}
@Override

View File

@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Mon, 24 Feb 2025 06:00:00 -0800
Subject: [PATCH] Configurable tripwire dupe
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index 9aace993c6c18f1a50610e4766225485984b8167..07ffe289b9556b45a9ef7db5357d85b14fe23feb 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -215,7 +215,7 @@ public class TripWireHookBlock extends Block {
BlockState blockState2 = blockStates[i2];
if (blockState2 != null) {
BlockState blockState3 = level.getBlockState(blockPos1);
- if (blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) {
+ if (me.earthme.luminol.config.modules.misc.AllowTripwireDupe.enabled || blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) {
if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates || !blockState3.is(Blocks.TRIPWIRE)) level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3); // Paper - prevent tripwire from updating
}
}

View File

@@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kercute <A3167717663@hotmail.com>
Date: Sun, 16 Mar 2025 23:31:41 +0800
Subject: [PATCH] Add force the data command to be enabled config
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 009e6405a11a391adca41a7c4ecafbf3254d799d..cfb37f2e428605965a37dc1eb83f302fe1bd6299 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -162,7 +162,9 @@ public class Commands {
ClearInventoryCommands.register(this.dispatcher, context);
//CloneCommands.register(this.dispatcher, context); // Folia - region threading - TODO
DamageCommand.register(this.dispatcher, context);
- //DataCommands.register(this.dispatcher); // Folia - region threading - TODO
+ if(me.earthme.luminol.config.modules.experiment.CommandDataConfig.enabled) {
+ DataCommands.register(this.dispatcher); // Folia - region threading - TODO
+ }
//DataPackCommand.register(this.dispatcher); // Folia - region threading - TODO
//DebugCommand.register(this.dispatcher); // Folia - region threading - TODO
DefaultGameModeCommands.register(this.dispatcher);

View File

@@ -0,0 +1,10 @@
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -108,6 +_,7 @@
JvmProfiler.INSTANCE.start(Environment.SERVER);
}
+ me.earthme.luminol.config.LuminolConfig.preLoadConfig(); // Luminol - Luminol config
io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
Bootstrap.bootStrap();
Bootstrap.validate();

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -212,6 +_,8 @@
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
// Paper end - initialize global and world-defaults configuration
+ me.earthme.luminol.config.LuminolConfig.finalizeLoadConfig(); //Luminol - load config file
+ me.earthme.luminol.config.LuminolConfig.setupLatch(); //Luminol - load config file
this.server.spark.enableEarlyIfRequested(); // Paper - spark
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
if (this.convertOldUsers()) {

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com> From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:17:53 +0800 Date: Tue, 11 Feb 2025 11:58:56 +0800
Subject: [PATCH] Add config for server mod name Subject: [PATCH] Add config for server mod name
@@ -17,32 +17,3 @@ index 6ed2114f577ce12d2d493985e798609c7d83f15e..7a5dcf3b7108794b9a224004730eb396
this.server = server; this.server = server;
} }
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..94e7c8910e3623163528a844fd7a08b3ffe5826b
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
@@ -0,0 +1,23 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class ServerModNameConfig implements IConfigModule {
+ @ConfigInfo(baseName = "name")
+ public static String serverModName = "Luminol";
+
+ @ConfigInfo(baseName = "vanilla_spoof")
+ public static boolean fakeVanilla = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "server_mod_name";
+ }
+}

View File

@@ -1,571 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:15:53 +0800
Subject: [PATCH] Add luminol config framework
diff --git a/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c8745dffa80cf47e856d04d283937bda86881f8
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
@@ -0,0 +1,70 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.LuminolConfig;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.Location;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LuminolConfigCommand extends Command {
+ public LuminolConfigCommand(){
+ super("luminolconfig");
+ this.setPermission("luminol.commands.luminolconfig");
+ this.setDescription("Manage config file");
+ this.setUsage("/luminolconfig");
+ }
+
+ @Override
+ public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args, @Nullable Location location) throws IllegalArgumentException {
+ final List<String> result = new ArrayList<>();
+
+ if (args.length == 1){
+ result.add("reload");
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!this.testPermission(sender)){
+ sender.sendMessage(Component
+ .text("No permission to execute this command!")
+ .color(TextColor.color(255,0,0))
+ );
+ }
+
+ if (args.length < 1){
+ sender.sendMessage(
+ Component
+ .text("Wrong use!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ return true;
+ }
+
+ switch (args[0]){
+ case "reload" -> {
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
+ Component
+ .text("Reloaded config file!")
+ .color(TextColor.color(0,255,0))
+ ));
+ }
+
+ default -> sender.sendMessage(
+ Component
+ .text("Unknown action!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ }
+
+ return true;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/ConfigInfo.java b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..01b64c2cf6b437114337626c242e1da3fbdb8ead
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
@@ -0,0 +1,11 @@
+package me.earthme.luminol.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ConfigInfo {
+ String baseName();
+
+ String comments() default "";
+}
diff --git a/src/main/java/me/earthme/luminol/config/DoNotLoad.java b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
new file mode 100644
index 0000000000000000000000000000000000000000..fffc5eb4be4b78a886f3c340bd60f3a2b0108a7d
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
@@ -0,0 +1,8 @@
+package me.earthme.luminol.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DoNotLoad {
+}
diff --git a/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java b/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b75405c468d24ed8aea5aa54ae5ac339118bf60
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java
@@ -0,0 +1,19 @@
+package me.earthme.luminol.config;
+
+public enum EnumConfigCategory {
+ OPTIMIZATIONS("optimizations"),
+ FIXES("fixes"),
+ MISC("misc"),
+ GAMEPLAY("gameplay"),
+ EXPERIMENT("experiment");
+
+ private final String baseKeyName;
+
+ EnumConfigCategory(String baseKeyName) {
+ this.baseKeyName = baseKeyName;
+ }
+
+ public String getBaseKeyName() {
+ return this.baseKeyName;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
new file mode 100644
index 0000000000000000000000000000000000000000..559c11cb523c7cade34a0abfad15c988f5ad87fe
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
@@ -0,0 +1,8 @@
+package me.earthme.luminol.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotReloadUnsupported {
+}
diff --git a/src/main/java/me/earthme/luminol/config/IConfigModule.java b/src/main/java/me/earthme/luminol/config/IConfigModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f6896711907ac30fe0c00130207b970007e4bb4
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/IConfigModule.java
@@ -0,0 +1,22 @@
+package me.earthme.luminol.config;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import org.jetbrains.annotations.NotNull;
+
+public interface IConfigModule {
+
+ EnumConfigCategory getCategory();
+
+ String getBaseName();
+
+ default void onLoaded(CommentedFileConfig configInstance) {}
+
+ default <T> T get(String keyName, T defaultValue, @NotNull CommentedFileConfig config){
+ if (!config.contains(keyName)){
+ config.set(keyName,defaultValue);
+ return defaultValue;
+ }
+
+ return config.get(keyName);
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/LuminolConfig.java b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..526b68e184a2f6f9e38cd02995b473a943404141
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
@@ -0,0 +1,226 @@
+package me.earthme.luminol.config;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import io.papermc.paper.threadedregions.RegionizedServer;
+import me.earthme.luminol.commands.LuminolConfigCommand;
+import org.bukkit.Bukkit;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class LuminolConfig {
+ public static final Logger logger = LogManager.getLogger();
+ private static final File baseConfigFolder = new File("luminol_config");
+ private static final File baseConfigFile = new File(baseConfigFolder,"luminol_global_config.toml");
+ private static final Set<IConfigModule> allInstanced = new HashSet<>();
+ private static CommentedFileConfig configFileInstance;
+ public static boolean alreadyInited = false;
+
+ public static void setupLatch(){
+ Bukkit.getCommandMap().register("luminolconfig","luminol",new LuminolConfigCommand());
+ alreadyInited = true;
+ }
+
+ public static void reload(){
+ RegionizedServer.ensureGlobalTickThread("Reload luminol config off global region thread!");
+
+ dropAllInstanced();
+ try {
+ preLoadConfig();
+ finalizeLoadConfig();
+ }catch (Exception e){
+ logger.error(e);
+ }
+ }
+
+ @Contract(" -> new")
+ public static @NotNull CompletableFuture<Void> reloadAsync(){
+ return CompletableFuture.runAsync(LuminolConfig::reload,task -> RegionizedServer.getInstance().addTask(() -> {
+ try{
+ task.run();
+ }catch (Exception e){
+ logger.error(e);
+ }
+ }));
+ }
+
+ public static void dropAllInstanced(){
+ allInstanced.clear();
+ }
+
+ public static void finalizeLoadConfig() {
+ for (IConfigModule module : allInstanced) {
+ module.onLoaded(configFileInstance);
+ }
+ }
+
+ public static void preLoadConfig() throws IOException {
+ baseConfigFolder.mkdirs();
+
+ if (!baseConfigFile.exists()){
+ baseConfigFile.createNewFile();
+ }
+
+ configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile);
+
+ configFileInstance.load();
+
+ try {
+ instanceAllModule();
+ loadAllModules();
+ }catch (Exception e){
+ logger.error("Failed to load config modules!",e);
+ throw new RuntimeException(e);
+ }
+
+ configFileInstance.save();
+ }
+
+ private static void loadAllModules() throws IllegalAccessException {
+ for (IConfigModule instanced : allInstanced){
+ loadForSingle(instanced);
+ }
+ }
+
+ private static void instanceAllModule() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
+ for (Class<?> clazz : getClasses("me.earthme.luminol.config.modules")){
+ if (IConfigModule.class.isAssignableFrom(clazz)){
+ allInstanced.add((IConfigModule) clazz.getConstructor().newInstance());
+ }
+ }
+ }
+
+ private static void loadForSingle(@NotNull IConfigModule singleConfigModule) throws IllegalAccessException {
+ final EnumConfigCategory category = singleConfigModule.getCategory();
+
+ Field[] fields = singleConfigModule.getClass().getDeclaredFields();
+
+ for (Field field : fields) {
+ int modifiers = field.getModifiers();
+ if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
+ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null || (alreadyInited && field.getAnnotation(HotReloadUnsupported.class) != null);
+ ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class);
+
+ if (skipLoad || configInfo == null){
+ continue;
+ }
+
+ final String fullConfigKeyName = category.getBaseKeyName() + "." + singleConfigModule.getBaseName() + "." + configInfo.baseName();
+
+ field.setAccessible(true);
+ final Object currentValue = field.get(null);
+
+ if (!configFileInstance.contains(fullConfigKeyName)){
+ if (currentValue == null){
+ throw new UnsupportedOperationException("Config " + singleConfigModule.getBaseName() + "tried to add an null default value!");
+ }
+
+ final String comments = configInfo.comments();
+
+ if (!comments.isBlank()){
+ configFileInstance.setComment(fullConfigKeyName,comments);
+ }
+
+ configFileInstance.add(fullConfigKeyName,currentValue);
+ continue;
+ }
+
+ final Object actuallyValue = configFileInstance.get(fullConfigKeyName);
+ field.set(null,actuallyValue);
+ }
+ }
+ }
+
+ public static @NotNull Set<Class<?>> getClasses(String pack) {
+ Set<Class<?>> classes = new LinkedHashSet<>();
+ String packageDirName = pack.replace('.', '/');
+ Enumeration<URL> dirs;
+
+ try {
+ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
+ while (dirs.hasMoreElements()) {
+ URL url = dirs.nextElement();
+ String protocol = url.getProtocol();
+ if ("file".equals(protocol)) {
+ String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
+ findClassesInPackageByFile(pack, filePath, classes);
+ } else if ("jar".equals(protocol)) {
+ JarFile jar;
+ try {
+ jar = ((JarURLConnection) url.openConnection()).getJarFile();
+ Enumeration<JarEntry> entries = jar.entries();
+ findClassesInPackageByJar(pack, entries, packageDirName, classes);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ return classes;
+ }
+
+ private static void findClassesInPackageByFile(String packageName, String packagePath, Set<Class<?>> classes) {
+ File dir = new File(packagePath);
+
+ if (!dir.exists() || !dir.isDirectory()) {
+ return;
+ }
+
+ File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"));
+ if (dirfiles != null) {
+ for (File file : dirfiles) {
+ if (file.isDirectory()) {
+ findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
+ } else {
+ String className = file.getName().substring(0, file.getName().length() - 6);
+ try {
+ classes.add(Class.forName(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+
+ private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, Set<Class<?>> classes) {
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String name = entry.getName();
+ if (name.charAt(0) == '/') {
+ name = name.substring(1);
+ }
+ if (name.startsWith(packageDirName)) {
+ int idx = name.lastIndexOf('/');
+ if (idx != -1) {
+ packageName = name.substring(0, idx).replace('/', '.');
+ }
+ if (name.endsWith(".class") && !entry.isDirectory()) {
+ String className = name.substring(packageName.length() + 1, name.length() - 6);
+ try {
+ classes.add(Class.forName(packageName + '.' + className));
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/utils/NullPlugin.java b/src/main/java/me/earthme/luminol/utils/NullPlugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..de94c8e39f0ae0da80d5a79af63413e287f5d190
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/NullPlugin.java
@@ -0,0 +1,152 @@
+package me.earthme.luminol.utils;
+
+import io.papermc.paper.plugin.configuration.PluginMeta;
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
+import org.bukkit.Server;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.generator.BiomeProvider;
+import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.plugin.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class NullPlugin extends PluginBase {
+ private boolean enabled = true;
+
+ private final String pluginName;
+ private PluginDescriptionFile pdf;
+
+ public NullPlugin() {
+ this.pluginName = "Minecraft";
+ pdf = new PluginDescriptionFile(pluginName, "1.0", "nms");
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public File getDataFolder() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public PluginDescriptionFile getDescription() {
+ return pdf;
+ }
+ // Paper start
+ @Override
+ public io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() {
+ return pdf;
+ }
+ // Paper end
+
+ @Override
+ public FileConfiguration getConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public InputStream getResource(String filename) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void saveConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void saveDefaultConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void saveResource(String resourcePath, boolean replace) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void reloadConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public PluginLogger getLogger() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public PluginLoader getPluginLoader() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public Server getServer() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void onDisable() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void onLoad() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void onEnable() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public boolean isNaggable() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void setNaggable(boolean canNag) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ // Paper start - lifecycle events
+ @Override
+ public @NotNull io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+ // Paper end - lifecycle events
+}
\ No newline at end of file

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com> From: MrHua269 <wangxyper@163.com>
Date: Wed, 29 Jan 2025 09:08:22 +0800 Date: Tue, 11 Feb 2025 12:00:30 +0800
Subject: [PATCH] Add config to disable async catchers Subject: [PATCH] Add config to disable async catchers
@@ -79,32 +79,6 @@ index c95769a4e64fabd7acdff6c5f6f349107e1cf5c0..4efa1c057ae6cfdea7889c372bd62dc1
final String ex = "Thread failed main thread check: " + final String ex = "Thread failed main thread check: " +
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ); reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
LOGGER.error(ex, new Throwable()); LOGGER.error(ex, new Throwable());
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..61f653eeca366672ded88c491cf5c59e546e7301
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class DisableAsyncCatcherConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.EXPERIMENT;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "disable_async_catchers";
+ }
+}
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
index 50f01faa88c8c658252fade3748f20e48e9c8432..36fa1f83c3286e10cc7c208a2a2f1a718d525ad8 100644 index 50f01faa88c8c658252fade3748f20e48e9c8432..36fa1f83c3286e10cc7c208a2a2f1a718d525ad8 100644
--- a/src/main/java/org/spigotmc/AsyncCatcher.java --- a/src/main/java/org/spigotmc/AsyncCatcher.java

View File

@@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 11 Feb 2025 11:57:22 +0800
Subject: [PATCH] Add tpsbar with chunkhot membar and region bar
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index de8b9048c8395c05b8688bc9d984b8ad680f15b3..f42692cd4f0154705c3d5b030d281cfc333803ed 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -437,4 +437,12 @@ public class CraftChunk implements Chunk {
static {
Arrays.fill(FULL_LIGHT, (byte) 0xFF);
}
+
+ // KioCG start - ChunkHot
+ @Override
+ public long getChunkHotAvg() {
+ final net.minecraft.world.level.chunk.LevelChunk target = this.worldServer.getChunkIfLoaded(this.x,this.z);
+ return target == null ? -1 : target.getChunkHot().getAverage();
+ }
+ // KioCG end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index c9afcd46f6a1b74b82ed68f1df6188369cf53a73..7cb95021f547c94eae7cef0bf5b2d8dff0a04937 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2404,6 +2404,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
handle.expToDrop = data.getInt("expToDrop");
handle.keepLevel = data.getBoolean("keepLevel");
}
+ //Luminol start - Tpsbar
+ getHandle().isTpsBarVisible = data.getBoolean("tpsbarVisible");
+ //Luminol end
+ //Luminol start - Membar
+ getHandle().isMemBarVisible = data.getBoolean("membarVisible");
+ //Luminol end
+ //Luminol start - Regionbar
+ getHandle().isRegionBarVisible = data.getBoolean("regionbarVisible");
+ //Luminol end
}
}
@@ -2425,6 +2434,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
data.putLong("lastPlayed", System.currentTimeMillis());
data.putString("lastKnownName", handle.getScoreboardName());
+ //Luminol start - Tpsbar
+ data.putBoolean("tpsbarVisible",handle.isTpsBarVisible);
+ //Luminol end
+ //Luminol start - Membar
+ data.putBoolean("membarVisible", handle.isMemBarVisible);
+ //Luminol end
+ //Luminol start - Regionbar
+ data.putBoolean("regionbarVisible", handle.isRegionBarVisible);
+ //Luminol end
// Paper start - persist for use in offline save data
if (!nbttagcompound.contains("Paper")) {
nbttagcompound.put("Paper", new CompoundTag());
@@ -3618,4 +3636,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setDeathScreenScore(final int score) {
getHandle().setScore(score);
}
+
+ // KioCG start - ChunkHot
+ @Override
+ public long getNearbyChunkHot() {
+ return this.getHandle().getNearbyChunkHot();
+ }
+ // KioCG end
}

View File

@@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 11 Feb 2025 12:01:39 +0800
Subject: [PATCH] Purpur Lobotomize stuck villagers
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
index bd515cdfbcc6fb0d17f70150d8b0bab60949db49..b6038fedea6251226b3b3db0f4b7a1f3d2276ab0 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
@@ -381,4 +381,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
getHandle().getGossips().gossips.clear();
}
// Paper end
+
+ // Purpur start
+ @Override
+ public boolean isLobotomized() {
+ return getHandle().isLobotomized();
+ }
+ // Purpur end
}

View File

@@ -18,10 +18,10 @@ index a0b84535a9d3833d4df692b85b272f145559dd80..c2ba46408b5ad727d7a17f21d47b2898
return; return;
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d4ede29d1 100644 index 6c2d9c9621f665412f1a8ccc41083fb0e3a07ed5..fb0ba43c8102a205d1402f53d47823672d2edfbe 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -313,7 +313,7 @@ public final class CraftServer implements Server { @@ -314,7 +314,7 @@ public final class CraftServer implements Server {
public static Exception excessiveVelEx; // Paper - Velocity warnings public static Exception excessiveVelEx; // Paper - Velocity warnings
private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes
@@ -30,7 +30,7 @@ index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d
// Paper start - Folia region threading API // 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 private final io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler(); // Folia - region threading
@@ -491,7 +491,7 @@ public final class CraftServer implements Server { @@ -492,7 +492,7 @@ public final class CraftServer implements Server {
} }
this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
@@ -39,7 +39,7 @@ index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d
} }
public boolean getCommandBlockOverride(String command) { public boolean getCommandBlockOverride(String command) {
@@ -1155,7 +1155,7 @@ public final class CraftServer implements Server { @@ -1156,7 +1156,7 @@ public final class CraftServer implements Server {
this.reloadData(); this.reloadData();
org.spigotmc.SpigotConfig.registerCommands(); // Spigot org.spigotmc.SpigotConfig.registerCommands(); // Spigot
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
@@ -48,7 +48,7 @@ index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
@@ -1184,7 +1184,7 @@ public final class CraftServer implements Server { @@ -1185,7 +1185,7 @@ public final class CraftServer implements Server {
this.loadPlugins(); this.loadPlugins();
this.enablePlugins(PluginLoadOrder.STARTUP); this.enablePlugins(PluginLoadOrder.STARTUP);
this.enablePlugins(PluginLoadOrder.POSTWORLD); this.enablePlugins(PluginLoadOrder.POSTWORLD);

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com> From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 15:35:44 +0800 Date: Tue, 11 Feb 2025 11:46:26 +0800
Subject: [PATCH] SparklyPaper Optimize canSee checks Subject: [PATCH] SparklyPaper Optimize canSee checks
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 84304fc8c26a6e1e3515b131a2ee3357262efcc3..e3fe81a1d91f60c6696070751c5220ec1868390a 100644 index 7cb95021f547c94eae7cef0bf5b2d8dff0a04937..b80795605a61cb0d7aa9fa7eec960d9a13d8c030 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -213,7 +213,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -214,7 +214,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private boolean hasPlayedBefore = false; private boolean hasPlayedBefore = false;
private final ConversationTracker conversationTracker = new ConversationTracker(); private final ConversationTracker conversationTracker = new ConversationTracker();
private final Set<String> channels = new HashSet<String>(); private final Set<String> channels = new HashSet<String>();
@@ -17,7 +17,7 @@ index 84304fc8c26a6e1e3515b131a2ee3357262efcc3..e3fe81a1d91f60c6696070751c5220ec
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>(); private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
private int hash = 0; private int hash = 0;
@@ -2267,9 +2267,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -2268,9 +2268,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override @Override
public boolean canSee(org.bukkit.entity.Entity entity) { public boolean canSee(org.bukkit.entity.Entity entity) {

View File

@@ -1,58 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:29:45 +0800
Subject: [PATCH] Add config for offline mode warning
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..502b93c7bda9e8577a1901a8777b7cf9b9bdc36b
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class OfflineModeWarningConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "warn_on_offline_mode";
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7e4724cc4ab8d911bcaf0106c098b266c843bb1
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class UsernameCheckConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "username_checks";
+ }
+}

View File

@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 11 Feb 2025 12:03:38 +0800
Subject: [PATCH] Leaf Secure seed and matter seed command
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index f42692cd4f0154705c3d5b030d281cfc333803ed..39cc976f65f826a00e2e637c139f9134c5e74715 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -206,7 +206,12 @@ public class CraftChunk implements Chunk {
@Override
public boolean isSlimeChunk() {
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
- return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ // Leaf start - Matter - Secure Seed
+ boolean isSlimeChunk = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
+ ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk()
+ : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
+ // Leaf end - Matter - Secure Seed
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index fb0ba43c8102a205d1402f53d47823672d2edfbe..d8627561b5ffec33e0c42974aa5e3d421c8cfac2 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1423,7 +1423,11 @@ public final class CraftServer implements Server {
registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess();
} else {
LevelSettings levelSettings;
- WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ // Leaf start - Matter - Secure Seed
+ WorldOptions worldOptions = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
+ ? new WorldOptions(creator.seed(), su.plo.matter.Globals.createRandomWorldSeed(), creator.generateStructures(), false)
+ : new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ // Leaf end - Matter - Secure Seed
WorldDimensions worldDimensions;
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));

View File

@@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 11 Feb 2025 11:46:44 +0800
Subject: [PATCH] Tick regions api
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 82d26889661a944e057be0c450fb5a296122ea8e..4f320a91fb8abe21cbb7b01fdc34330def5b2448 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2517,4 +2517,11 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return this.adventure$pointers;
}
// Paper end
+
+ // Luminol start - Tick regions api
+ @Override
+ public me.earthme.luminol.api.ThreadedRegionizer getThreadedRegionizer() {
+ return new me.earthme.luminol.api.impl.ThreadedRegionizerImpl(this.world);
+ }
+ // Luminol end
}

View File

@@ -1,59 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:31:09 +0800
Subject: [PATCH] Add config to verify signature only in online-mode
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..e45ce3abf49684c911678abcefd69586246cc0e3
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java
@@ -0,0 +1,21 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class PublickeyVerifyConfig implements IConfigModule {
+
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "verify_publickey_only_in_online_mode";
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/TripwireConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/TripwireConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..8def8aad908f5e6b828d7d9179bfe1962c39f9f7
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TripwireConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class TripwireConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "tripwire_dupe";
+ }
+}

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Suisuroru <qwertyuiop14077@qq.com>
Date: Thu, 20 Feb 2025 01:00:29 +0800
Subject: [PATCH] Purpur-Barrels-and-enderchests-6-rows
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
index 1ce328bed5cf3d087a3f7dc9236153381d758493..20f2b9945eaa58e05b417d9cca7c30dd0496cf72 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
@@ -145,9 +145,26 @@ public class CraftContainer extends AbstractContainerMenu {
case PLAYER:
case CHEST:
case ENDER_CHEST:
- case BARREL:
- this.delegate = new ChestMenu(net.minecraft.world.inventory.MenuType.GENERIC_9x3, windowId, bottom, top, top.getContainerSize() / 9);
+ // Purpur start - Barrels and enderchests 6 rows
+ this.delegate = new ChestMenu(switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
+ case 2 -> net.minecraft.world.inventory.MenuType.GENERIC_9x2;
+ case 1 -> net.minecraft.world.inventory.MenuType.GENERIC_9x1;
+ default -> net.minecraft.world.inventory.MenuType.GENERIC_9x3;
+ }, windowId, bottom, top, top.getContainerSize() / 9);
break;
+ case BARREL:
+ this.delegate = new ChestMenu(switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
+ case 2 -> net.minecraft.world.inventory.MenuType.GENERIC_9x2;
+ case 1 -> net.minecraft.world.inventory.MenuType.GENERIC_9x1;
+ default -> net.minecraft.world.inventory.MenuType.GENERIC_9x3;
+ }, windowId, bottom, top, top.getContainerSize() / 9);
+ // Purpur end - Barrels and enderchests 6 rows
case DISPENSER:
case DROPPER:
this.delegate = new DispenserMenu(windowId, bottom, top);
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
index c6159c70f7a37b9bffe268b91905ce848d1d2927..1ae08daecb7f072e0afaae327bad64e43c3ae027 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
@@ -84,7 +84,7 @@ public class CraftInventory implements Inventory {
@Override
public void setContents(ItemStack[] items) {
- Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize());
+ // Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize()); // Purpur - Barrels and enderchests 6 rows
for (int i = 0; i < this.getSize(); i++) {
if (i >= items.length) {

View File

@@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Wed, 29 Jan 2025 14:57:27 +0800
Subject: [PATCH] Skip collision check if the block is not belong to current
tick region
A temporary fix of these issues:
https://github.com/PaperMC/Folia/issues/311
Due to that mojang won't ignore the blocks the entity passed by, and sometimes the old position may not be updated and it points to a block that we don't own it, and it will access it during applyEffectsFromBlocks.So the best way to fix that is to skip the collision check of that block because it was already not owned by us and it's not necessary to check it
Related to mojang's bug fix:
https://bugs.mojang.com/browse/MC-92875
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaOldPositionIssueFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaOldPositionIssueFixConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..7294792d934e7374dcf335135dda739702fdcc62
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaOldPositionIssueFixConfig.java
@@ -0,0 +1,20 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class FoliaOldPositionIssueFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.FIXES;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "folia.fix_old_position_issue";
+ }
+}

View File

@@ -1,201 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Wed, 29 Jan 2025 09:12:07 +0800
Subject: [PATCH] KioCG Chunk API and display of chunkhot in tpsbar
diff --git a/src/main/java/com/kiocg/ChunkHot.java b/src/main/java/com/kiocg/ChunkHot.java
new file mode 100644
index 0000000000000000000000000000000000000000..53b4397997bc9b9b9d88e48304b37a2590161906
--- /dev/null
+++ b/src/main/java/com/kiocg/ChunkHot.java
@@ -0,0 +1,90 @@
+package com.kiocg;
+
+import java.util.Arrays;
+
+public class ChunkHot {
+ // 热度统计总区间数量
+ private static final int TIMES_LENGTH = 10;
+ // 当前统计区间下标
+ private int index = -1;
+
+ // 热度统计区间
+ private final long[] times = new long[TIMES_LENGTH];
+ // 存放临时的区间数值
+ // 用于修正正在统计的当前区间热度没有计入总值的问题
+ private long temp;
+ // 所有区间的热度总值
+ private long total;
+
+ // 用于每个具体统计的计算
+ private long nanos;
+ // 当前统计是否进行中
+ private volatile boolean started = false;
+
+ /**
+ * 更新区间下标
+ */
+ public void nextTick() {
+ this.index = ++this.index % TIMES_LENGTH;
+ }
+
+ /**
+ * 开始统计一个新区间
+ */
+ public void start() {
+ started = true;
+ temp = times[this.index];
+ times[this.index] = 0L;
+ }
+
+ public boolean isStarted(){
+ return this.started;
+ }
+
+ /**
+ * 结束当前区间的统计
+ * 将统计值更新入热度总值
+ */
+ public void stop() {
+ started = false;
+ total -= temp;
+ total += times[this.index];
+ }
+
+ /**
+ * 开始一个具体统计
+ */
+ public void startTicking() {
+ if (!started) return;
+ nanos = System.nanoTime();
+ }
+
+ /**
+ * 结束一个具体统计
+ * 将统计值计入当前热度区间
+ */
+ public void stopTickingAndCount() {
+ if (!started) return;
+ // 定义一个具体统计的最大值为 1,000,000
+ // 有时候某个具体统计的计算值会在某1刻飙升可能是由于保存数据到磁盘
+ times[this.index] += Math.min(System.nanoTime() - nanos, 1000000L);
+ }
+
+ /**
+ * 清空统计 (当区块卸载时)
+ */
+ public void clear() {
+ started = false;
+ Arrays.fill(times, 0L);
+ temp = 0L;
+ total = 0L;
+ nanos = 0L;
+ }
+
+ /**
+ * @return 获取区块热度平均值
+ */
+ public long getAverage() {
+ return total / ((long) TIMES_LENGTH * 20L);
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
index aafb2f5052c7c8e5971a47308253badb3027093c..9fe7ac7ba83bbcc9a2a851a5cace47641323f4d2 100644
--- a/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
@@ -12,11 +12,13 @@ public class TpsBarConfig implements IConfigModule {
@ConfigInfo(baseName = "enabled")
public static boolean tpsbarEnabled = false;
@ConfigInfo(baseName = "format")
- public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
+ public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms ChunkHot<yellow>:</yellow> <chunkhot>";
@ConfigInfo(baseName = "tps_color_list")
public static List<String> tpsColors = List.of("GREEN","YELLOW","RED","PURPLE");
@ConfigInfo(baseName = "ping_color_list")
public static List<String> pingColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ @ConfigInfo(baseName = "chunkhot_color_list")
+ public static List<String> chunkHotColors = List.of("GREEN","YELLOW","RED","PURPLE");
@ConfigInfo(baseName = "update_interval_ticks")
public static int updateInterval = 15;
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
index de2f03d6e771c09e8da2da454b7ec4a16c0a17ab..0b7347e8fdf995900221ee4aa4e97a4d260c6f9f 100644
--- a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
@@ -128,7 +128,8 @@ public class GlobalServerTpsBar {
TpsBarConfig.tpsBarFormat,
Placeholder.component("tps",getTpsComponent(tps)),
Placeholder.component("mspt",getMsptComponent(mspt)),
- Placeholder.component("ping",getPingComponent(player.getPing()))
+ Placeholder.component("ping",getPingComponent(player.getPing())),
+ Placeholder.component("chunkhot",getChunkHotComponent(player.getNearbyChunkHot()))
));
bar.color(barColorFromTps(tps));
bar.progress((float) Math.min((float)1,Math.max(mspt / 50,0)));
@@ -170,6 +171,32 @@ public class GlobalServerTpsBar {
return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", mspt)));
}
+ private static @NotNull Component getChunkHotComponent(long chunkHot){
+ final BossBar.Color colorBukkit = barColorFromChunkHot(chunkHot);
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.valueOf(chunkHot)));
+ }
+
+ private static BossBar.Color barColorFromChunkHot(long chunkHot){
+ if (chunkHot == -1){
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(3));
+ }
+
+ if (chunkHot <= 300000L){
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(0));
+ }
+
+ if (chunkHot <= 500000L){
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(2));
+ }
+
private static BossBar.Color barColorFromMspt(double mspt){
if (mspt == -1){
return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index de8b9048c8395c05b8688bc9d984b8ad680f15b3..f42692cd4f0154705c3d5b030d281cfc333803ed 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -437,4 +437,12 @@ public class CraftChunk implements Chunk {
static {
Arrays.fill(FULL_LIGHT, (byte) 0xFF);
}
+
+ // KioCG start - ChunkHot
+ @Override
+ public long getChunkHotAvg() {
+ final net.minecraft.world.level.chunk.LevelChunk target = this.worldServer.getChunkIfLoaded(this.x,this.z);
+ return target == null ? -1 : target.getChunkHot().getAverage();
+ }
+ // KioCG end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 03a9f4d8e83f53326c30f00286efd1ddaaac84d2..84304fc8c26a6e1e3515b131a2ee3357262efcc3 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -3611,4 +3611,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
handle.containerMenu.broadcastChanges();
return new PaperPlayerGiveResult(leftovers.build(), drops.build());
}
+
+ // KioCG start - ChunkHot
+ @Override
+ public long getNearbyChunkHot() {
+ return this.getHandle().getNearbyChunkHot();
+ }
+ // KioCG end
}

View File

@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Thu, 30 Jan 2025 08:42:31 +0800
Subject: [PATCH] Purpur Lobotomize stuck villagers
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/LobotomizeVillageConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/LobotomizeVillageConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b30546a26634361cd6eb2dbf08af9e2608a060f
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/LobotomizeVillageConfig.java
@@ -0,0 +1,24 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class LobotomizeVillageConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean villagerLobotomizeEnabled = false;
+ @ConfigInfo(baseName = "check_interval")
+ public static int villagerLobotomizeCheckInterval = 100;
+ @ConfigInfo(baseName = "wait_until_trade_locked")
+ public static boolean villagerLobotomizeWaitUntilTradeLocked = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.OPTIMIZATIONS;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "lobotomize_villager";
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
index bd515cdfbcc6fb0d17f70150d8b0bab60949db49..b6038fedea6251226b3b3db0f4b7a1f3d2276ab0 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
@@ -381,4 +381,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
getHandle().getGossips().gossips.clear();
}
// Paper end
+
+ // Purpur start
+ @Override
+ public boolean isLobotomized() {
+ return getHandle().isLobotomized();
+ }
+ // Purpur end
}

View File

@@ -1,413 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Tue, 28 Jan 2025 18:56:59 +0800
Subject: [PATCH] Leaf Secure seed and matter seed command
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/SecureSeedConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/SecureSeedConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..923e6dee55b765e46737ee145c32b767558c0132
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/SecureSeedConfig.java
@@ -0,0 +1,22 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class SecureSeedConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments = """
+ Once you enable secure seed, all ores and structures are generated with 1024-bit seed
+ instead of using 64-bit seed in vanilla, made seed cracker become impossible.""")
+ public static boolean enabled = false;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "secure_seed";
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index f42692cd4f0154705c3d5b030d281cfc333803ed..39cc976f65f826a00e2e637c139f9134c5e74715 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -206,7 +206,12 @@ public class CraftChunk implements Chunk {
@Override
public boolean isSlimeChunk() {
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
- return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ // Leaf start - Matter - Secure Seed
+ boolean isSlimeChunk = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
+ ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk()
+ : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
+ // Leaf end - Matter - Secure Seed
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index f9f20e9fd4530d0130046b56c55e798d4ede29d1..d34502a826b1582dd13c6983ed1060373837353f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1422,7 +1422,11 @@ public final class CraftServer implements Server {
registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess();
} else {
LevelSettings levelSettings;
- WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ // Leaf start - Matter - Secure Seed
+ WorldOptions worldOptions = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
+ ? new WorldOptions(creator.seed(), su.plo.matter.Globals.createRandomWorldSeed(), creator.generateStructures(), false)
+ : new WorldOptions(creator.seed(), creator.generateStructures(), false);
+ // Leaf end - Matter - Secure Seed
WorldDimensions worldDimensions;
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));
diff --git a/src/main/java/su/plo/matter/Globals.java b/src/main/java/su/plo/matter/Globals.java
new file mode 100644
index 0000000000000000000000000000000000000000..3cb89c197ca82c7f86c821fd96f6342428fff5d3
--- /dev/null
+++ b/src/main/java/su/plo/matter/Globals.java
@@ -0,0 +1,94 @@
+package su.plo.matter;
+
+import com.google.common.collect.Iterables;
+import net.minecraft.server.level.ServerLevel;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Optional;
+
+public class Globals {
+ public static final int WORLD_SEED_LONGS = 16;
+ public static final int WORLD_SEED_BITS = WORLD_SEED_LONGS * 64;
+
+ public static final long[] worldSeed = new long[WORLD_SEED_LONGS];
+ public static final ThreadLocal<Integer> dimension = ThreadLocal.withInitial(() -> 0);
+
+ public enum Salt {
+ UNDEFINED,
+ BASTION_FEATURE,
+ WOODLAND_MANSION_FEATURE,
+ MINESHAFT_FEATURE,
+ BURIED_TREASURE_FEATURE,
+ NETHER_FORTRESS_FEATURE,
+ PILLAGER_OUTPOST_FEATURE,
+ GEODE_FEATURE,
+ NETHER_FOSSIL_FEATURE,
+ OCEAN_MONUMENT_FEATURE,
+ RUINED_PORTAL_FEATURE,
+ POTENTIONAL_FEATURE,
+ GENERATE_FEATURE,
+ JIGSAW_PLACEMENT,
+ STRONGHOLDS,
+ POPULATION,
+ DECORATION,
+ SLIME_CHUNK
+ }
+
+ public static void setupGlobals(ServerLevel world) {
+ if (!me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) return;
+
+ long[] seed = world.getServer().getWorldData().worldGenOptions().featureSeed();
+ System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS);
+ int worldIndex = Iterables.indexOf(world.getServer().levelKeys(), it -> it == world.dimension());
+ if (worldIndex == -1)
+ worldIndex = world.getServer().levelKeys().size(); // if we are in world construction it may not have been added to the map yet
+ dimension.set(worldIndex);
+ }
+
+ public static long[] createRandomWorldSeed() {
+ long[] seed = new long[WORLD_SEED_LONGS];
+ SecureRandom rand = new SecureRandom();
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
+ seed[i] = rand.nextLong();
+ }
+ return seed;
+ }
+
+ // 1024-bit string -> 16 * 64 long[]
+ public static Optional<long[]> parseSeed(String seedStr) {
+ if (seedStr.isEmpty()) return Optional.empty();
+
+ if (seedStr.length() != WORLD_SEED_BITS) {
+ throw new IllegalArgumentException("Secure seed length must be " + WORLD_SEED_BITS + "-bit but found " + seedStr.length() + "-bit.");
+ }
+
+ long[] seed = new long[WORLD_SEED_LONGS];
+
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
+ int start = i * 64;
+ int end = start + 64;
+ String seedSection = seedStr.substring(start, end);
+
+ BigInteger seedInDecimal = new BigInteger(seedSection, 2);
+ seed[i] = seedInDecimal.longValue();
+ }
+
+ return Optional.of(seed);
+ }
+
+ // 16 * 64 long[] -> 1024-bit string
+ public static String seedToString(long[] seed) {
+ StringBuilder sb = new StringBuilder();
+
+ for (long longV : seed) {
+ // Convert to 64-bit binary string per long
+ // Use format to keep 64-bit length, and use 0 to complete space
+ String binaryStr = String.format("%64s", Long.toBinaryString(longV)).replace(' ', '0');
+
+ sb.append(binaryStr);
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/su/plo/matter/Hashing.java b/src/main/java/su/plo/matter/Hashing.java
new file mode 100644
index 0000000000000000000000000000000000000000..ec7a57c6af5d5f4fd27a643d253c2ecce90c01ac
--- /dev/null
+++ b/src/main/java/su/plo/matter/Hashing.java
@@ -0,0 +1,73 @@
+package su.plo.matter;
+
+public class Hashing {
+ // https://en.wikipedia.org/wiki/BLAKE_(hash_function)
+ // https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/Blake2bDigest.java
+
+ private final static long[] blake2b_IV = {
+ 0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, 0x3c6ef372fe94f82bL,
+ 0xa54ff53a5f1d36f1L, 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL,
+ 0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L
+ };
+
+ private final static byte[][] blake2b_sigma = {
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
+ {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
+ {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
+ {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
+ {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
+ {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
+ {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
+ {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
+ {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}
+ };
+
+ public static long[] hashWorldSeed(long[] worldSeed) {
+ long[] result = blake2b_IV.clone();
+ result[0] ^= 0x01010040;
+ hash(worldSeed, result, new long[16], 0, false);
+ return result;
+ }
+
+ public static void hash(long[] message, long[] chainValue, long[] internalState, long messageOffset, boolean isFinal) {
+ assert message.length == 16;
+ assert chainValue.length == 8;
+ assert internalState.length == 16;
+
+ System.arraycopy(chainValue, 0, internalState, 0, chainValue.length);
+ System.arraycopy(blake2b_IV, 0, internalState, chainValue.length, 4);
+ internalState[12] = messageOffset ^ blake2b_IV[4];
+ internalState[13] = blake2b_IV[5];
+ if (isFinal) internalState[14] = ~blake2b_IV[6];
+ internalState[15] = blake2b_IV[7];
+
+ for (int round = 0; round < 12; round++) {
+ G(message[blake2b_sigma[round][0]], message[blake2b_sigma[round][1]], 0, 4, 8, 12, internalState);
+ G(message[blake2b_sigma[round][2]], message[blake2b_sigma[round][3]], 1, 5, 9, 13, internalState);
+ G(message[blake2b_sigma[round][4]], message[blake2b_sigma[round][5]], 2, 6, 10, 14, internalState);
+ G(message[blake2b_sigma[round][6]], message[blake2b_sigma[round][7]], 3, 7, 11, 15, internalState);
+ G(message[blake2b_sigma[round][8]], message[blake2b_sigma[round][9]], 0, 5, 10, 15, internalState);
+ G(message[blake2b_sigma[round][10]], message[blake2b_sigma[round][11]], 1, 6, 11, 12, internalState);
+ G(message[blake2b_sigma[round][12]], message[blake2b_sigma[round][13]], 2, 7, 8, 13, internalState);
+ G(message[blake2b_sigma[round][14]], message[blake2b_sigma[round][15]], 3, 4, 9, 14, internalState);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ chainValue[i] ^= internalState[i] ^ internalState[i + 8];
+ }
+ }
+
+ private static void G(long m1, long m2, int posA, int posB, int posC, int posD, long[] internalState) {
+ internalState[posA] = internalState[posA] + internalState[posB] + m1;
+ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 32);
+ internalState[posC] = internalState[posC] + internalState[posD];
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE
+ internalState[posA] = internalState[posA] + internalState[posB] + m2;
+ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 16);
+ internalState[posC] = internalState[posC] + internalState[posD];
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
+ }
+}
diff --git a/src/main/java/su/plo/matter/WorldgenCryptoRandom.java b/src/main/java/su/plo/matter/WorldgenCryptoRandom.java
new file mode 100644
index 0000000000000000000000000000000000000000..fab359afe44c573b8b315115810ddefd85b4d22b
--- /dev/null
+++ b/src/main/java/su/plo/matter/WorldgenCryptoRandom.java
@@ -0,0 +1,159 @@
+package su.plo.matter;
+
+import net.minecraft.util.Mth;
+import net.minecraft.util.RandomSource;
+import net.minecraft.world.level.levelgen.LegacyRandomSource;
+import net.minecraft.world.level.levelgen.WorldgenRandom;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+public class WorldgenCryptoRandom extends WorldgenRandom {
+ // hash the world seed to guard against badly chosen world seeds
+ private static final long[] HASHED_ZERO_SEED = Hashing.hashWorldSeed(new long[Globals.WORLD_SEED_LONGS]);
+ private static final ThreadLocal<long[]> LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[Globals.WORLD_SEED_LONGS]);
+ private static final ThreadLocal<long[]> HASHED_WORLD_SEED = ThreadLocal.withInitial(() -> HASHED_ZERO_SEED);
+
+ private final long[] worldSeed = new long[Globals.WORLD_SEED_LONGS];
+ private final long[] randomBits = new long[8];
+ private int randomBitIndex;
+ private static final int MAX_RANDOM_BIT_INDEX = 64 * 8;
+ private static final int LOG2_MAX_RANDOM_BIT_INDEX = 9;
+ private long counter;
+ private final long[] message = new long[16];
+ private final long[] cachedInternalState = new long[16];
+
+ public WorldgenCryptoRandom(int x, int z, Globals.Salt typeSalt, long salt) {
+ super(new LegacyRandomSource(0L));
+ if (typeSalt != null) {
+ this.setSecureSeed(x, z, typeSalt, salt);
+ }
+ }
+
+ public void setSecureSeed(int x, int z, Globals.Salt typeSalt, long salt) {
+ System.arraycopy(Globals.worldSeed, 0, this.worldSeed, 0, Globals.WORLD_SEED_LONGS);
+ message[0] = ((long) x << 32) | ((long) z & 0xffffffffL);
+ message[1] = ((long) Globals.dimension.get() << 32) | ((long) salt & 0xffffffffL);
+ message[2] = typeSalt.ordinal();
+ message[3] = counter = 0;
+ randomBitIndex = MAX_RANDOM_BIT_INDEX;
+ }
+
+ private long[] getHashedWorldSeed() {
+ if (!Arrays.equals(worldSeed, LAST_SEEN_WORLD_SEED.get())) {
+ HASHED_WORLD_SEED.set(Hashing.hashWorldSeed(worldSeed));
+ System.arraycopy(worldSeed, 0, LAST_SEEN_WORLD_SEED.get(), 0, Globals.WORLD_SEED_LONGS);
+ }
+ return HASHED_WORLD_SEED.get();
+ }
+
+ private void moreRandomBits() {
+ message[3] = counter++;
+ System.arraycopy(getHashedWorldSeed(), 0, randomBits, 0, 8);
+ Hashing.hash(message, randomBits, cachedInternalState, 64, true);
+ }
+
+ private long getBits(int count) {
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
+ moreRandomBits();
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
+ }
+
+ int alignment = randomBitIndex & 63;
+ if ((randomBitIndex >>> 6) == ((randomBitIndex + count) >>> 6)) {
+ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << count) - 1);
+ randomBitIndex += count;
+ return result;
+ } else {
+ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << (64 - alignment)) - 1);
+ randomBitIndex += count;
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
+ moreRandomBits();
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
+ }
+ alignment = randomBitIndex & 63;
+ result <<= alignment;
+ result |= (randomBits[randomBitIndex >>> 6] >>> (64 - alignment)) & ((1L << alignment) - 1);
+
+ return result;
+ }
+ }
+
+ @Override
+ public @NotNull RandomSource fork() {
+ WorldgenCryptoRandom fork = new WorldgenCryptoRandom(0, 0, null, 0);
+
+ System.arraycopy(Globals.worldSeed, 0, fork.worldSeed, 0, Globals.WORLD_SEED_LONGS);
+ fork.message[0] = this.message[0];
+ fork.message[1] = this.message[1];
+ fork.message[2] = this.message[2];
+ fork.message[3] = this.message[3];
+ fork.randomBitIndex = this.randomBitIndex;
+ fork.counter = this.counter;
+ fork.nextLong();
+
+ return fork;
+ }
+
+ @Override
+ public int next(int bits) {
+ return (int) getBits(bits);
+ }
+
+ @Override
+ public void consumeCount(int count) {
+ randomBitIndex += count;
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX * 2) {
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
+ counter += randomBitIndex >>> LOG2_MAX_RANDOM_BIT_INDEX;
+ randomBitIndex &= MAX_RANDOM_BIT_INDEX - 1;
+ randomBitIndex += MAX_RANDOM_BIT_INDEX;
+ }
+ }
+
+ @Override
+ public int nextInt(int bound) {
+ int bits = Mth.ceillog2(bound);
+ int result;
+ do {
+ result = (int) getBits(bits);
+ } while (result >= bound);
+
+ return result;
+ }
+
+ @Override
+ public long nextLong() {
+ return getBits(64);
+ }
+
+ @Override
+ public double nextDouble() {
+ return getBits(53) * 0x1.0p-53;
+ }
+
+ @Override
+ public long setDecorationSeed(long worldSeed, int blockX, int blockZ) {
+ setSecureSeed(blockX, blockZ, Globals.Salt.POPULATION, 0);
+ return ((long) blockX << 32) | ((long) blockZ & 0xffffffffL);
+ }
+
+ @Override
+ public void setFeatureSeed(long populationSeed, int index, int step) {
+ setSecureSeed((int) (populationSeed >> 32), (int) populationSeed, Globals.Salt.DECORATION, index + 10000L * step);
+ }
+
+ @Override
+ public void setLargeFeatureSeed(long worldSeed, int chunkX, int chunkZ) {
+ super.setLargeFeatureSeed(worldSeed, chunkX, chunkZ);
+ }
+
+ @Override
+ public void setLargeFeatureWithSalt(long worldSeed, int regionX, int regionZ, int salt) {
+ super.setLargeFeatureWithSalt(worldSeed, regionX, regionZ, salt);
+ }
+
+ public static RandomSource seedSlimeChunk(int chunkX, int chunkZ) {
+ return new WorldgenCryptoRandom(chunkX, chunkZ, Globals.Salt.SLIME_CHUNK, 0);
+ }
+}

View File

@@ -1,203 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Mon, 27 Jan 2025 13:01:56 +0800
Subject: [PATCH] Tick regions api
diff --git a/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java b/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..30d4e7b6a433974c5047148f35973eb31c82d424
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java
@@ -0,0 +1,27 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.RegionStats;
+
+public class RegionStatsImpl implements RegionStats {
+ private final TickRegions.RegionStats internal;
+
+ public RegionStatsImpl(TickRegions.RegionStats internal) {
+ this.internal = internal;
+ }
+
+ @Override
+ public int getEntityCount() {
+ return this.internal.getEntityCount();
+ }
+
+ @Override
+ public int getPlayerCount() {
+ return this.internal.getPlayerCount();
+ }
+
+ @Override
+ public int getChunkCount() {
+ return this.internal.getChunkCount();
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1380abacf7bc0fe106982d9b4cd7bbc44e4e375
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java
@@ -0,0 +1,47 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.ThreadedRegion;
+import me.earthme.luminol.api.TickRegionData;
+import net.minecraft.world.level.ChunkPos;
+import org.bukkit.Location;
+import org.bukkit.World;
+
+import javax.annotation.Nullable;
+
+public class ThreadedRegionImpl implements ThreadedRegion {
+ private final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal;
+
+ public ThreadedRegionImpl(ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal) {
+ this.internal = internal;
+ }
+
+ @Nullable
+ @Override
+ public Location getCenterChunkPos() {
+ final ChunkPos centerChunkPos = this.internal.getCenterChunk();
+
+ if (centerChunkPos == null) {
+ return null;
+ }
+
+ return new Location(this.internal.regioniser.world.getWorld(), centerChunkPos.getMiddleBlockX(), 0, centerChunkPos.getMiddleBlockZ());
+ }
+
+ @Override
+ public double getDeadSectionPercent() {
+ return this.internal.getDeadSectionPercent();
+ }
+
+ @Override
+ public TickRegionData getTickRegionData() {
+ return new TickRegionDataImpl(this.internal.getData());
+ }
+
+ @Nullable
+ @Override
+ public World getWorld() {
+ return this.internal.regioniser.world.getWorld();
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..203ba60216febd8c19315afd89140d5400213f67
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java
@@ -0,0 +1,53 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.ThreadedRegion;
+import me.earthme.luminol.api.ThreadedRegionizer;
+import net.minecraft.server.level.ServerLevel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ThreadedRegionizerImpl implements ThreadedRegionizer {
+ private final ServerLevel internal;
+
+ public ThreadedRegionizerImpl(ServerLevel internal) {
+ this.internal = internal;
+ }
+
+ @Override
+ public Collection<ThreadedRegion> getAllRegions() {
+ final List<ThreadedRegion> ret = new ArrayList<>();
+
+ this.internal.regioniser.computeForAllRegions(region -> {
+ final ThreadedRegion wrapped = new ThreadedRegionImpl(region);
+
+ ret.add(wrapped);
+ });
+
+ return ret;
+ }
+
+ @Override
+ public ThreadedRegion getAtSynchronized(int chunkX, int chunkZ) {
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtSynchronised(chunkX, chunkZ);
+
+ if (got == null) {
+ return null;
+ }
+
+ return new ThreadedRegionImpl(got);
+ }
+
+ @Override
+ public ThreadedRegion getAtUnSynchronized(int chunkX, int chunkZ) {
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtUnsynchronised(chunkX, chunkZ);
+
+ if (got == null) {
+ return null;
+ }
+
+ return new ThreadedRegionImpl(got);
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java b/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf51350ccabeda97e9eff41ccd30c58e836fe041
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java
@@ -0,0 +1,30 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.RegionStats;
+import me.earthme.luminol.api.TickRegionData;
+import org.bukkit.World;
+
+public class TickRegionDataImpl implements TickRegionData {
+ private final TickRegions.TickRegionData internal;
+
+ public TickRegionDataImpl(TickRegions.TickRegionData internal) {
+ this.internal = internal;
+ }
+
+ @Override
+ public World getWorld() {
+ return this.internal.world.getWorld();
+ }
+
+ @Override
+ public long getCurrentTickCount() {
+ return this.internal.getCurrentTick();
+ }
+
+ @Override
+ public RegionStats getRegionStats() {
+ return new RegionStatsImpl(this.internal.getRegionStats());
+ }
+
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index d7973737809177b577ce029d146325194eb0831e..57944f3f12417e5727b47caad3e9d03b4720b298 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2544,4 +2544,11 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return this.adventure$pointers;
}
// Paper end
+
+ // Luminol start - Tick regions api
+ @Override
+ public me.earthme.luminol.api.ThreadedRegionizer getThreadedRegionizer() {
+ return new me.earthme.luminol.api.impl.ThreadedRegionizerImpl(this.world);
+ }
+ // Luminol end
}

View File

@@ -0,0 +1,42 @@
--- /dev/null
+++ b/src/main/java/abomination/IRegionFile.java
@@ -1,0 +_,39 @@
+package abomination;
+
+import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.level.ChunkPos;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.file.Path;
+
+public interface IRegionFile extends ChunkSystemRegionFile, AutoCloseable {
+ Path getPath();
+
+ DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException;
+
+ boolean doesChunkExist(ChunkPos pos) throws Exception;
+
+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException;
+
+ void flush() throws IOException;
+
+ void clear(ChunkPos pos) throws IOException;
+
+ boolean hasChunk(ChunkPos pos);
+
+ void close() throws IOException;
+
+ void write(ChunkPos pos, ByteBuffer buf) throws IOException;
+
+ CompoundTag getOversizedData(int x, int z) throws IOException;
+
+ boolean isOversized(int x, int z);
+
+ boolean recalculateHeader() throws IOException;
+
+ void setOversized(int x, int z, boolean oversized) throws IOException;
+}

View File

@@ -1,61 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 10:49:22 +0800
Subject: [PATCH] Add configurable region format framework & linear v2 region
format support
diff --git a/src/main/java/abomination/IRegionFile.java b/src/main/java/abomination/IRegionFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..fda43a34c89d75e3036f14da3c6efcf157189b22
--- /dev/null
+++ b/src/main/java/abomination/IRegionFile.java
@@ -0,0 +1,39 @@
+package abomination;
+
+import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.level.ChunkPos;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.file.Path;
+
+public interface IRegionFile extends ChunkSystemRegionFile, AutoCloseable {
+ Path getPath();
+
+ DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException;
+
+ boolean doesChunkExist(ChunkPos pos) throws Exception;
+
+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException;
+
+ void flush() throws IOException;
+
+ void clear(ChunkPos pos) throws IOException;
+
+ boolean hasChunk(ChunkPos pos);
+
+ void close() throws IOException;
+
+ void write(ChunkPos pos, ByteBuffer buf) throws IOException;
+
+ CompoundTag getOversizedData(int x, int z) throws IOException;
+
+ boolean isOversized(int x, int z);
+
+ boolean recalculateHeader() throws IOException;
+
+ void setOversized(int x, int z, boolean oversized) throws IOException;
+}
diff --git a/src/main/java/abomination/LinearRegionFile.java b/src/main/java/abomination/LinearRegionFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb0fcf5f47b5ae3d86e1d0572f951236afdcd017
--- /dev/null --- /dev/null
+++ b/src/main/java/abomination/LinearRegionFile.java +++ b/src/main/java/abomination/LinearRegionFile.java
@@ -0,0 +1,622 @@ @@ -1,0 +_,622 @@
+package abomination; +package abomination;
+ +
+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
@@ -678,142 +623,3 @@ index 0000000000000000000000000000000000000000..bb0fcf5f47b5ae3d86e1d0572f951236
+ } + }
+ } + }
+} +}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb689b6b79143ffaf1eadcba84feca0c632d1407
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java
@@ -0,0 +1,59 @@
+package me.earthme.luminol.config.modules.misc;
+
+import abomination.LinearRegionFile;
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.config.*;
+import me.earthme.luminol.utils.EnumRegionFormat;
+import net.minecraft.server.MinecraftServer;
+
+public class RegionFormatConfig implements IConfigModule {
+ @HotReloadUnsupported
+ @ConfigInfo(baseName = "format")
+ public static String format = "MCA";
+ @HotReloadUnsupported
+ @ConfigInfo(baseName = "linear_compression_level")
+ public static int linearCompressionLevel = 1;
+ @HotReloadUnsupported
+ @ConfigInfo(baseName = "linear_io_thread_count")
+ public static int linearIoThreadCount = 6;
+ @HotReloadUnsupported
+ @ConfigInfo(baseName = "linear_io_flush_delay_ms")
+ public static int linearIoFlushDelayMs = 100;
+ @HotReloadUnsupported
+ @ConfigInfo(baseName = "linear_use_virtual_thread")
+ public static boolean linearUseVirtualThread = true;
+
+ @DoNotLoad
+ public static EnumRegionFormat regionFormat;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "region_format";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance) {
+ regionFormat = EnumRegionFormat.fromString(format.toUpperCase());
+
+ if (regionFormat == null) {
+ throw new RuntimeException("Invalid region format: " + format);
+ }
+
+ if (regionFormat == EnumRegionFormat.LINEAR_V2) {
+ if (RegionFormatConfig.linearCompressionLevel > 23 || RegionFormatConfig.linearCompressionLevel < 1) {
+ MinecraftServer.LOGGER.error("Linear region compression level should be between 1 and 22 in config: {}", RegionFormatConfig.linearCompressionLevel);
+ MinecraftServer.LOGGER.error("Falling back to compression level 1.");
+ RegionFormatConfig.linearCompressionLevel = 1;
+ }
+
+ LinearRegionFile.SAVE_DELAY_MS = linearIoFlushDelayMs;
+ LinearRegionFile.SAVE_THREAD_MAX_COUNT = linearIoThreadCount;
+ LinearRegionFile.USE_VIRTUAL_THREAD = linearUseVirtualThread;
+ }
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/utils/EnumRegionFormat.java b/src/main/java/me/earthme/luminol/utils/EnumRegionFormat.java
new file mode 100644
index 0000000000000000000000000000000000000000..73b4f9b5f608322839cf1e37fbf1d3a147247c60
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/EnumRegionFormat.java
@@ -0,0 +1,40 @@
+package me.earthme.luminol.utils;
+
+import abomination.LinearRegionFile;
+import me.earthme.luminol.config.modules.misc.RegionFormatConfig;
+import net.minecraft.world.level.chunk.storage.RegionFile;
+import org.jetbrains.annotations.Nullable;
+
+public enum EnumRegionFormat {
+ MCA("mca", "mca" , (info) -> new RegionFile(info.info(), info.filePath(), info.folder(), info.sync())),
+ LINEAR_V2("linear_v2", "linear" ,(info) -> new LinearRegionFile(info.info(), info.filePath(), info.folder(), info.sync(), RegionFormatConfig.linearCompressionLevel));
+
+ private final String name;
+ private final String argument;
+ private final IRegionCreateFunction creator;
+
+ EnumRegionFormat(String name, String argument, IRegionCreateFunction creator) {
+ this.name = name;
+ this.argument = argument;
+ this.creator = creator;
+ }
+
+ @Nullable
+ public static EnumRegionFormat fromString(String string) {
+ for (EnumRegionFormat format : values()) {
+ if (format.name.equalsIgnoreCase(string)) {
+ return format;
+ }
+ }
+
+ return null;
+ }
+
+ public IRegionCreateFunction getCreator() {
+ return this.creator;
+ }
+
+ public String getArgument() {
+ return this.argument;
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/utils/IRegionCreateFunction.java b/src/main/java/me/earthme/luminol/utils/IRegionCreateFunction.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb87ef13803122aa5a2e7f0c578de359140d4f31
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/IRegionCreateFunction.java
@@ -0,0 +1,9 @@
+package me.earthme.luminol.utils;
+
+import abomination.IRegionFile;
+
+import java.io.IOException;
+
+public interface IRegionCreateFunction {
+ IRegionFile create(RegionCreatorInfo info) throws IOException;
+}
diff --git a/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java b/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..5af068489646ed70330d8c6242ec88f536c4c289
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java
@@ -0,0 +1,7 @@
+package me.earthme.luminol.utils;
+
+import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
+
+import java.nio.file.Path;
+
+public record RegionCreatorInfo (RegionStorageInfo info, Path filePath, Path folder, boolean sync) {}

View File

@@ -0,0 +1,93 @@
--- /dev/null
+++ b/src/main/java/com/kiocg/ChunkHot.java
@@ -1,0 +_,90 @@
+package com.kiocg;
+
+import java.util.Arrays;
+
+public class ChunkHot {
+ // 热度统计总区间数量
+ private static final int TIMES_LENGTH = 10;
+ // 当前统计区间下标
+ private int index = -1;
+
+ // 热度统计区间
+ private final long[] times = new long[TIMES_LENGTH];
+ // 存放临时的区间数值
+ // 用于修正正在统计的当前区间热度没有计入总值的问题
+ private long temp;
+ // 所有区间的热度总值
+ private long total;
+
+ // 用于每个具体统计的计算
+ private long nanos;
+ // 当前统计是否进行中
+ private volatile boolean started = false;
+
+ /**
+ * 更新区间下标
+ */
+ public void nextTick() {
+ this.index = ++this.index % TIMES_LENGTH;
+ }
+
+ /**
+ * 开始统计一个新区间
+ */
+ public void start() {
+ started = true;
+ temp = times[this.index];
+ times[this.index] = 0L;
+ }
+
+ public boolean isStarted(){
+ return this.started;
+ }
+
+ /**
+ * 结束当前区间的统计
+ * 将统计值更新入热度总值
+ */
+ public void stop() {
+ started = false;
+ total -= temp;
+ total += times[this.index];
+ }
+
+ /**
+ * 开始一个具体统计
+ */
+ public void startTicking() {
+ if (!started) return;
+ nanos = System.nanoTime();
+ }
+
+ /**
+ * 结束一个具体统计
+ * 将统计值计入当前热度区间
+ */
+ public void stopTickingAndCount() {
+ if (!started) return;
+ // 定义一个具体统计的最大值为 1,000,000
+ // 有时候某个具体统计的计算值会在某1刻飙升可能是由于保存数据到磁盘
+ times[this.index] += Math.min(System.nanoTime() - nanos, 1000000L);
+ }
+
+ /**
+ * 清空统计 (当区块卸载时)
+ */
+ public void clear() {
+ started = false;
+ Arrays.fill(times, 0L);
+ temp = 0L;
+ total = 0L;
+ nanos = 0L;
+ }
+
+ /**
+ * @return 获取区块热度平均值
+ */
+ public long getAverage() {
+ return total / ((long) TIMES_LENGTH * 20L);
+ }
+}

View File

@@ -0,0 +1,37 @@
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java
@@ -1,0 +_,34 @@
+package com.logisticscraft.occlusionculling;
+
+import com.logisticscraft.occlusionculling.util.Vec3d;
+
+public interface DataProvider {
+
+ /**
+ * Prepares the requested chunk. Returns true if the chunk is ready, false when
+ * not loaded. Should not reload the chunk when the x and y are the same as the
+ * last request!
+ *
+ * @param chunkX
+ * @param chunkZ
+ * @return
+ */
+ boolean prepareChunk(int chunkX, int chunkZ);
+
+ /**
+ * Location is inside the chunk.
+ *
+ * @param x
+ * @param y
+ * @param z
+ * @return
+ */
+ boolean isOpaqueFullCube(int x, int y, int z);
+
+ default void cleanup() {
+ }
+
+ default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
+ }
+
+}

View File

@@ -1,57 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Wed, 5 Feb 2025 15:22:21 +0800
Subject: [PATCH] Raytracing tracker experiment
Based on the framework of EntityCulling(((((((
diff --git a/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ab4600554e8dcb2a2ddc22dd1c1015c89ba5b82
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java
@@ -0,0 +1,34 @@
+package com.logisticscraft.occlusionculling;
+
+import com.logisticscraft.occlusionculling.util.Vec3d;
+
+public interface DataProvider {
+
+ /**
+ * Prepares the requested chunk. Returns true if the chunk is ready, false when
+ * not loaded. Should not reload the chunk when the x and y are the same as the
+ * last request!
+ *
+ * @param chunkX
+ * @param chunkZ
+ * @return
+ */
+ boolean prepareChunk(int chunkX, int chunkZ);
+
+ /**
+ * Location is inside the chunk.
+ *
+ * @param x
+ * @param y
+ * @param z
+ * @return
+ */
+ boolean isOpaqueFullCube(int x, int y, int z);
+
+ default void cleanup() {
+ }
+
+ default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
+ }
+
+}
diff --git a/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java
new file mode 100644
index 0000000000000000000000000000000000000000..30efa77d8ed337e9f044c41a10c6ecfd5ec162e2
--- /dev/null --- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java +++ b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java
@@ -0,0 +1,515 @@ @@ -1,0 +_,515 @@
+package com.logisticscraft.occlusionculling; +package com.logisticscraft.occlusionculling;
+ +
+import java.util.Arrays; +import java.util.Arrays;
@@ -567,477 +516,3 @@ index 0000000000000000000000000000000000000000..30efa77d8ed337e9f044c41a10c6ecfd
+ } + }
+ +
+} +}
diff --git a/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..08f0ddb343c12ac781ee33f1a7da1462573405b9
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java
@@ -0,0 +1,57 @@
+package com.logisticscraft.occlusionculling.cache;
+
+import java.util.Arrays;
+
+public class ArrayOcclusionCache implements OcclusionCache {
+
+ private final int reachX2;
+ private final byte[] cache;
+ private int positionKey;
+ private int entry;
+ private int offset;
+
+ public ArrayOcclusionCache(int reach) {
+ this.reachX2 = reach * 2;
+ this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4];
+ }
+
+ @Override
+ public void resetCache() {
+ Arrays.fill(cache, (byte) 0);
+ }
+
+ @Override
+ public void setVisible(int x, int y, int z) {
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
+ entry = positionKey / 4;
+ offset = (positionKey % 4) * 2;
+ cache[entry] |= 1 << offset;
+ }
+
+ @Override
+ public void setHidden(int x, int y, int z) {
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
+ entry = positionKey / 4;
+ offset = (positionKey % 4) * 2;
+ cache[entry] |= 1 << offset + 1;
+ }
+
+ @Override
+ public int getState(int x, int y, int z) {
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
+ entry = positionKey / 4;
+ offset = (positionKey % 4) * 2;
+ return cache[entry] >> offset & 3;
+ }
+
+ @Override
+ public void setLastVisible() {
+ cache[entry] |= 1 << offset;
+ }
+
+ @Override
+ public void setLastHidden() {
+ cache[entry] |= 1 << offset + 1;
+ }
+
+}
diff --git a/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a2e5620fb2b1a71fbca2068fc049bfa89a47737
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java
@@ -0,0 +1,17 @@
+package com.logisticscraft.occlusionculling.cache;
+
+public interface OcclusionCache {
+
+ void resetCache();
+
+ void setVisible(int x, int y, int z);
+
+ void setHidden(int x, int y, int z);
+
+ int getState(int x, int y, int z);
+
+ void setLastHidden();
+
+ void setLastVisible();
+
+}
diff --git a/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb28265631b079eb5da8ae3a7ecca6e343f8c0b6
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java
@@ -0,0 +1,25 @@
+package com.logisticscraft.occlusionculling.util;
+
+/**
+ * Contains MathHelper methods
+ */
+public final class MathUtilities {
+
+ private MathUtilities() {
+ }
+
+ public static int floor(double d) {
+ int i = (int) d;
+ return d < (double) i ? i - 1 : i;
+ }
+
+ public static int fastFloor(double d) {
+ return (int) (d + 1024.0) - 1024;
+ }
+
+ public static int ceil(double d) {
+ int i = (int) d;
+ return d > (double) i ? i + 1 : i;
+ }
+
+}
diff --git a/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e3cb9e11f65af0627164c8dbd6aad3e5690d36c
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java
@@ -0,0 +1,87 @@
+package com.logisticscraft.occlusionculling.util;
+
+public class Vec3d {
+
+ public double x;
+ public double y;
+ public double z;
+
+ public Vec3d(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public double getZ() {
+ return z;
+ }
+
+ public void set(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public void setAdd(Vec3d vec, double x, double y, double z) {
+ this.x = vec.x + x;
+ this.y = vec.y + y;
+ this.z = vec.z + z;
+ }
+
+ public Vec3d div(Vec3d rayDir) {
+ this.x /= rayDir.x;
+ this.z /= rayDir.z;
+ this.y /= rayDir.y;
+ return this;
+ }
+
+ public Vec3d normalize() {
+ double mag = Math.sqrt(x*x+y*y+z*z);
+ this.x /= mag;
+ this.y /= mag;
+ this.z /= mag;
+ return this;
+ }
+
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof Vec3d)) {
+ return false;
+ }
+ Vec3d vec3d = (Vec3d) other;
+ if (Double.compare(vec3d.x, x) != 0) {
+ return false;
+ }
+ if (Double.compare(vec3d.y, y) != 0) {
+ return false;
+ }
+ return Double.compare(vec3d.z, z) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ long l = Double.doubleToLongBits(x);
+ int i = (int) (l ^ l >>> 32);
+ l = Double.doubleToLongBits(y);
+ i = 31 * i + (int) (l ^ l >>> 32);
+ l = Double.doubleToLongBits(z);
+ i = 31 * i + (int) (l ^ l >>> 32);
+ return i;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+
+}
diff --git a/src/main/java/dev/tr7zw/entityculling/CullTask.java b/src/main/java/dev/tr7zw/entityculling/CullTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..57e36d4a2c770a3d2ae72a78e69802dd119e6999
--- /dev/null
+++ b/src/main/java/dev/tr7zw/entityculling/CullTask.java
@@ -0,0 +1,152 @@
+package dev.tr7zw.entityculling;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import ca.spottedleaf.moonrise.common.util.TickThread;
+import com.logisticscraft.occlusionculling.OcclusionCullingInstance;
+import com.logisticscraft.occlusionculling.util.Vec3d;
+
+import dev.tr7zw.entityculling.versionless.access.Cullable;
+import me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.decoration.ArmorStand;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.phys.AABB;
+import net.minecraft.world.phys.Vec3;
+
+public class CullTask implements Runnable {
+
+ private volatile boolean requestCull = false;
+ private volatile boolean scheduleNext = true;
+ private volatile boolean inited = false;
+
+ private final OcclusionCullingInstance culling;
+ private final Player checkTarget;
+
+ private final int hitboxLimit;
+
+ public long lastCheckedTime = 0;
+
+ // reused preallocated vars
+ private final Vec3d lastPos = new Vec3d(0, 0, 0);
+ private final Vec3d aabbMin = new Vec3d(0, 0, 0);
+ private final Vec3d aabbMax = new Vec3d(0, 0, 0);
+
+ private static final Executor backgroundWorker = Executors.newCachedThreadPool(task -> {
+ final TickThread worker = new TickThread("EntityCulling") {
+ @Override
+ public void run() {
+ task.run();
+ }
+ };
+
+ worker.setDaemon(true);
+
+ return worker;
+ });
+
+ private final Executor worker;
+
+ public CullTask(
+ OcclusionCullingInstance culling,
+ Player checkTarget,
+ int hitboxLimit,
+ long checkIntervalMs
+ ) {
+ this.culling = culling;
+ this.checkTarget = checkTarget;
+ this.hitboxLimit = hitboxLimit;
+ this.worker = CompletableFuture.delayedExecutor(checkIntervalMs, TimeUnit.MILLISECONDS, backgroundWorker);
+ }
+
+ public void requestCullSignal() {
+ this.requestCull = true;
+ }
+
+ public void signalStop() {
+ this.scheduleNext = false;
+ }
+
+ public void setup() {
+ if (!this.inited)
+ this.inited = true;
+ else
+ return;
+ this.worker.execute(this);
+ }
+
+ @Override
+ public void run() {
+ try {
+ if (this.checkTarget.tickCount > 10) {
+ // getEyePosition can use a fixed delta as its debug only anyway
+ Vec3 cameraMC = this.checkTarget.getEyePosition(0);
+ if (requestCull || !(cameraMC.x == lastPos.x && cameraMC.y == lastPos.y && cameraMC.z == lastPos.z)) {
+ long start = System.currentTimeMillis();
+
+ requestCull = false;
+
+ lastPos.set(cameraMC.x, cameraMC.y, cameraMC.z);
+ culling.resetCache();
+
+ cullEntities(cameraMC, lastPos);
+
+ lastCheckedTime = (System.currentTimeMillis() - start);
+ }
+ }
+ }finally {
+ if (this.scheduleNext) {
+ this.worker.execute(this);
+ }
+ }
+ }
+
+ private void cullEntities(Vec3 cameraMC, Vec3d camera) {
+ for (Entity entity : this.checkTarget.level().getEntities().getAll()) {
+ if (!(entity instanceof Cullable cullable)) {
+ continue; // Not sure how this could happen outside from mixin screwing up the inject into
+ // Entity
+ }
+
+ if (entity.getType().skipRaytracningCheck) {
+ continue;
+ }
+
+ if (!cullable.isForcedVisible()) {
+ if (entity.isCurrentlyGlowing() || isSkippableArmorstand(entity)) {
+ cullable.setCulled(false);
+ continue;
+ }
+
+ if (!entity.position().closerThan(cameraMC, me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance)) {
+ cullable.setCulled(false); // If your entity view distance is larger than tracingDistance just
+ // render it
+ continue;
+ }
+
+ AABB boundingBox = entity.getBoundingBox();
+ if (boundingBox.getXsize() > hitboxLimit || boundingBox.getYsize() > hitboxLimit
+ || boundingBox.getZsize() > hitboxLimit) {
+ cullable.setCulled(false); // To big to bother to cull
+ continue;
+ }
+
+ aabbMin.set(boundingBox.minX, boundingBox.minY, boundingBox.minZ);
+ aabbMax.set(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ);
+
+ boolean visible = culling.isAABBVisible(aabbMin, aabbMax, camera);
+
+ cullable.setCulled(!visible);
+ }
+ }
+ }
+
+ private boolean isSkippableArmorstand(Entity entity) {
+ if (!RayTrackingEntityTrackerConfig.skipMarkerArmorStands)
+ return false;
+ return entity instanceof ArmorStand && entity.isInvisible();
+ }
+}
diff --git a/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java b/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..aadf7cdc4a28ecf92853e147fa115d43c89f6fe8
--- /dev/null
+++ b/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java
@@ -0,0 +1,43 @@
+package dev.tr7zw.entityculling;
+
+import com.logisticscraft.occlusionculling.DataProvider;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.chunk.ChunkAccess;
+import net.minecraft.world.level.chunk.status.ChunkStatus;
+
+public class DefaultChunkDataProvider implements DataProvider {
+ private final Level level;
+
+ public DefaultChunkDataProvider(Level level) {
+ this.level = level;
+ }
+
+ @Override
+ public boolean prepareChunk(int chunkX, int chunkZ) {
+ return this.level.getChunkIfLoaded(chunkX, chunkZ) != null;
+ }
+
+ @Override
+ public boolean isOpaqueFullCube(int x, int y, int z) {
+ BlockPos pos = new BlockPos(x, y, z);
+
+ final ChunkAccess access = this.level.getChunkIfLoaded(pos);
+ if (access == null) {
+ return false;
+ }
+
+ if (this.level.isOutsideBuildHeight(pos)) {
+ return Blocks.VOID_AIR.defaultBlockState().isSolidRender();
+ } else {
+ return access.getBlockState(pos).isSolidRender();// 好孩子不要学坏叔叔这样绕过异步拦截()
+ }
+ }
+
+ @Override
+ public void cleanup() {
+ DataProvider.super.cleanup();
+ }
+
+}
diff --git a/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java b/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java
new file mode 100644
index 0000000000000000000000000000000000000000..948e8e934793532704161e0a129ebf86355ba5a8
--- /dev/null
+++ b/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java
@@ -0,0 +1,17 @@
+package dev.tr7zw.entityculling.versionless.access;
+
+public interface Cullable {
+
+ public void setTimeout();
+
+ public boolean isForcedVisible();
+
+ public void setCulled(boolean value);
+
+ public boolean isCulled();
+
+ public void setOutOfCamera(boolean value);
+
+ public boolean isOutOfCamera();
+
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/RayTrackingEntityTrackerConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/RayTrackingEntityTrackerConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e3e6a500c9eb26a06f5441f9e542dc9b1ad0cf4
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/RayTrackingEntityTrackerConfig.java
@@ -0,0 +1,28 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class RayTrackingEntityTrackerConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+ @ConfigInfo(baseName = "skip_marker_armor_stands")
+ public static boolean skipMarkerArmorStands = true;
+ @ConfigInfo(baseName = "check_interval_ms")
+ public static int checkIntervalMs = 10;
+ @ConfigInfo(baseName = "tracing_distance")
+ public static int tracingDistance = 48;
+ @ConfigInfo(baseName = "hitbox_limit")
+ public static int hitboxLimit = 50;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.EXPERIMENT;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "ray_tracking_entity_tracker";
+ }
+}

View File

@@ -0,0 +1,60 @@
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java
@@ -1,0 +_,57 @@
+package com.logisticscraft.occlusionculling.cache;
+
+import java.util.Arrays;
+
+public class ArrayOcclusionCache implements OcclusionCache {
+
+ private final int reachX2;
+ private final byte[] cache;
+ private int positionKey;
+ private int entry;
+ private int offset;
+
+ public ArrayOcclusionCache(int reach) {
+ this.reachX2 = reach * 2;
+ this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4];
+ }
+
+ @Override
+ public void resetCache() {
+ Arrays.fill(cache, (byte) 0);
+ }
+
+ @Override
+ public void setVisible(int x, int y, int z) {
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
+ entry = positionKey / 4;
+ offset = (positionKey % 4) * 2;
+ cache[entry] |= 1 << offset;
+ }
+
+ @Override
+ public void setHidden(int x, int y, int z) {
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
+ entry = positionKey / 4;
+ offset = (positionKey % 4) * 2;
+ cache[entry] |= 1 << offset + 1;
+ }
+
+ @Override
+ public int getState(int x, int y, int z) {
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
+ entry = positionKey / 4;
+ offset = (positionKey % 4) * 2;
+ return cache[entry] >> offset & 3;
+ }
+
+ @Override
+ public void setLastVisible() {
+ cache[entry] |= 1 << offset;
+ }
+
+ @Override
+ public void setLastHidden() {
+ cache[entry] |= 1 << offset + 1;
+ }
+
+}

View File

@@ -0,0 +1,20 @@
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java
@@ -1,0 +_,17 @@
+package com.logisticscraft.occlusionculling.cache;
+
+public interface OcclusionCache {
+
+ void resetCache();
+
+ void setVisible(int x, int y, int z);
+
+ void setHidden(int x, int y, int z);
+
+ int getState(int x, int y, int z);
+
+ void setLastHidden();
+
+ void setLastVisible();
+
+}

View File

@@ -0,0 +1,28 @@
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java
@@ -1,0 +_,25 @@
+package com.logisticscraft.occlusionculling.util;
+
+/**
+ * Contains MathHelper methods
+ */
+public final class MathUtilities {
+
+ private MathUtilities() {
+ }
+
+ public static int floor(double d) {
+ int i = (int) d;
+ return d < (double) i ? i - 1 : i;
+ }
+
+ public static int fastFloor(double d) {
+ return (int) (d + 1024.0) - 1024;
+ }
+
+ public static int ceil(double d) {
+ int i = (int) d;
+ return d > (double) i ? i + 1 : i;
+ }
+
+}

View File

@@ -0,0 +1,90 @@
--- /dev/null
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java
@@ -1,0 +_,87 @@
+package com.logisticscraft.occlusionculling.util;
+
+public class Vec3d {
+
+ public double x;
+ public double y;
+ public double z;
+
+ public Vec3d(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public double getZ() {
+ return z;
+ }
+
+ public void set(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public void setAdd(Vec3d vec, double x, double y, double z) {
+ this.x = vec.x + x;
+ this.y = vec.y + y;
+ this.z = vec.z + z;
+ }
+
+ public Vec3d div(Vec3d rayDir) {
+ this.x /= rayDir.x;
+ this.z /= rayDir.z;
+ this.y /= rayDir.y;
+ return this;
+ }
+
+ public Vec3d normalize() {
+ double mag = Math.sqrt(x*x+y*y+z*z);
+ this.x /= mag;
+ this.y /= mag;
+ this.z /= mag;
+ return this;
+ }
+
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof Vec3d)) {
+ return false;
+ }
+ Vec3d vec3d = (Vec3d) other;
+ if (Double.compare(vec3d.x, x) != 0) {
+ return false;
+ }
+ if (Double.compare(vec3d.y, y) != 0) {
+ return false;
+ }
+ return Double.compare(vec3d.z, z) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ long l = Double.doubleToLongBits(x);
+ int i = (int) (l ^ l >>> 32);
+ l = Double.doubleToLongBits(y);
+ i = 31 * i + (int) (l ^ l >>> 32);
+ l = Double.doubleToLongBits(z);
+ i = 31 * i + (int) (l ^ l >>> 32);
+ return i;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+
+}

View File

@@ -1,15 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 11:07:09 +0800
Subject: [PATCH] Kaiiju Entity tick and removal limiter
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java
new file mode 100644
index 0000000000000000000000000000000000000000..40e80fc685a42bbaeea3e6e64754121178cc7d22
--- /dev/null --- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java +++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java
@@ -0,0 +1,141 @@ @@ -1,0 +_,141 @@
+package dev.kaiijumc.kaiiju; +package dev.kaiijumc.kaiiju;
+ +
+import java.io.File; +import java.io.File;
@@ -151,122 +142,3 @@ index 0000000000000000000000000000000000000000..40e80fc685a42bbaeea3e6e647541211
+ } + }
+ } + }
+} +}
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb690efacf083e4ff3e321578b12c534e6a40196
--- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java
@@ -0,0 +1,84 @@
+package dev.kaiijumc.kaiiju;
+
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import net.minecraft.world.entity.Entity;
+import io.papermc.paper.threadedregions.RegionizedWorldData;
+
+public class KaiijuEntityThrottler {
+ private static class TickInfo {
+ int currentTick;
+ int continueFrom;
+ int toTick;
+ int toRemove;
+ }
+
+ public static class EntityThrottlerReturn {
+ public boolean skip;
+ public boolean remove;
+ }
+
+ private final Object2ObjectOpenHashMap<KaiijuEntityLimits.EntityLimit, TickInfo> entityLimitTickInfoMap = new Object2ObjectOpenHashMap<>();
+
+ public void tickLimiterStart() {
+ for (TickInfo tickInfo : entityLimitTickInfoMap.values()) {
+ tickInfo.currentTick = 0;
+ }
+ }
+
+ public EntityThrottlerReturn tickLimiterShouldSkip(Entity entity) {
+ EntityThrottlerReturn retVal = new EntityThrottlerReturn();
+ if (entity.isRemoved()) return retVal;
+ KaiijuEntityLimits.EntityLimit entityLimit = KaiijuEntityLimits.getEntityLimit(entity);
+
+ if (entityLimit != null) {
+ TickInfo tickInfo = entityLimitTickInfoMap.computeIfAbsent(entityLimit, el -> {
+ TickInfo newTickInfo = new TickInfo();
+ newTickInfo.toTick = entityLimit.limit();
+ return newTickInfo;
+ });
+
+ tickInfo.currentTick++;
+ if (tickInfo.currentTick <= tickInfo.toRemove && entityLimit.removal() > 0) {
+ retVal.skip = false;
+ retVal.remove = true;
+ return retVal;
+ }
+
+ if (tickInfo.currentTick < tickInfo.continueFrom) {
+ retVal.skip = true;
+ return retVal;
+ }
+ if (tickInfo.currentTick - tickInfo.continueFrom < tickInfo.toTick) {
+ retVal.skip = false;
+ return retVal;
+ }
+ retVal.skip = true;
+ return retVal;
+ } else {
+ retVal.skip = false;
+ return retVal;
+ }
+ }
+
+ public void tickLimiterFinish(RegionizedWorldData regionizedWorldData) {
+ for (var entry : entityLimitTickInfoMap.entrySet()) {
+ KaiijuEntityLimits.EntityLimit entityLimit = entry.getKey();
+ TickInfo tickInfo = entry.getValue();
+
+ int additionals = 0;
+ int nextContinueFrom = tickInfo.continueFrom + tickInfo.toTick;
+ if (nextContinueFrom >= tickInfo.currentTick) {
+ additionals = entityLimit.limit() - (tickInfo.currentTick - tickInfo.continueFrom);
+ nextContinueFrom = 0;
+ }
+ tickInfo.continueFrom = nextContinueFrom;
+ tickInfo.toTick = entityLimit.limit() + additionals;
+
+ if (tickInfo.toRemove == 0 && tickInfo.currentTick > entityLimit.removal()) {
+ tickInfo.toRemove = tickInfo.currentTick - entityLimit.removal();
+ } else if (tickInfo.toRemove != 0) {
+ tickInfo.toRemove = 0;
+ }
+ }
+ }
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/KaiijuEntityLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/KaiijuEntityLimiterConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..038d9ab60cfac7e40e7c0c0644fa0a0d035eac01
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/KaiijuEntityLimiterConfig.java
@@ -0,0 +1,23 @@
+package me.earthme.luminol.config.modules.misc;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import dev.kaiijumc.kaiiju.KaiijuEntityLimits;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+
+public class KaiijuEntityLimiterConfig implements IConfigModule {
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "kaiiju_entity_limiter";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance) {
+ KaiijuEntityLimits.init();
+ }
+}

View File

@@ -0,0 +1,87 @@
--- /dev/null
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java
@@ -1,0 +_,84 @@
+package dev.kaiijumc.kaiiju;
+
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import net.minecraft.world.entity.Entity;
+import io.papermc.paper.threadedregions.RegionizedWorldData;
+
+public class KaiijuEntityThrottler {
+ private static class TickInfo {
+ int currentTick;
+ int continueFrom;
+ int toTick;
+ int toRemove;
+ }
+
+ public static class EntityThrottlerReturn {
+ public boolean skip;
+ public boolean remove;
+ }
+
+ private final Object2ObjectOpenHashMap<KaiijuEntityLimits.EntityLimit, TickInfo> entityLimitTickInfoMap = new Object2ObjectOpenHashMap<>();
+
+ public void tickLimiterStart() {
+ for (TickInfo tickInfo : entityLimitTickInfoMap.values()) {
+ tickInfo.currentTick = 0;
+ }
+ }
+
+ public EntityThrottlerReturn tickLimiterShouldSkip(Entity entity) {
+ EntityThrottlerReturn retVal = new EntityThrottlerReturn();
+ if (entity.isRemoved()) return retVal;
+ KaiijuEntityLimits.EntityLimit entityLimit = KaiijuEntityLimits.getEntityLimit(entity);
+
+ if (entityLimit != null) {
+ TickInfo tickInfo = entityLimitTickInfoMap.computeIfAbsent(entityLimit, el -> {
+ TickInfo newTickInfo = new TickInfo();
+ newTickInfo.toTick = entityLimit.limit();
+ return newTickInfo;
+ });
+
+ tickInfo.currentTick++;
+ if (tickInfo.currentTick <= tickInfo.toRemove && entityLimit.removal() > 0) {
+ retVal.skip = false;
+ retVal.remove = true;
+ return retVal;
+ }
+
+ if (tickInfo.currentTick < tickInfo.continueFrom) {
+ retVal.skip = true;
+ return retVal;
+ }
+ if (tickInfo.currentTick - tickInfo.continueFrom < tickInfo.toTick) {
+ retVal.skip = false;
+ return retVal;
+ }
+ retVal.skip = true;
+ return retVal;
+ } else {
+ retVal.skip = false;
+ return retVal;
+ }
+ }
+
+ public void tickLimiterFinish(RegionizedWorldData regionizedWorldData) {
+ for (var entry : entityLimitTickInfoMap.entrySet()) {
+ KaiijuEntityLimits.EntityLimit entityLimit = entry.getKey();
+ TickInfo tickInfo = entry.getValue();
+
+ int additionals = 0;
+ int nextContinueFrom = tickInfo.continueFrom + tickInfo.toTick;
+ if (nextContinueFrom >= tickInfo.currentTick) {
+ additionals = entityLimit.limit() - (tickInfo.currentTick - tickInfo.continueFrom);
+ nextContinueFrom = 0;
+ }
+ tickInfo.continueFrom = nextContinueFrom;
+ tickInfo.toTick = entityLimit.limit() + additionals;
+
+ if (tickInfo.toRemove == 0 && tickInfo.currentTick > entityLimit.removal()) {
+ tickInfo.toRemove = tickInfo.currentTick - entityLimit.removal();
+ } else if (tickInfo.toRemove != 0) {
+ tickInfo.toRemove = 0;
+ }
+ }
+ }
+}

View File

@@ -0,0 +1,155 @@
--- /dev/null
+++ b/src/main/java/dev/tr7zw/entityculling/CullTask.java
@@ -1,0 +_,152 @@
+package dev.tr7zw.entityculling;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import ca.spottedleaf.moonrise.common.util.TickThread;
+import com.logisticscraft.occlusionculling.OcclusionCullingInstance;
+import com.logisticscraft.occlusionculling.util.Vec3d;
+
+import dev.tr7zw.entityculling.versionless.access.Cullable;
+import me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.decoration.ArmorStand;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.phys.AABB;
+import net.minecraft.world.phys.Vec3;
+
+public class CullTask implements Runnable {
+
+ private volatile boolean requestCull = false;
+ private volatile boolean scheduleNext = true;
+ private volatile boolean inited = false;
+
+ private final OcclusionCullingInstance culling;
+ private final Player checkTarget;
+
+ private final int hitboxLimit;
+
+ public long lastCheckedTime = 0;
+
+ // reused preallocated vars
+ private final Vec3d lastPos = new Vec3d(0, 0, 0);
+ private final Vec3d aabbMin = new Vec3d(0, 0, 0);
+ private final Vec3d aabbMax = new Vec3d(0, 0, 0);
+
+ private static final Executor backgroundWorker = Executors.newCachedThreadPool(task -> {
+ final TickThread worker = new TickThread("EntityCulling") {
+ @Override
+ public void run() {
+ task.run();
+ }
+ };
+
+ worker.setDaemon(true);
+
+ return worker;
+ });
+
+ private final Executor worker;
+
+ public CullTask(
+ OcclusionCullingInstance culling,
+ Player checkTarget,
+ int hitboxLimit,
+ long checkIntervalMs
+ ) {
+ this.culling = culling;
+ this.checkTarget = checkTarget;
+ this.hitboxLimit = hitboxLimit;
+ this.worker = CompletableFuture.delayedExecutor(checkIntervalMs, TimeUnit.MILLISECONDS, backgroundWorker);
+ }
+
+ public void requestCullSignal() {
+ this.requestCull = true;
+ }
+
+ public void signalStop() {
+ this.scheduleNext = false;
+ }
+
+ public void setup() {
+ if (!this.inited)
+ this.inited = true;
+ else
+ return;
+ this.worker.execute(this);
+ }
+
+ @Override
+ public void run() {
+ try {
+ if (this.checkTarget.tickCount > 10) {
+ // getEyePosition can use a fixed delta as its debug only anyway
+ Vec3 cameraMC = this.checkTarget.getEyePosition(0);
+ if (requestCull || !(cameraMC.x == lastPos.x && cameraMC.y == lastPos.y && cameraMC.z == lastPos.z)) {
+ long start = System.currentTimeMillis();
+
+ requestCull = false;
+
+ lastPos.set(cameraMC.x, cameraMC.y, cameraMC.z);
+ culling.resetCache();
+
+ cullEntities(cameraMC, lastPos);
+
+ lastCheckedTime = (System.currentTimeMillis() - start);
+ }
+ }
+ }finally {
+ if (this.scheduleNext) {
+ this.worker.execute(this);
+ }
+ }
+ }
+
+ private void cullEntities(Vec3 cameraMC, Vec3d camera) {
+ for (Entity entity : this.checkTarget.level().getEntities().getAll()) {
+ if (!(entity instanceof Cullable cullable)) {
+ continue; // Not sure how this could happen outside from mixin screwing up the inject into
+ // Entity
+ }
+
+ if (entity.getType().skipRaytracningCheck) {
+ continue;
+ }
+
+ if (!cullable.isForcedVisible()) {
+ if (entity.isCurrentlyGlowing() || isSkippableArmorstand(entity)) {
+ cullable.setCulled(false);
+ continue;
+ }
+
+ if (!entity.position().closerThan(cameraMC, me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance)) {
+ cullable.setCulled(false); // If your entity view distance is larger than tracingDistance just
+ // render it
+ continue;
+ }
+
+ AABB boundingBox = entity.getBoundingBox();
+ if (boundingBox.getXsize() > hitboxLimit || boundingBox.getYsize() > hitboxLimit
+ || boundingBox.getZsize() > hitboxLimit) {
+ cullable.setCulled(false); // To big to bother to cull
+ continue;
+ }
+
+ aabbMin.set(boundingBox.minX, boundingBox.minY, boundingBox.minZ);
+ aabbMax.set(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ);
+
+ boolean visible = culling.isAABBVisible(aabbMin, aabbMax, camera);
+
+ cullable.setCulled(!visible);
+ }
+ }
+ }
+
+ private boolean isSkippableArmorstand(Entity entity) {
+ if (!RayTrackingEntityTrackerConfig.skipMarkerArmorStands)
+ return false;
+ return entity instanceof ArmorStand && entity.isInvisible();
+ }
+}

View File

@@ -0,0 +1,46 @@
--- /dev/null
+++ b/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java
@@ -1,0 +_,43 @@
+package dev.tr7zw.entityculling;
+
+import com.logisticscraft.occlusionculling.DataProvider;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.chunk.ChunkAccess;
+import net.minecraft.world.level.chunk.status.ChunkStatus;
+
+public class DefaultChunkDataProvider implements DataProvider {
+ private final Level level;
+
+ public DefaultChunkDataProvider(Level level) {
+ this.level = level;
+ }
+
+ @Override
+ public boolean prepareChunk(int chunkX, int chunkZ) {
+ return this.level.getChunkIfLoaded(chunkX, chunkZ) != null;
+ }
+
+ @Override
+ public boolean isOpaqueFullCube(int x, int y, int z) {
+ BlockPos pos = new BlockPos(x, y, z);
+
+ final ChunkAccess access = this.level.getChunkIfLoaded(pos);
+ if (access == null) {
+ return false;
+ }
+
+ if (this.level.isOutsideBuildHeight(pos)) {
+ return Blocks.VOID_AIR.defaultBlockState().isSolidRender();
+ } else {
+ return access.getBlockState(pos).isSolidRender();// 好孩子不要学坏叔叔这样绕过异步拦截()
+ }
+ }
+
+ @Override
+ public void cleanup() {
+ DataProvider.super.cleanup();
+ }
+
+}

View File

@@ -0,0 +1,20 @@
--- /dev/null
+++ b/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java
@@ -1,0 +_,17 @@
+package dev.tr7zw.entityculling.versionless.access;
+
+public interface Cullable {
+
+ public void setTimeout();
+
+ public boolean isForcedVisible();
+
+ public void setCulled(boolean value);
+
+ public boolean isCulled();
+
+ public void setOutOfCamera(boolean value);
+
+ public boolean isOutOfCamera();
+
+}

View File

@@ -1,15 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 15:26:09 +0800
Subject: [PATCH] Pufferfish Sentry
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b830cb288ceba390ed39cd33fc1ee855357a97e
--- /dev/null --- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java +++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
@@ -0,0 +1,133 @@ @@ -1,0 +_,133 @@
+package gg.pufferfish.pufferfish.sentry; +package gg.pufferfish.pufferfish.sentry;
+ +
+import com.google.common.reflect.TypeToken; +import com.google.common.reflect.TypeToken;
@@ -143,107 +134,3 @@ index 0000000000000000000000000000000000000000..2b830cb288ceba390ed39cd33fc1ee85
+ } + }
+ } + }
+} +}
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..c01e5b5de685eca7edbe8a87732efd45d4dd2557
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
@@ -0,0 +1,44 @@
+package gg.pufferfish.pufferfish.sentry;
+
+import io.sentry.Sentry;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class SentryManager {
+
+ private static final Logger logger = LogManager.getLogger(SentryManager.class);
+
+ private SentryManager() {
+
+ }
+
+ private static boolean initialized = false;
+
+ public static synchronized void init(Level logLevel) {
+ if (initialized) {
+ return;
+ }
+ if (logLevel == null) {
+ logger.error("Invalid log level, defaulting to WARN.");
+ logLevel = Level.WARN;
+ }
+ try {
+ initialized = true;
+
+ Sentry.init(options -> {
+ options.setDsn(me.earthme.luminol.config.modules.misc.SentryConfig.sentryDsn);
+ options.setMaxBreadcrumbs(100);
+ });
+
+ PufferfishSentryAppender appender = new PufferfishSentryAppender(logLevel);
+ appender.start();
+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender);
+ logger.info("Sentry logging started!");
+ } catch (Exception e) {
+ logger.warn("Failed to initialize sentry!", e);
+ initialized = false;
+ }
+ }
+
+}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/SentryConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/SentryConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..55d6bb635b182d15471bfcd481a2b7c6ce26c00b
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/SentryConfig.java
@@ -0,0 +1,47 @@
+package me.earthme.luminol.config.modules.misc;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import org.apache.logging.log4j.Level;
+
+public class SentryConfig implements IConfigModule {
+
+ @ConfigInfo(baseName = "dsn", comments =
+ " Sentry DSN for improved error logging, leave blank to disable,\n" +
+ " Obtain from https://sentry.io/")
+ public static String sentryDsn = "";
+
+ @ConfigInfo(baseName = "log_level", comments = " Logs with a level higher than or equal to this level will be recorded.")
+ public static String logLevel = "WARN";
+
+ @ConfigInfo(baseName = "only_log_thrown", comments = " Only log with a Throwable will be recorded after enabling this.")
+ public static boolean onlyLogThrown = true;
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "sentry";
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance) {
+ String sentryEnvironment = System.getenv("SENTRY_DSN");
+
+ sentryDsn = sentryEnvironment != null && !sentryEnvironment.isBlank()
+ ? sentryEnvironment
+ : configInstance.getOrElse("sentry.dsn", sentryDsn);
+
+ logLevel = configInstance.getOrElse("sentry.log-level", logLevel);
+ onlyLogThrown = configInstance.getOrElse("sentry.only-log-thrown", onlyLogThrown);
+
+ if (sentryDsn != null && !sentryDsn.isBlank()) {
+ gg.pufferfish.pufferfish.sentry.SentryManager.init(Level.getLevel(logLevel));
+ }
+ }
+}
\ No newline at end of file

View File

@@ -0,0 +1,47 @@
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
@@ -1,0 +_,44 @@
+package gg.pufferfish.pufferfish.sentry;
+
+import io.sentry.Sentry;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class SentryManager {
+
+ private static final Logger logger = LogManager.getLogger(SentryManager.class);
+
+ private SentryManager() {
+
+ }
+
+ private static boolean initialized = false;
+
+ public static synchronized void init(Level logLevel) {
+ if (initialized) {
+ return;
+ }
+ if (logLevel == null) {
+ logger.error("Invalid log level, defaulting to WARN.");
+ logLevel = Level.WARN;
+ }
+ try {
+ initialized = true;
+
+ Sentry.init(options -> {
+ options.setDsn(me.earthme.luminol.config.modules.misc.SentryConfig.sentryDsn);
+ options.setMaxBreadcrumbs(100);
+ });
+
+ PufferfishSentryAppender appender = new PufferfishSentryAppender(logLevel);
+ appender.start();
+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender);
+ logger.info("Sentry logging started!");
+ } catch (Exception e) {
+ logger.warn("Failed to initialize sentry!", e);
+ initialized = false;
+ }
+ }
+
+}

View File

@@ -0,0 +1,30 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java
@@ -1,0 +_,27 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.RegionStats;
+
+public class RegionStatsImpl implements RegionStats {
+ private final TickRegions.RegionStats internal;
+
+ public RegionStatsImpl(TickRegions.RegionStats internal) {
+ this.internal = internal;
+ }
+
+ @Override
+ public int getEntityCount() {
+ return this.internal.getEntityCount();
+ }
+
+ @Override
+ public int getPlayerCount() {
+ return this.internal.getPlayerCount();
+ }
+
+ @Override
+ public int getChunkCount() {
+ return this.internal.getChunkCount();
+ }
+}

View File

@@ -0,0 +1,50 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java
@@ -1,0 +_,47 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.ThreadedRegion;
+import me.earthme.luminol.api.TickRegionData;
+import net.minecraft.world.level.ChunkPos;
+import org.bukkit.Location;
+import org.bukkit.World;
+
+import javax.annotation.Nullable;
+
+public class ThreadedRegionImpl implements ThreadedRegion {
+ private final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal;
+
+ public ThreadedRegionImpl(ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal) {
+ this.internal = internal;
+ }
+
+ @Nullable
+ @Override
+ public Location getCenterChunkPos() {
+ final ChunkPos centerChunkPos = this.internal.getCenterChunk();
+
+ if (centerChunkPos == null) {
+ return null;
+ }
+
+ return new Location(this.internal.regioniser.world.getWorld(), centerChunkPos.getMiddleBlockX(), 0, centerChunkPos.getMiddleBlockZ());
+ }
+
+ @Override
+ public double getDeadSectionPercent() {
+ return this.internal.getDeadSectionPercent();
+ }
+
+ @Override
+ public TickRegionData getTickRegionData() {
+ return new TickRegionDataImpl(this.internal.getData());
+ }
+
+ @Nullable
+ @Override
+ public World getWorld() {
+ return this.internal.regioniser.world.getWorld();
+ }
+}

View File

@@ -0,0 +1,56 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java
@@ -1,0 +_,53 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.ThreadedRegion;
+import me.earthme.luminol.api.ThreadedRegionizer;
+import net.minecraft.server.level.ServerLevel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ThreadedRegionizerImpl implements ThreadedRegionizer {
+ private final ServerLevel internal;
+
+ public ThreadedRegionizerImpl(ServerLevel internal) {
+ this.internal = internal;
+ }
+
+ @Override
+ public Collection<ThreadedRegion> getAllRegions() {
+ final List<ThreadedRegion> ret = new ArrayList<>();
+
+ this.internal.regioniser.computeForAllRegions(region -> {
+ final ThreadedRegion wrapped = new ThreadedRegionImpl(region);
+
+ ret.add(wrapped);
+ });
+
+ return ret;
+ }
+
+ @Override
+ public ThreadedRegion getAtSynchronized(int chunkX, int chunkZ) {
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtSynchronised(chunkX, chunkZ);
+
+ if (got == null) {
+ return null;
+ }
+
+ return new ThreadedRegionImpl(got);
+ }
+
+ @Override
+ public ThreadedRegion getAtUnSynchronized(int chunkX, int chunkZ) {
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtUnsynchronised(chunkX, chunkZ);
+
+ if (got == null) {
+ return null;
+ }
+
+ return new ThreadedRegionImpl(got);
+ }
+}

View File

@@ -0,0 +1,33 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java
@@ -1,0 +_,30 @@
+package me.earthme.luminol.api.impl;
+
+import io.papermc.paper.threadedregions.TickRegions;
+import me.earthme.luminol.api.RegionStats;
+import me.earthme.luminol.api.TickRegionData;
+import org.bukkit.World;
+
+public class TickRegionDataImpl implements TickRegionData {
+ private final TickRegions.TickRegionData internal;
+
+ public TickRegionDataImpl(TickRegions.TickRegionData internal) {
+ this.internal = internal;
+ }
+
+ @Override
+ public World getWorld() {
+ return this.internal.world.getWorld();
+ }
+
+ @Override
+ public long getCurrentTickCount() {
+ return this.internal.getCurrentTick();
+ }
+
+ @Override
+ public RegionStats getRegionStats() {
+ return new RegionStatsImpl(this.internal.getRegionStats());
+ }
+
+}

View File

@@ -0,0 +1,73 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
@@ -1,0 +_,70 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.LuminolConfig;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.Location;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LuminolConfigCommand extends Command {
+ public LuminolConfigCommand(){
+ super("luminolconfig");
+ this.setPermission("luminol.commands.luminolconfig");
+ this.setDescription("Manage config file");
+ this.setUsage("/luminolconfig");
+ }
+
+ @Override
+ public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args, @Nullable Location location) throws IllegalArgumentException {
+ final List<String> result = new ArrayList<>();
+
+ if (args.length == 1){
+ result.add("reload");
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!this.testPermission(sender)){
+ sender.sendMessage(Component
+ .text("No permission to execute this command!")
+ .color(TextColor.color(255,0,0))
+ );
+ }
+
+ if (args.length < 1){
+ sender.sendMessage(
+ Component
+ .text("Wrong use!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ return true;
+ }
+
+ switch (args[0]){
+ case "reload" -> {
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
+ Component
+ .text("Reloaded config file!")
+ .color(TextColor.color(0,255,0))
+ ));
+ }
+
+ default -> sender.sendMessage(
+ Component
+ .text("Unknown action!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ }
+
+ return true;
+ }
+}

View File

@@ -0,0 +1,50 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/MembarCommand.java
@@ -1,0 +_,47 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.modules.misc.MembarConfig;
+import me.earthme.luminol.functions.GlobalServerMemoryBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class MembarCommand extends Command {
+ public MembarCommand(@NotNull String name) {
+ super(name);
+ this.setPermission("luminol.commands.membar");
+ this.setDescription("Show the memory usage through a bossbar");
+ this.setUsage("/membar");
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!testPermission(sender)){
+ return true;
+ }
+
+ if (!MembarConfig.memoryBarEnabled){
+ sender.sendMessage(Component.text("Membar was already disabled!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)){
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (GlobalServerMemoryBar.isPlayerVisible(player)) {
+ player.sendMessage(Component.text("Disabled mem bar").color(TextColor.color(0,255,0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player,false);
+ return true;
+ }
+
+ player.sendMessage(Component.text("Enabled mem bar").color(TextColor.color(0,255,0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player,true);
+
+ return true;
+ }
+}

View File

@@ -0,0 +1,50 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/RegionBarCommand.java
@@ -1,0 +_,47 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.modules.misc.RegionBarConfig;
+import me.earthme.luminol.functions.GlobalServerRegionBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class RegionBarCommand extends Command {
+ public RegionBarCommand(@NotNull String name) {
+ super(name);
+ this.setPermission("luminol.commands.regionbar");
+ this.setDescription("Show info about your current region through a bossbar");
+ this.setUsage("/regionbar");
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!testPermission(sender)) {
+ return true;
+ }
+
+ if (!RegionBarConfig.regionbarEnabled) {
+ sender.sendMessage(Component.text("Regionbar was already disabled!").color(TextColor.color(255, 0, 0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255, 0, 0)));
+ return true;
+ }
+
+ if (GlobalServerRegionBar.isPlayerVisible(player)) {
+ player.sendMessage(Component.text("Disabled region bar").color(TextColor.color(0, 255, 0)));
+ GlobalServerRegionBar.setVisibilityForPlayer(player, false);
+ return true;
+ }
+
+ player.sendMessage(Component.text("Enabled region bar").color(TextColor.color(0, 255, 0)));
+ GlobalServerRegionBar.setVisibilityForPlayer(player, true);
+
+ return true;
+ }
+}

View File

@@ -0,0 +1,53 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
@@ -1,0 +_,50 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.modules.misc.TpsBarConfig;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import net.kyori.adventure.util.RGBLike;
+import org.bukkit.ChatColor;
+import org.bukkit.Color;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class TpsBarCommand extends Command {
+ public TpsBarCommand(@NotNull String name) {
+ super(name);
+ this.setPermission("luminol.commands.tpsbar");
+ this.setDescription("Show the tps and mspt through a bossbar");
+ this.setUsage("/tpsbar");
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!testPermission(sender)){
+ return true;
+ }
+
+ if (!TpsBarConfig.tpsbarEnabled){
+ sender.sendMessage(Component.text("Tpsbar was already disabled!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)){
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
+ return true;
+ }
+
+ if (GlobalServerTpsBar.isPlayerVisible(player)) {
+ player.sendMessage(Component.text("Disabled tps bar").color(TextColor.color(0,255,0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player,false);
+ return true;
+ }
+
+ player.sendMessage(Component.text("Enabled tps bar").color(TextColor.color(0,255,0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player,true);
+
+ return true;
+ }
+}

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