Compare commits
285 Commits
1.21.1-a50
...
dev/1.21.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a8e4f4484 | ||
|
|
33a24b7503 | ||
|
|
d96e3d882a | ||
|
|
bdec926efd | ||
|
|
42163c20b3 | ||
|
|
ac1a7165fb | ||
|
|
2e85aaf801 | ||
|
|
7bd5c4ecc4 | ||
|
|
56e7949273 | ||
|
|
7a2129c45c | ||
|
|
eb49a31dad | ||
|
|
f2fa3514bd | ||
|
|
83c54e3134 | ||
|
|
021c3666f7 | ||
|
|
860e9fbaf5 | ||
|
|
1a6a70069c | ||
|
|
1f0fc01a6e | ||
|
|
c20bbf9842 | ||
|
|
93e4d4eea1 | ||
|
|
efc5adae8b | ||
|
|
f51216d01d | ||
|
|
3ef35a1b4b | ||
|
|
c06b8444aa | ||
|
|
3e96017ed6 | ||
|
|
85e32d5d03 | ||
|
|
778c82ee0a | ||
|
|
14146549a8 | ||
|
|
064898cddf | ||
|
|
c829110cf3 | ||
|
|
08cc27a648 | ||
|
|
531d824a55 | ||
|
|
0f6e3ac870 | ||
|
|
93e956372b | ||
|
|
0bf38e65cf | ||
|
|
e5b2276a8d | ||
|
|
589c263bac | ||
|
|
5d3d2271bc | ||
|
|
3361b9db14 | ||
|
|
3550274e82 | ||
|
|
f6ca4cc24a | ||
|
|
85ffaa1156 | ||
|
|
6c48c27b7d | ||
|
|
41770b069e | ||
|
|
e24d0fffdf | ||
|
|
d4c1790f94 | ||
|
|
4346983b7d | ||
|
|
720e02e944 | ||
|
|
f035a3bd8e | ||
|
|
365a5252a9 | ||
|
|
5746a0e01c | ||
|
|
8bce97d0bb | ||
|
|
8817720b5a | ||
|
|
525b5ccfba | ||
|
|
821c69804d | ||
|
|
cc840886f3 | ||
|
|
70257fa22b | ||
|
|
40242ad8de | ||
|
|
08cf5d6179 | ||
|
|
88eb84f82d | ||
|
|
19745cf033 | ||
|
|
9ba08a6ce6 | ||
|
|
2274af4415 | ||
|
|
1fe23949f0 | ||
|
|
92fb91fb08 | ||
|
|
50a6e68dcc | ||
|
|
4f924a1594 | ||
|
|
711c8534fe | ||
|
|
2260aed532 | ||
|
|
956bc88e58 | ||
|
|
0e93cb6f59 | ||
|
|
1cecb38fee | ||
|
|
78636dc0bd | ||
|
|
cdb8ff1aba | ||
|
|
f8f537423c | ||
|
|
23fc8891ed | ||
|
|
c4c8fd3d62 | ||
|
|
a92a95b296 | ||
|
|
1c3358728a | ||
|
|
c2249e4002 | ||
|
|
23692ba677 | ||
|
|
0e7081c2e5 | ||
|
|
0ac067ae20 | ||
|
|
ebe4b76463 | ||
|
|
01d686b420 | ||
|
|
0cb0a2c8ea | ||
|
|
68cd1a1f2c | ||
|
|
74faeab654 | ||
|
|
4517c9548c | ||
|
|
c7894407ab | ||
|
|
d2926dfe83 | ||
|
|
582149a21f | ||
|
|
4ef9f261f4 | ||
|
|
73e0a0c135 | ||
|
|
c40a7be6cd | ||
|
|
818dfeede1 | ||
|
|
a3b9a862ee | ||
|
|
7a4290580f | ||
|
|
22a263b18c | ||
|
|
cfdf1607df | ||
|
|
16ba8f40f3 | ||
|
|
56b428ddc4 | ||
|
|
9425fd9ec0 | ||
|
|
7604000bec | ||
|
|
81977c7f19 | ||
|
|
37ead10d7b | ||
|
|
cd9dbb24bb | ||
|
|
efd55893c7 | ||
|
|
0ef5ac515b | ||
|
|
6019c70728 | ||
|
|
9553bc97d8 | ||
|
|
9f134a9a1f | ||
|
|
6e29fe7b7d | ||
|
|
9a52936bd1 | ||
|
|
bbcc33f505 | ||
|
|
fb02ab7ae5 | ||
|
|
41c275bce6 | ||
|
|
eb91e07a0e | ||
|
|
11eecfee58 | ||
|
|
1fb706e081 | ||
|
|
762ea4fe63 | ||
|
|
92f33ed7da | ||
|
|
d18e27d447 | ||
|
|
4cff0f834d | ||
|
|
45d40874ec | ||
|
|
8b17257f15 | ||
|
|
7cde9ec70b | ||
|
|
74121bcb29 | ||
|
|
8a8d0fcf7a | ||
|
|
67c4e452d0 | ||
|
|
2ad92983c0 | ||
|
|
90fd4ca205 | ||
|
|
01467c7fcb | ||
|
|
67949a070c | ||
|
|
e4ba4e0497 | ||
|
|
4b43bded79 | ||
|
|
a11e94e56e | ||
|
|
f3e8f024a7 | ||
|
|
85f21d1be1 | ||
|
|
c0f20000cf | ||
|
|
b33e2fc51d | ||
|
|
b2c753bcfd | ||
|
|
677544289b | ||
|
|
87d2047f24 | ||
|
|
217047f7b5 | ||
|
|
2dcdca21b2 | ||
|
|
7afc1b403c | ||
|
|
e6e33b3947 | ||
|
|
bebfe1eda7 | ||
|
|
b9ca4c0c7a | ||
|
|
12cfb7a0ef | ||
|
|
e618370375 | ||
|
|
74aeb4fe5d | ||
|
|
102979a7d8 | ||
|
|
c5f561233f | ||
|
|
0d6b9a051f | ||
|
|
36b617c5be | ||
|
|
487fcdfc10 | ||
|
|
c99f65d958 | ||
|
|
1984558e49 | ||
|
|
ab5b160232 | ||
|
|
16df7dce12 | ||
|
|
8a01b9ad39 | ||
|
|
27a2e2a129 | ||
|
|
3b9b3813b4 | ||
|
|
9b4a6d60ac | ||
|
|
6055cc7367 | ||
|
|
9edeb2a539 | ||
|
|
207f96891a | ||
|
|
9baaa0a236 | ||
|
|
99c167504b | ||
|
|
2b5bedf14b | ||
|
|
38e4a96ab7 | ||
|
|
c7134597cb | ||
|
|
b1c6c29458 | ||
|
|
eeae6bc62c | ||
|
|
852529973b | ||
|
|
43af4d5432 | ||
|
|
b428505e23 | ||
|
|
e4b448c6df | ||
|
|
db4f0f7e1b | ||
|
|
bb144df37b | ||
|
|
21d1ee350a | ||
|
|
4a76009af8 | ||
|
|
1445e4683d | ||
|
|
fa959bf213 | ||
|
|
4a40f56920 | ||
|
|
9360a5adbd | ||
|
|
ea34494c03 | ||
|
|
1526790e77 | ||
|
|
af556ab869 | ||
|
|
4e8d54e073 | ||
|
|
f8559b9ca6 | ||
|
|
bc5a83c69c | ||
|
|
6a8df3771b | ||
|
|
ff4fdcc7d1 | ||
|
|
94ae8e3ce0 | ||
|
|
f1dfac26d8 | ||
|
|
5d9dfc3e17 | ||
|
|
ca44ba98a5 | ||
|
|
27298b865c | ||
|
|
bcea80b4d1 | ||
|
|
d20e0b1940 | ||
|
|
6fb1f6934b | ||
|
|
ab28422974 | ||
|
|
1247d8bf89 | ||
|
|
76ce141d63 | ||
|
|
f9514f1866 | ||
|
|
3102b1c581 | ||
|
|
770e4b848d | ||
|
|
78cfb0a760 | ||
|
|
98552da7aa | ||
|
|
a50e2f5be9 | ||
|
|
c275bd7e93 | ||
|
|
6825d1dbd1 | ||
|
|
cad01d6368 | ||
|
|
dacd3c5a29 | ||
|
|
4f051b3c62 | ||
|
|
a0f4d02bc9 | ||
|
|
63a8beaafc | ||
|
|
5905dbad61 | ||
|
|
bfe835b8b9 | ||
|
|
bf5c6d04d4 | ||
|
|
e20088ff17 | ||
|
|
62470e9097 | ||
|
|
b96655d098 | ||
|
|
f3b16cb314 | ||
|
|
0296cd03b1 | ||
|
|
791d374a94 | ||
|
|
065b78f0d5 | ||
|
|
156837d199 | ||
|
|
5a60f7395f | ||
|
|
973b437ad6 | ||
|
|
051ed97668 | ||
|
|
4918bb98e5 | ||
|
|
8d491c23a9 | ||
|
|
16eca828f1 | ||
|
|
7c312e7851 | ||
|
|
76f1b9d02d | ||
|
|
896fd7bf1a | ||
|
|
81f17dc7b0 | ||
|
|
5f694869c2 | ||
|
|
dc0f1f9933 | ||
|
|
1a6ea9fc98 | ||
|
|
f175359ad9 | ||
|
|
e6a76b5794 | ||
|
|
d170436ff0 | ||
|
|
cc907e891d | ||
|
|
5b9d44ee94 | ||
|
|
c749ca011a | ||
|
|
72f6717b13 | ||
|
|
55be3489f0 | ||
|
|
d547f8ab3f | ||
|
|
a22472fe99 | ||
|
|
d15f2774ea | ||
|
|
b27cf9614e | ||
|
|
98bbcd67e4 | ||
|
|
1ed71f5812 | ||
|
|
14de6bf8c7 | ||
|
|
d0d9ce0c46 | ||
|
|
2e520168e1 | ||
|
|
58d45e32c5 | ||
|
|
8830d65945 | ||
|
|
fb55d3e201 | ||
|
|
892dfcd2a0 | ||
|
|
6c600853dd | ||
|
|
1299dbfeea | ||
|
|
8e876b48f2 | ||
|
|
a4794fb096 | ||
|
|
064679fd22 | ||
|
|
2541ddfd7b | ||
|
|
c5cb9503c9 | ||
|
|
ab71de6298 | ||
|
|
7bba0412a3 | ||
|
|
b56f9723e7 | ||
|
|
190e5e094a | ||
|
|
17e9d04db0 | ||
|
|
09861230f7 | ||
|
|
a92cfa3637 | ||
|
|
84cf8fbb38 | ||
|
|
620e093735 | ||
|
|
d01eef55ec | ||
|
|
05101da67b | ||
|
|
32db7a453c | ||
|
|
576d488a36 | ||
|
|
4959ecceba |
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# Linux start script should use lf
|
||||
/gradlew text eol=lf
|
||||
|
||||
# These are Windows script files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
# Binary files should be left untouched
|
||||
*.jar binary
|
||||
@@ -1,10 +1,10 @@
|
||||
name: Luminol CI - vev/1.20.6
|
||||
name: Luminol CI - dev/1.21.4-hardfork-with-new-scheduler
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "ver/1.20.6" ]
|
||||
branches: [ "dev/1.21.4-hardfork-with-new-scheduler" ]
|
||||
pull_request:
|
||||
branches: [ "ver/1.20.6" ]
|
||||
branches: [ "dev/1.21.4-hardfork-with-new-scheduler" ]
|
||||
|
||||
permissions: write-all
|
||||
|
||||
@@ -15,53 +15,55 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout Git Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
gradle-version: 8.7
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: '21'
|
||||
java-version: '22'
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Configure Git User Details
|
||||
run: git config --global user.email "ci@luminolmc.com" && git config --global user.name "LuminolMC CI"
|
||||
- name: Apply Patches
|
||||
run: gradle applyPatches
|
||||
run: ./gradlew applyAllPatches
|
||||
- name: CreateJar
|
||||
run: gradle createMojmapBundlerJar createMojmapPaperclipJar
|
||||
- name: SetENV
|
||||
run: sh scripts/SetENV.sh
|
||||
run: ./gradlew createMojmapPaperclipJar
|
||||
- name: Publish to repo
|
||||
if: github.event_name != 'pull_request'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
export MAVEN_REPO_USER=${{ secrets.MAVEN_REPO_USER }}
|
||||
export MAVEN_REPO_PASSWORD=${{ secrets.MAVEN_REPO_PASSWORD }}
|
||||
./gradlew publish -PpublishDevBundle=true
|
||||
- name: Upload Artifact
|
||||
uses: "actions/upload-artifact@v4"
|
||||
with:
|
||||
name: "${{ env.project_id_b }} CI Artifacts"
|
||||
path: "build/libs/*.jar"
|
||||
path: "luminol-server/build/libs/*-paperclip-*-mojmap.jar"
|
||||
- name: SetENV
|
||||
if: github.event_name != 'pull_request'
|
||||
run: sh scripts/SetENV.sh
|
||||
- name: Create Release
|
||||
if: "!contains(github.event.commits[0].message, '[release skip]')"
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: ncipollo/release-action@v1.16.0
|
||||
with:
|
||||
tag: ${{ env.tag }}
|
||||
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}
|
||||
body: |
|
||||
> [!CAUTION]
|
||||
> 🚨You are trying to download experimental builds!
|
||||
> **<u>DO NOT</u>** use these builds in production, as there may be many bugs and corruption issues.
|
||||
> Please report any and all issues you encounter!
|
||||
|
||||
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [](https://github.com/LuminolMC/${{ env.project_id }}/download/${{ env.tag }}/${{ env.jar }})
|
||||
This release is automatically compiled by GitHub Actions
|
||||
### Commit Message
|
||||
${{ env.commit_msg }}
|
||||
artifacts: |
|
||||
${{ env.jar_dir }}
|
||||
${{ env.jar_dir_bundler }}
|
||||
generateReleaseNotes: true
|
||||
prerelease: ${{ env.pre }}
|
||||
makeLatest: ${{ env.make_latest }}
|
||||
token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Push to API
|
||||
if: "!contains(github.event.commits[0].message, '[release skip]')"
|
||||
continue-on-error: true
|
||||
env:
|
||||
secret_v2: ${{ secrets.API_KEY }}
|
||||
tag: ${{ env.tag }}
|
||||
project_id: ${{ env.project_id }}
|
||||
run: sh scripts/PushToAPI.sh
|
||||
72
.gitignore
vendored
72
.gitignore
vendored
@@ -1,59 +1,17 @@
|
||||
# JVM crash related
|
||||
core.*
|
||||
hs_err_pid*
|
||||
# Ignore Gradle project-specific cache directory
|
||||
.gradle
|
||||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
||||
|
||||
/run
|
||||
|
||||
/luminol-server/build.gradle.kts
|
||||
/luminol-api/build.gradle.kts
|
||||
/folia-server/build.gradle.kts
|
||||
/folia-server/src/minecraft
|
||||
/folia-api/build.gradle.kts
|
||||
/paper-server
|
||||
/paper-api
|
||||
|
||||
# Intellij
|
||||
.idea/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
out/
|
||||
|
||||
# Eclipse
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
|
||||
# netbeans
|
||||
nbproject/
|
||||
nbactions.xml
|
||||
|
||||
# Gradle
|
||||
!gradle-wrapper.jar
|
||||
.gradle/
|
||||
build/
|
||||
*/build/
|
||||
|
||||
# we use maven!
|
||||
build.xml
|
||||
|
||||
# Maven
|
||||
log/
|
||||
target/
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# various other potential build files
|
||||
bin/
|
||||
dist/
|
||||
manifest.mf
|
||||
|
||||
# Mac
|
||||
.DS_Store/
|
||||
.DS_Store
|
||||
|
||||
# vim
|
||||
.*.sw[a-p]
|
||||
|
||||
# Linux temp files
|
||||
*~
|
||||
|
||||
# other stuff
|
||||
run/
|
||||
|
||||
# Luminol
|
||||
build-data/
|
||||
Luminol-API
|
||||
Luminol-Server
|
||||
paper-api-generator
|
||||
*.jar
|
||||
/patches2/todo/
|
||||
48
Jenkinsfile
vendored
Normal file
48
Jenkinsfile
vendored
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 LuminolMC
|
||||
Copyright (c) 2025 LuminolMC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
38
README.md
38
README.md
@@ -24,32 +24,47 @@
|
||||
要构建一个paperclip jar,你需要运行以下命令。你可以在build/libs中找到jar(注意:需要`JDK21`)
|
||||
|
||||
```shell
|
||||
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
|
||||
./gradlew applyAllPatches && ./gradlew createMojmapPaperclipJar
|
||||
```
|
||||
|
||||
## 使用API
|
||||
使用 Gradle:
|
||||
|
||||
```kotlin
|
||||
repositories {
|
||||
maven {
|
||||
url = "https://maven.moliatopia.icu/repository/maven-snapshots/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("me.earthme.luminol:luminol-api:1.20.6-R0.1-SNAPSHOT")
|
||||
compileOnly("me.earthme.luminol:luminol-api:$VERSION")
|
||||
}
|
||||
```
|
||||
|
||||
使用 Maven
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>me.earthme.luminol</groupId>
|
||||
<artifactId>luminol-api</artifactId>
|
||||
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>moliatopia</id>
|
||||
<url>https://maven.moliatopia.icu/repository/maven-snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>me.earthme.luminol</groupId>
|
||||
<artifactId>luminol-api</artifactId>
|
||||
<version>$VERSION</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
## 联系方式
|
||||
> 如果您对这个项目感兴趣或有任何问题,请随时向我们提问。
|
||||
|
||||
**QQ群: [368632360](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=MfosKhcDd8Fdxn1MREuZ8Krbf9T6jiBC&authKey=3cm6qdHohON3gHnuD63FK4k07fIbrWnY4hdyq8OmELsfjMVP1kbFTJY9mRyM2Rkj&noverify=0&group_code=368632360)** | QQ频道: [点击加入](https://pd.qq.com/s/eq9krf9j) | Telegram: [点击加入](https://t.me/LuminolMC) | Discord: [点击加入](https://discord.gg/Qd7m3V6eDx)
|
||||
**QQ群: [1015048616](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=QML5kIVsniPi1PlZvnjHQT_02EHsZ5Jc&authKey=%2FTCJsZC7JFQ9sxAroPCKuYnlV57Z5fyqp36ewXZk3Sn4iJ9p4MB1JKdc%2FFcX3HOM&noverify=0&group_code=1015048616)** | QQ频道: [点击加入](https://pd.qq.com/s/eq9krf9j) | Telegram: [点击加入](https://t.me/LuminolMinecraft) | Discord: [点击加入](https://discord.gg/Qd7m3V6eDx)
|
||||
|
||||
|
||||
## 关于 Issue
|
||||
@@ -61,6 +76,11 @@ dependencies {
|
||||
## BStats
|
||||

|
||||
|
||||
## 特别感谢
|
||||
<b>感谢[LegacyLands](https://github.com/LegacyLands)对本项目的赞助,如果你想开发一些跨folia/非folia平台的插件,[legacy-lands-library](https://github.com/LegacyLands/legacy-lands-library/)将会是个不错的lib</b>
|
||||
|
||||

|
||||
|
||||
## 请给我们一个 ⭐Star!
|
||||
> 你的每一个免费的 ⭐Star 就是我们每一个前进的动力。
|
||||
|
||||
@@ -70,4 +90,4 @@ dependencies {
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date" />
|
||||
<img alt="Star历史表" src="https://api.star-history.com/svg?repos=LuminolMC/Luminol%2CLuminolMC/LightingLuminol&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
</a>
|
||||
|
||||
32
README_EN.md
32
README_EN.md
@@ -25,32 +25,47 @@ Any versions are available in the [release](https://github.com/LuminolMC/Luminol
|
||||
To build a paperclip jar, you need to run the following command. You can find the jar in build/libs(Note: JDK21 is needed)
|
||||
|
||||
```shell
|
||||
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
|
||||
./gradlew applyAllPatches && ./gradlew createMojmapPaperclipJar
|
||||
```
|
||||
|
||||
## Using API
|
||||
For gradle:
|
||||
|
||||
```kotlin
|
||||
repositories {
|
||||
maven {
|
||||
url = "https://maven.moliatopia.icu/repository/maven-snapshots/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("me.earthme.luminol:luminol-api:1.20.6-R0.1-SNAPSHOT")
|
||||
compileOnly("me.earthme.luminol:luminol-api:$VERSION")
|
||||
}
|
||||
```
|
||||
|
||||
For maven
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>moliatopia</id>
|
||||
<url>https://maven.moliatopia.icu/repository/maven-snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>me.earthme.luminol</groupId>
|
||||
<artifactId>luminol-api</artifactId>
|
||||
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||
<groupId>me.earthme.luminol</groupId>
|
||||
<artifactId>luminol-api</artifactId>
|
||||
<version>$VERSION</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
## Contact
|
||||
> If you are interested in this project or have any issue, feel free to ask us.
|
||||
|
||||
**QQ Group: [368632360](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=MfosKhcDd8Fdxn1MREuZ8Krbf9T6jiBC&authKey=3cm6qdHohON3gHnuD63FK4k07fIbrWnY4hdyq8OmELsfjMVP1kbFTJY9mRyM2Rkj&noverify=0&group_code=368632360)** | QQ Channel: [Click To Join](https://pd.qq.com/s/eq9krf9j) | Telegram: [Click To Join](https://t.me/LuminolMC) | Discord: [Click To Join](https://discord.gg/Qd7m3V6eDx)
|
||||
**QQ Group: [1015048616](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=hTPlI5j6XB8pgk4sdx6RkjhBPGG1r4IR&authKey=pnu6uCKQP7Sja2CJWC15Qi3BeI%2FAsh8tU4m5muufMBjbB3zz%2BwHBZCTRRdSNKhld&noverify=0&group_code=1015048616)** | QQ Channel: [Click To Join](https://pd.qq.com/s/eq9krf9j) | Telegram: [Click To Join](https://t.me/LuminolMinecraft) | Discord: [Click To Join](https://discord.gg/Qd7m3V6eDx)
|
||||
|
||||
## About Issue
|
||||
When you meet any problems, just ask us, we will do our best to solve it, but remember to state your problem clear and provide enough logs etc.</br>
|
||||
@@ -61,6 +76,11 @@ See [Contributing](./docs/CONTRIBUTING_EN.md)
|
||||
## BStats
|
||||

|
||||
|
||||
## Special Thanks
|
||||
Thanks [LegacyLands](https://github.com/LegacyLands) for sponsoring this project.If you want to develop some crossing folia/non-folia platform plugins, [legacy-lands-library](https://github.com/LegacyLands/legacy-lands-library/) will be a nice choice for you
|
||||
|
||||

|
||||
|
||||
## Please ⭐star us!
|
||||
<a href="https://star-history.com/#LuminolMC/Luminol&LuminolMC/LightingLuminol&Date">
|
||||
<picture>
|
||||
|
||||
168
build.gradle.kts
168
build.gradle.kts
@@ -1,128 +1,92 @@
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||
|
||||
plugins {
|
||||
java
|
||||
`maven-publish`
|
||||
id("io.papermc.paperweight.patcher") version "1.7.1"
|
||||
java // TODO java launcher tasks
|
||||
id("io.papermc.paperweight.patcher") version "2.0.0-SNAPSHOT"
|
||||
}
|
||||
|
||||
paperweight {
|
||||
upstreams.register("folia") {
|
||||
repo = github("PaperMC", "Folia")
|
||||
ref = providers.gradleProperty("foliaRef")
|
||||
|
||||
patchFile {
|
||||
path = "folia-server/build.gradle.kts"
|
||||
outputFile = file("luminol-server/build.gradle.kts")
|
||||
patchFile = file("luminol-server/build.gradle.kts.patch")
|
||||
}
|
||||
patchFile {
|
||||
path = "folia-api/build.gradle.kts"
|
||||
outputFile = file("luminol-api/build.gradle.kts")
|
||||
patchFile = file("luminol-api/build.gradle.kts.patch")
|
||||
}
|
||||
patchRepo("paperApi") {
|
||||
upstreamPath = "paper-api"
|
||||
patchesDir = file("luminol-api/paper-patches")
|
||||
outputDir = file("paper-api")
|
||||
}
|
||||
patchDir("foliaApi") {
|
||||
upstreamPath = "folia-api"
|
||||
excludes = listOf("build.gradle.kts", "build.gradle.kts.patch", "paper-patches")
|
||||
patchesDir = file("luminol-api/folia-patches")
|
||||
outputDir = file("folia-api")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven(paperMavenPublicUrl) {
|
||||
content { onlyForConfigurations(configurations.paperclip.name) }
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
remapper("net.fabricmc:tiny-remapper:0.10.1:fat")
|
||||
decompiler("org.vineflower:vineflower:1.10.1")
|
||||
paperclip("io.papermc:paperclip:3.0.3")
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "java-library")
|
||||
apply(plugin = "maven-publish")
|
||||
|
||||
java {
|
||||
extensions.configure<JavaPluginExtension> {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(21)
|
||||
}
|
||||
|
||||
tasks.withType<Javadoc> {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
|
||||
tasks.withType<ProcessResources> {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven(paperMavenPublicUrl)
|
||||
maven("https://oss.sonatype.org/content/groups/public/")
|
||||
maven("https://ci.emc.gs/nexus/content/groups/aikar/")
|
||||
maven("https://repo.aikar.co/content/groups/aikar")
|
||||
maven("https://repo.md-5.net/content/repositories/releases/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
maven("https://jitpack.io")
|
||||
maven("https://repo.codemc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
}
|
||||
dependencies {
|
||||
"testRuntimeOnly"("org.junit.platform:junit-platform-launcher")
|
||||
}
|
||||
|
||||
paperweight {
|
||||
serverProject.set(project(":luminol-server"))
|
||||
|
||||
remapRepo.set("https://maven.fabricmc.net/")
|
||||
decompileRepo.set("https://maven.quiltmc.org/")
|
||||
|
||||
useStandardUpstream("folia") {
|
||||
url.set(github("PaperMC", "Folia"))
|
||||
ref.set(providers.gradleProperty("foliaCommit"))
|
||||
|
||||
withStandardPatcher {
|
||||
apiSourceDirPath.set("Folia-API")
|
||||
serverSourceDirPath.set("Folia-Server")
|
||||
|
||||
|
||||
apiPatchDir.set(layout.projectDirectory.dir("patches/api"))
|
||||
apiOutputDir.set(layout.projectDirectory.dir("Luminol-API"))
|
||||
|
||||
serverPatchDir.set(layout.projectDirectory.dir("patches/server"))
|
||||
serverOutputDir.set(layout.projectDirectory.dir("Luminol-Server"))
|
||||
}
|
||||
|
||||
patchTasks.register("generatedApi") {
|
||||
isBareDirectory = true
|
||||
upstreamDirPath = "paper-api-generator/generated"
|
||||
patchDir = layout.projectDirectory.dir("patches/generatedApi")
|
||||
outputDir = layout.projectDirectory.dir("paper-api-generator/generated")
|
||||
tasks.withType<AbstractArchiveTask>().configureEach {
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
}
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release = 21
|
||||
options.isFork = true
|
||||
}
|
||||
tasks.withType<Javadoc> {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
tasks.withType<ProcessResources> {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
}
|
||||
tasks.withType<Test> {
|
||||
testLogging {
|
||||
showStackTraces = true
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
events(TestLogEvent.STANDARD_OUT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.generateDevelopmentBundle {
|
||||
apiCoordinates.set("me.earthme.luminol:luminol-api")
|
||||
libraryRepositories.addAll(
|
||||
"https://repo.maven.apache.org/maven2/",
|
||||
"https://maven.pkg.github.com/LuminolMC/Luminol",
|
||||
paperMavenPublicUrl,
|
||||
)
|
||||
}
|
||||
|
||||
allprojects {
|
||||
publishing {
|
||||
extensions.configure<PublishingExtension> {
|
||||
repositories {
|
||||
maven {
|
||||
name = "githubPackage"
|
||||
url = uri("https://maven.pkg.github.com/LuminolMC/Luminol")
|
||||
|
||||
credentials.username = System.getenv("GITHUB_USERNAME")
|
||||
credentials.password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
|
||||
publications {
|
||||
register<MavenPublication>("gpr") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
if (project.hasProperty("publishDevBundle")) {
|
||||
publications.create<MavenPublication>("devBundle") {
|
||||
artifact(tasks.generateDevelopmentBundle) {
|
||||
artifactId = "dev-bundle"
|
||||
/*
|
||||
maven("https://repo.papermc.io/repository/maven-snapshots/") {
|
||||
name = "paperSnapshots"
|
||||
credentials(PasswordCredentials::class)
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,23 +21,24 @@
|
||||
在开始开发之前,您首先需要拥有以下软件作为开发环境:
|
||||
|
||||
- `git`
|
||||
- `JDK 17 或更高版本`
|
||||
- `JDK 21 或更高版本`
|
||||
|
||||
## 了解补丁(Patches)
|
||||
|
||||
Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的修改分成了两个目录:
|
||||
|
||||
- `luminol-api` - 对 `Folia-API` / `Paper-API` / `Spigot-API` / `Bukkit` 进行的修改。
|
||||
- `luminol-server` - 对 Minecraft 标准服务器原有逻辑进行的修改。
|
||||
|
||||
补丁系统是基于 git 的,你可以在这里了解 git 的基本内容: <https://git-scm.com/docs/gittutorial>
|
||||
|
||||
如果你已经 Fork 了主储存库,那么下面你应该这么做:
|
||||
|
||||
1. 将你的仓库 clone 到本地;
|
||||
2. 在你的 IDE 或 终端 内执行 Gradle 的 `applyPatches` 任务,如果是在终端内,你可以执行 `./gradlew applyPatches`;
|
||||
3. 进入 `luminol-api` 文件夹进行修改。
|
||||
2. 在你的 IDE 或 终端 内执行 Gradle 的 `applyAllPatches` 任务,如果是在终端内,你可以执行 `./gradlew applyAllPatches`;
|
||||
3. 进入 仓库根目录下的 `luminol-api` 和 `luminol-server` 文件夹进行修改。
|
||||
|
||||
顺便一提,`luminol-api` 并不是正常的 git 仓库:
|
||||
顺便一提,仓库根目录下的 `luminol-api` 和 `luminol-server` 并不是正常的 git 仓库:
|
||||
|
||||
- 在应用补丁前,基点将会指向未被更改的源码
|
||||
- 在基点后的每一个提交都是一个补丁
|
||||
@@ -47,11 +48,12 @@ Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的
|
||||
|
||||
按照以下步骤增加一个补丁是非常简单的:
|
||||
|
||||
1. 对 `luminol-api` 进行修改;
|
||||
2. 使用 git 添加你的修改,比如 `git add .`;
|
||||
1. 对 `luminol-api` 和 `luminol-server` 进行修改;
|
||||
2. 使用 git 添加你的修改,比如 `git add .`(不要提交新建的文件的修改);
|
||||
3. 使用 `git commit -m <提交信息>` 进行提交;
|
||||
4. 运行 Gradle 任务 `rebuildPatches` 将你的提交转化为一个补丁;
|
||||
5. 将你生成的补丁文件进行推送。
|
||||
4. 运行 Gradle 任务 `rebuildAllServerPatches` 将你的提交转化为一个补丁;
|
||||
5. 运行 Gradle 任务 `fixupPaperApiFilePatches` 生成新建文件的补丁文件(注意不要提交);
|
||||
6. 将你生成的补丁文件进行推送。
|
||||
|
||||
这样做以后,你就可以将你的补丁文件进行 PR 提交。
|
||||
|
||||
@@ -60,8 +62,9 @@ Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的
|
||||
你可以使用以下方法来修改一个补丁的内容:
|
||||
|
||||
1. 在 HEAD 上直接进行修改;
|
||||
2. 使用 `git commit -a --fixup <hash>` 来进行一个更正提交;
|
||||
2. 使用 `git commit -a --fixup <hash>` 来进行一个更正提交;(不要提交对在luminol新建文件的修改)
|
||||
- 如果你想要更改提交信息,你也可以用 `--squash` 来代替 `--fixup`。
|
||||
3. 使用 `git rebase -i --autosquash base` 来进行自动变基,你只需要输入 `:q` 来关闭确认页面即可;
|
||||
4. 运行 Gradle 任务 `rebuildPatches` 来修改已被修改的补丁;
|
||||
5. 将修改后的补丁 PR 发回储存库。
|
||||
4. 运行 Gradle 任务 `rebuildAllServerPatches` 来修改已被修改的补丁;
|
||||
5. 运行 Gradle 任务 `fixupPaperApiFilePatches` 来修改已被修改的在luminol新建文件的补丁(注意不要提交);
|
||||
6. 将修改后的补丁 PR 发回储存库。
|
||||
|
||||
@@ -10,20 +10,20 @@ And if you can follow the rules below, we can complete the review faster.
|
||||
## Please fork using your personal account
|
||||
|
||||
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.
|
||||
|
||||
## 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`
|
||||
- `JDK 17 or higher`
|
||||
- `JDK 21 or higher`
|
||||
|
||||
## 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:
|
||||
|
||||
- `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>
|
||||
|
||||
If you have forked the main repository, then you should follow the steps below:
|
||||
|
||||
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.)
|
||||
3. Enter `luminol-api` directory to carry out modifications.
|
||||
2. Run Gradle's `applyAllPatches` task in your IDE or terminal (You can run `./gradlew applyAllPatches` directly in terminal.)
|
||||
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.
|
||||
- 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
|
||||
|
||||
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 .`)
|
||||
3. Commit these changes using `git commit -m <Commit Message>`
|
||||
4. Run Gradle's task `rebuildPatches` to convert your commits to a new patch
|
||||
5. Push your patches to your repository
|
||||
3. Commit these changes using `git commit -m <Commit Message>` (PS: do not commit new-created files)
|
||||
4. Run Gradle's task `rebuildAllServerPatches` to convert your commits to a new patch
|
||||
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.
|
||||
|
||||
## 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
|
||||
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`.
|
||||
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
|
||||
5. Push and PR again
|
||||
4. Run Gradle's task `rebuildAllServerPatches` to modify existing patches
|
||||
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
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
group = me.earthme.luminol
|
||||
version = 1.20.6-R0.1-SNAPSHOT
|
||||
version=1.21.4-R0.1-SNAPSHOT
|
||||
mcVersion=1.21.4
|
||||
|
||||
foliaCommit = d79708296e75ee4f26e78c2925f6e7d4217d0575
|
||||
foliaRef=80ab57dcbe5fa96cc2f7fe34ecba94162d8dd5e9
|
||||
|
||||
org.gradle.caching = true
|
||||
org.gradle.parallel = true
|
||||
org.gradle.vfs.watch = false
|
||||
org.gradle.jvmargs = -Xmx3G
|
||||
|
||||
mcVersion = 1.20.6
|
||||
GroupMCV = 1.20
|
||||
preVersion = false
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.vfs.watch=false
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
6
gradlew
vendored
6
gradlew
vendored
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -84,7 +86,7 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
2
gradlew.bat
vendored
2
gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
|
||||
43
luminol-api/build.gradle.kts.patch
Normal file
43
luminol-api/build.gradle.kts.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
--- a/folia-api/build.gradle.kts
|
||||
+++ b/folia-api/build.gradle.kts
|
||||
@@ -54,6 +_,7 @@
|
||||
api("org.apache.logging.log4j:log4j-api:$log4jVersion")
|
||||
api("org.slf4j:slf4j-api:$slf4jVersion")
|
||||
api("com.mojang:brigadier:1.3.10")
|
||||
+ api("io.sentry:sentry:8.0.0-rc.2") // Pufferfish
|
||||
|
||||
// Deprecate bungeecord-chat in favor of adventure
|
||||
api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.19") {
|
||||
@@ -104,17 +_,21 @@
|
||||
java {
|
||||
srcDir(generatedApiPath)
|
||||
srcDir(file("../paper-api/src/main/java"))
|
||||
+ srcDir(file("../folia-api/src/main/java"))
|
||||
}
|
||||
resources {
|
||||
srcDir(file("../paper-api/src/main/resources"))
|
||||
+ srcDir(file("../folia-api/src/main/resources"))
|
||||
}
|
||||
}
|
||||
test {
|
||||
java {
|
||||
srcDir(file("../paper-api/src/test/java"))
|
||||
+ srcDir(file("../folia-api/src/test/java"))
|
||||
}
|
||||
resources {
|
||||
srcDir(file("../paper-api/src/test/resources"))
|
||||
+ srcDir(file("../folia-api/src/test/resources"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,3 +_,10 @@
|
||||
tasks.check {
|
||||
dependsOn(scanJarForOldGeneratedCode)
|
||||
}
|
||||
+
|
||||
+// Pufferfish Start
|
||||
+tasks.withType<JavaCompile> {
|
||||
+ val compilerArgs = options.compilerArgs
|
||||
+ compilerArgs.add("--add-modules=jdk.incubator.vector")
|
||||
+}
|
||||
+// Pufferfish End
|
||||
@@ -1,14 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
|
||||
Date: Tue, 21 May 2024 21:31:53 +0800
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:18:38 +0800
|
||||
Subject: [PATCH] Rebrand to Luminol
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfo.java b/src/main/java/io/papermc/paper/ServerBuildInfo.java
|
||||
index 9df9d09aa477d4cd3c496ba0933c816df1ef0964..b8a5e4f02499e3a3c370d43f6bbb84ffba58e1f3 100644
|
||||
index 652ff54e7c50412503725d628bfe72ed03059790..ee163b9fa8f441aa4b3e2309f33e8f932dfc02d7 100644
|
||||
--- a/src/main/java/io/papermc/paper/ServerBuildInfo.java
|
||||
+++ b/src/main/java/io/papermc/paper/ServerBuildInfo.java
|
||||
@@ -18,6 +18,13 @@ public interface ServerBuildInfo {
|
||||
@@ -19,6 +19,13 @@ public interface ServerBuildInfo {
|
||||
*/
|
||||
Key BRAND_PAPER_ID = Key.key("papermc", "paper");
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <novau233@163.com>
|
||||
Date: Sat, 27 Apr 2024 13:22:59 +0000
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 09:16:49 +0800
|
||||
Subject: [PATCH] KioCG Chunk API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java
|
||||
index bc8b5bc17706250b8535b1b309134843d2ce2bb1..1cfe84ad1094e3c4fab96487f328be53e035a64c 100644
|
||||
index d434277342b2db19f98e032d3a316b27d728b840..e188353ad193f6203533790ae52fafc0554df63f 100644
|
||||
--- a/src/main/java/org/bukkit/Chunk.java
|
||||
+++ b/src/main/java/org/bukkit/Chunk.java
|
||||
@@ -389,4 +389,6 @@ public interface Chunk extends PersistentDataHolder {
|
||||
@@ -388,4 +388,6 @@ public interface Chunk extends PersistentDataHolder {
|
||||
*/
|
||||
UNLOADED;
|
||||
}
|
||||
@@ -16,13 +16,13 @@ index bc8b5bc17706250b8535b1b309134843d2ce2bb1..1cfe84ad1094e3c4fab96487f328be53
|
||||
+ long getChunkHotAvg(); // KioCG
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index eb34f22e973fe46529eb93f435f5bf7f85091404..b2d23eeb24d1132607cf68c2a6eec352db321fa2 100644
|
||||
index 494dca2ee48a03953d47050b178496df12bc48c5..a65d64b1ef64cf1cf213cec00e7f73cc7ad2b79c 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -3854,4 +3854,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
@Override
|
||||
Spigot spigot();
|
||||
// Spigot end
|
||||
@@ -3918,4 +3918,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param score New death screen score of player
|
||||
*/
|
||||
void setDeathScreenScore(int score);
|
||||
+
|
||||
+ long getNearbyChunkHot(); // KioCG
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 12:22:53 +0800
|
||||
Subject: [PATCH] Disable timings warn msg and commands
|
||||
|
||||
|
||||
diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java
|
||||
index 89017af09ce32e7a66014fc3aeb50155921252a5..b862779b48176dd7e67a2f1a3e7f24bc8c84e993 100644
|
||||
--- a/src/main/java/co/aikar/timings/Timings.java
|
||||
+++ b/src/main/java/co/aikar/timings/Timings.java
|
||||
@@ -147,7 +147,7 @@ public final class Timings {
|
||||
public static void setTimingsEnabled(boolean enabled) {
|
||||
enabled = false; // Folia - region threading - disable timings
|
||||
if (enabled && !warnedAboutDeprecationOnEnable) {
|
||||
- Bukkit.getLogger().severe(PlainTextComponentSerializer.plainText().serialize(deprecationMessage()));
|
||||
+ // Bukkit.getLogger().severe(PlainTextComponentSerializer.plainText().serialize(deprecationMessage())); // Luminol - Disable timings warn msg and commands
|
||||
warnedAboutDeprecationOnEnable = true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index 5df19bd701c67506689fc7f49d91f99ebfbc83f0..baf0cbd2f995ebe2e4382244eff6e15ec125d790 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -39,7 +39,7 @@ public class SimpleCommandMap implements CommandMap {
|
||||
register("bukkit", new VersionCommand("version"));
|
||||
register("bukkit", new ReloadCommand("reload"));
|
||||
//register("bukkit", new PluginsCommand("plugins")); // Paper
|
||||
- register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper
|
||||
+ //register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper // Luminol - Disable timings warn msg and commands
|
||||
}
|
||||
|
||||
public void setFallbackCommands() {
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 468f5646da7bc413a6e91e82379e6554cc8b459d..ab36e3aaff57e2f27b5aed06b4bdfe277f86a35e 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -966,7 +966,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void useTimings(boolean use) {
|
||||
- co.aikar.timings.Timings.setTimingsEnabled(use); // Paper
|
||||
+ // co.aikar.timings.Timings.setTimingsEnabled(use); // Paper // Luminol - Disable timings warn msg and commands
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Thu, 23 Jan 2025 12:04:04 +0800
|
||||
Subject: [PATCH] Force disable reload command
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index baf0cbd2f995ebe2e4382244eff6e15ec125d790..0d354eb5e7df427faff2d6c816c297c3d39a6e63 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -37,7 +37,7 @@ public class SimpleCommandMap implements CommandMap {
|
||||
|
||||
private void setDefaultCommands() {
|
||||
register("bukkit", new VersionCommand("version"));
|
||||
- register("bukkit", new ReloadCommand("reload"));
|
||||
+ //register("bukkit", new ReloadCommand("reload")); // Luminol - Force disable reload command
|
||||
//register("bukkit", new PluginsCommand("plugins")); // Paper
|
||||
//register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper // Luminol - Disable timings warn msg and commands
|
||||
}
|
||||
231
luminol-api/paper-patches/features/0005-Pufferfish-Sentry.patch
Normal file
231
luminol-api/paper-patches/features/0005-Pufferfish-Sentry.patch
Normal file
@@ -0,0 +1,231 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 13:27:38 +0800
|
||||
Subject: [PATCH] Pufferfish Sentry
|
||||
|
||||
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c7772aac00f6db664f7a5673bc2585fa025e6aad
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java
|
||||
@@ -0,0 +1,165 @@
|
||||
+package gg.pufferfish.pufferfish.sentry;
|
||||
+
|
||||
+import com.google.gson.Gson;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.Map;
|
||||
+import java.util.TreeMap;
|
||||
+
|
||||
+import org.apache.logging.log4j.ThreadContext;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+import org.bukkit.plugin.RegisteredListener;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class SentryContext {
|
||||
+
|
||||
+ private static final Gson GSON = new Gson();
|
||||
+
|
||||
+ public static void setPluginContext(@Nullable Plugin plugin) {
|
||||
+ if (plugin != null) {
|
||||
+ ThreadContext.put("pufferfishsentry_pluginname", plugin.getName());
|
||||
+ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getPluginMeta().getVersion());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void removePluginContext() {
|
||||
+ ThreadContext.remove("pufferfishsentry_pluginname");
|
||||
+ ThreadContext.remove("pufferfishsentry_pluginversion");
|
||||
+ }
|
||||
+
|
||||
+ public static void setSenderContext(@Nullable CommandSender sender) {
|
||||
+ if (sender != null) {
|
||||
+ ThreadContext.put("pufferfishsentry_playername", sender.getName());
|
||||
+ if (sender instanceof Player player) {
|
||||
+ ThreadContext.put("pufferfishsentry_playerid", player.getUniqueId().toString());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void removeSenderContext() {
|
||||
+ ThreadContext.remove("pufferfishsentry_playername");
|
||||
+ ThreadContext.remove("pufferfishsentry_playerid");
|
||||
+ }
|
||||
+
|
||||
+ public static void setEventContext(Event event, RegisteredListener registration) {
|
||||
+ setPluginContext(registration.getPlugin());
|
||||
+
|
||||
+ try {
|
||||
+ // Find the player that was involved with this event
|
||||
+ Player player = null;
|
||||
+ if (event instanceof PlayerEvent) {
|
||||
+ player = ((PlayerEvent) event).getPlayer();
|
||||
+ } else {
|
||||
+ Class<? extends Event> eventClass = event.getClass();
|
||||
+
|
||||
+ Field playerField = null;
|
||||
+
|
||||
+ for (Field field : eventClass.getDeclaredFields()) {
|
||||
+ if (field.getType().equals(Player.class)) {
|
||||
+ playerField = field;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (playerField != null) {
|
||||
+ playerField.setAccessible(true);
|
||||
+ player = (Player) playerField.get(event);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (player != null) {
|
||||
+ setSenderContext(player);
|
||||
+ }
|
||||
+ } catch (Exception ignored) {
|
||||
+ } // We can't really safely log exceptions.
|
||||
+
|
||||
+ ThreadContext.put("pufferfishsentry_eventdata", GSON.toJson(serializeFields(event)));
|
||||
+ }
|
||||
+
|
||||
+ public static void removeEventContext() {
|
||||
+ removePluginContext();
|
||||
+ removeSenderContext();
|
||||
+ ThreadContext.remove("pufferfishsentry_eventdata");
|
||||
+ }
|
||||
+
|
||||
+ private static Map<String, String> serializeFields(Object object) {
|
||||
+ Map<String, String> fields = new TreeMap<>();
|
||||
+ fields.put("_class", object.getClass().getName());
|
||||
+ for (Field declaredField : object.getClass().getDeclaredFields()) {
|
||||
+ try {
|
||||
+ if (Modifier.isStatic(declaredField.getModifiers())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ String fieldName = declaredField.getName();
|
||||
+ if (fieldName.equals("handlers")) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ declaredField.setAccessible(true);
|
||||
+ Object value = declaredField.get(object);
|
||||
+ if (value != null) {
|
||||
+ fields.put(fieldName, value.toString());
|
||||
+ } else {
|
||||
+ fields.put(fieldName, "<null>");
|
||||
+ }
|
||||
+ } catch (Exception ignored) {
|
||||
+ } // We can't really safely log exceptions.
|
||||
+ }
|
||||
+ return fields;
|
||||
+ }
|
||||
+
|
||||
+ public static class State {
|
||||
+
|
||||
+ private Plugin plugin;
|
||||
+ private Command command;
|
||||
+ private String commandLine;
|
||||
+ private Event event;
|
||||
+ private RegisteredListener registeredListener;
|
||||
+
|
||||
+ public Plugin getPlugin() {
|
||||
+ return plugin;
|
||||
+ }
|
||||
+
|
||||
+ public void setPlugin(Plugin plugin) {
|
||||
+ this.plugin = plugin;
|
||||
+ }
|
||||
+
|
||||
+ public Command getCommand() {
|
||||
+ return command;
|
||||
+ }
|
||||
+
|
||||
+ public void setCommand(Command command) {
|
||||
+ this.command = command;
|
||||
+ }
|
||||
+
|
||||
+ public String getCommandLine() {
|
||||
+ return commandLine;
|
||||
+ }
|
||||
+
|
||||
+ public void setCommandLine(String commandLine) {
|
||||
+ this.commandLine = commandLine;
|
||||
+ }
|
||||
+
|
||||
+ public Event getEvent() {
|
||||
+ return event;
|
||||
+ }
|
||||
+
|
||||
+ public void setEvent(Event event) {
|
||||
+ this.event = event;
|
||||
+ }
|
||||
+
|
||||
+ public RegisteredListener getRegisteredListener() {
|
||||
+ return registeredListener;
|
||||
+ }
|
||||
+
|
||||
+ public void setRegisteredListener(RegisteredListener registeredListener) {
|
||||
+ this.registeredListener = registeredListener;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index ab36e3aaff57e2f27b5aed06b4bdfe277f86a35e..96da9f1082ab134d197b3a6069f2fcdf38585efe 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -597,7 +597,9 @@ public final class SimplePluginManager implements PluginManager {
|
||||
|
||||
// Paper start
|
||||
private void handlePluginException(String msg, Throwable ex, Plugin plugin) {
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish
|
||||
server.getLogger().log(Level.SEVERE, msg, ex);
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish
|
||||
callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin)));
|
||||
}
|
||||
// Paper end
|
||||
@@ -667,9 +669,11 @@ public final class SimplePluginManager implements PluginManager {
|
||||
));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.setEventContext(event, registration); // Pufferfish
|
||||
// Paper start - error reporting
|
||||
String msg = "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName();
|
||||
server.getLogger().log(Level.SEVERE, msg, ex);
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.removeEventContext(); // Pufferfish
|
||||
if (!(event instanceof com.destroystokyo.paper.event.server.ServerExceptionEvent)) { // We don't want to cause an endless event loop
|
||||
callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerEventException(msg, ex, registration.getPlugin(), registration.getListener(), event)));
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index b412aaf08901d169ac9fc89b36f9d6ccb95c53d3..45a9ca8969f635d20cc44c062fda85bbccd8f8ff 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -336,7 +336,13 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
try {
|
||||
jPlugin.setEnabled(true);
|
||||
} catch (Throwable ex) {
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish
|
||||
server.getLogger().log(Level.SEVERE, "Error occurred while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish
|
||||
+ // Paper start - Disable plugins that fail to load
|
||||
+ this.server.getPluginManager().disablePlugin(jPlugin);
|
||||
+ return;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// Perhaps abort here, rather than continue going, but as it stands,
|
||||
@@ -361,7 +367,9 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
try {
|
||||
jPlugin.setEnabled(false);
|
||||
} catch (Throwable ex) {
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish
|
||||
server.getLogger().log(Level.SEVERE, "Error occurred while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish
|
||||
}
|
||||
|
||||
if (cloader instanceof PluginClassLoader) {
|
||||
@@ -0,0 +1,202 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 14:00:28 +0800
|
||||
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
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..856de1331b15542c00e01990f471fa5152722c11
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
@@ -0,0 +1,35 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import jdk.incubator.vector.FloatVector;
|
||||
+import jdk.incubator.vector.IntVector;
|
||||
+import jdk.incubator.vector.VectorSpecies;
|
||||
+import org.slf4j.Logger;
|
||||
+
|
||||
+/**
|
||||
+ * Basically, java is annoying and we have to push this out to its own class.
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class SIMDChecker {
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public static boolean canEnable(Logger logger) {
|
||||
+ try {
|
||||
+ SIMDDetection.testRun = true;
|
||||
+
|
||||
+ VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED;
|
||||
+ VectorSpecies<Float> FSPEC = FloatVector.SPECIES_PREFERRED;
|
||||
+
|
||||
+ logger.info("Max SIMD vector size on this system is {} bits (int)", ISPEC.vectorBitSize());
|
||||
+ logger.info("Max SIMD vector size on this system is " + FSPEC.vectorBitSize() + " bits (float)");
|
||||
+
|
||||
+ if (ISPEC.elementSize() < 2 || FSPEC.elementSize() < 2) {
|
||||
+ logger.warn("SIMD is not properly supported on this system!");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ } catch (NoClassDefFoundError | Exception ignored) {} // Basically, we don't do anything. This lets us detect if it's not functional and disable it.
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
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
|
||||
index 0000000000000000000000000000000000000000..0a64cd0e88083ac4af6674ad0fb07b771109c737
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import org.slf4j.Logger;
|
||||
+
|
||||
+@Deprecated
|
||||
+public class SIMDDetection {
|
||||
+
|
||||
+ public static boolean isEnabled = false;
|
||||
+ public static boolean testRun = false;
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public static boolean canEnable(Logger logger) {
|
||||
+ try {
|
||||
+ return SIMDChecker.canEnable(logger);
|
||||
+ } catch (NoClassDefFoundError | Exception ignored) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public static int getJavaVersion() {
|
||||
+ // https://stackoverflow.com/a/2591122
|
||||
+ String version = System.getProperty("java.version");
|
||||
+ if(version.startsWith("1.")) {
|
||||
+ version = version.substring(2, 3);
|
||||
+ } else {
|
||||
+ int dot = version.indexOf(".");
|
||||
+ if(dot != -1) { version = version.substring(0, dot); }
|
||||
+ }
|
||||
+ version = version.split("-")[0]; // Azul is stupid
|
||||
+ return Integer.parseInt(version);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
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;
|
||||
}
|
||||
|
||||
200
luminol-api/paper-patches/features/0007-Tick-regions-api.patch
Normal file
200
luminol-api/paper-patches/features/0007-Tick-regions-api.patch
Normal file
@@ -0,0 +1,200 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Mon, 27 Jan 2025 13:01:59 +0800
|
||||
Subject: [PATCH] Tick regions api
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/RegionStats.java b/src/main/java/me/earthme/luminol/api/RegionStats.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..96147cace1550d14c682258dab0397587dcf76a4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/RegionStats.java
|
||||
@@ -0,0 +1,25 @@
|
||||
+package me.earthme.luminol.api;
|
||||
+
|
||||
+/**
|
||||
+ * A simple package of folia's tick region state.It linked to the RegionStats of the nms part so that</br>
|
||||
+ * You could call these methods to get the status of this tick region</br>
|
||||
+ */
|
||||
+public interface RegionStats {
|
||||
+ /**
|
||||
+ * Get the entity count in this tick region
|
||||
+ * @return the entity count
|
||||
+ */
|
||||
+ int getEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the player count in this tick region
|
||||
+ * @return the player count
|
||||
+ */
|
||||
+ int getPlayerCount();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the chunk count in this tick region
|
||||
+ * @return the chunk count
|
||||
+ */
|
||||
+ int getChunkCount();
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/ThreadedRegion.java b/src/main/java/me/earthme/luminol/api/ThreadedRegion.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..38972ac3d05ccbbb134f751a8d018b9c53ad10b5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/ThreadedRegion.java
|
||||
@@ -0,0 +1,50 @@
|
||||
+package me.earthme.luminol.api;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.World;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * A mirror of folia's ThreadedRegion</br>
|
||||
+ * Including some handy methods to get the information of the tick region</br>
|
||||
+ * Note: You should call these methods inside this tick region's thread context
|
||||
+ */
|
||||
+public interface ThreadedRegion {
|
||||
+ /**
|
||||
+ * Get the center chunk pos of this tick region</br>
|
||||
+ * Note:</br>
|
||||
+ * 1.Global region will return a null value(But we don't finish the global region yet()</br>
|
||||
+ * 2.You should call these methods inside this tick region's thread context
|
||||
+ * @return The center chunk pos
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Location getCenterChunkPos();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the dead section percent of this tick region
|
||||
+ * Note: </br>
|
||||
+ * 1.Dead percent is mean the percent of the unloaded chunk count of this tick region, which is also used for determine
|
||||
+ * that the tick region should or not check for splitting</br>
|
||||
+ * 2.You should call these methods inside this tick region's thread context
|
||||
+ * @return The dead section percent
|
||||
+ */
|
||||
+ double getDeadSectionPercent();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the tick region data of this tick region</br>
|
||||
+ * Note:</br>
|
||||
+ * 1.You should call this method inside this tick region's thread context</br>
|
||||
+ * 2.You should call these methods inside this tick region's thread context
|
||||
+ * @return The tick region data
|
||||
+ */
|
||||
+ TickRegionData getTickRegionData();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the world of this tick region</br>
|
||||
+ * Note: Global region will return a null value too
|
||||
+ * @return The world of this tick region
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ World getWorld();
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/ThreadedRegionizer.java b/src/main/java/me/earthme/luminol/api/ThreadedRegionizer.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ff31a68a019fd9e5e687e6818f8729f4950bc060
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/ThreadedRegionizer.java
|
||||
@@ -0,0 +1,56 @@
|
||||
+package me.earthme.luminol.api;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+
|
||||
+/**
|
||||
+ * A mirror of folia's ThreadedRegionizer
|
||||
+ */
|
||||
+public interface ThreadedRegionizer {
|
||||
+ /**
|
||||
+ * Get all the tick regions
|
||||
+ * @return Temporary copied collection of all tick regions
|
||||
+ */
|
||||
+ Collection<ThreadedRegion> getAllRegions();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the tick region at the given chunk coordinates
|
||||
+ * @param chunkX Chunk X
|
||||
+ * @param chunkZ Chunk Z
|
||||
+ * @return The tick region at the given chunk coordinates
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ ThreadedRegion getAtSynchronized(int chunkX, int chunkZ);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the tick region at the given chunk coordinates
|
||||
+ * @param chunkX Chunk X
|
||||
+ * @param chunkZ Chunk Z
|
||||
+ * @return The tick region at the given chunk coordinates
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ ThreadedRegion getAtUnSynchronized(int chunkX, int chunkZ);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the tick region at the given location
|
||||
+ * @param pos The location
|
||||
+ * @return The tick region at the given location
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ default ThreadedRegion getAtSynchronized(@NotNull Location pos) {
|
||||
+ return this.getAtSynchronized(pos.getBlockX() >> 4, pos.getBlockZ() >> 4);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the tick region at the given location
|
||||
+ * @param pos The location
|
||||
+ * @return The tick region at the given location
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ default ThreadedRegion getAtUnSynchronized(@NotNull Location pos) {
|
||||
+ return this.getAtUnSynchronized(pos.getBlockX() >> 4, pos.getBlockZ() >> 4);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/TickRegionData.java b/src/main/java/me/earthme/luminol/api/TickRegionData.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ecde4462b08d701b8bff9f26902f17754cf791dd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/TickRegionData.java
|
||||
@@ -0,0 +1,26 @@
|
||||
+package me.earthme.luminol.api;
|
||||
+
|
||||
+import org.bukkit.World;
|
||||
+
|
||||
+/**
|
||||
+ * A mirror of folia's tick region data
|
||||
+ */
|
||||
+public interface TickRegionData {
|
||||
+ /**
|
||||
+ * Get the world it's currently holding
|
||||
+ * @return the world
|
||||
+ */
|
||||
+ World getWorld();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the current tick count
|
||||
+ * @return the current tick count
|
||||
+ */
|
||||
+ long getCurrentTickCount();
|
||||
+
|
||||
+ /**
|
||||
+ * Get the region stats
|
||||
+ * @return the region stats
|
||||
+ */
|
||||
+ RegionStats getRegionStats();
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 015d852d5a0c01042a2153a6916d408660356c59..c7b6f3f6c42746297816c0650571990f565d5e68 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -4432,4 +4432,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Luminol start - Tick regions api
|
||||
+ me.earthme.luminol.api.ThreadedRegionizer getThreadedRegionizer();
|
||||
+ // Luminol end - Tick regions api
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Thu, 30 Jan 2025 09:29:03 +0800
|
||||
Subject: [PATCH] Purpur Lobotomize stuck villagers
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java
|
||||
index 1db3742024e9cd1b70af2d52b4b756a544c019df..9c722a762c88a88bb5ef18c3b9eab8b371360dac 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Villager.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Villager.java
|
||||
@@ -367,4 +367,14 @@ public interface Villager extends AbstractVillager {
|
||||
*/
|
||||
public void clearReputations();
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+
|
||||
+ /**
|
||||
+ * Check if villager is currently lobotomized
|
||||
+ *
|
||||
+ * @return True if lobotomized
|
||||
+ */
|
||||
+ boolean isLobotomized();
|
||||
+ // Purpur end
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Fri, 31 Jan 2025 20:28:47 +0800
|
||||
Subject: [PATCH] Add missing teleportation apis for folia
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/entity/EntityTeleportAsyncEvent.java b/src/main/java/me/earthme/luminol/api/entity/EntityTeleportAsyncEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a31c803831dad3d31386924cbe27deff59855fc9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/entity/EntityTeleportAsyncEvent.java
|
||||
@@ -0,0 +1,68 @@
|
||||
+package me.earthme.luminol.api.entity;
|
||||
+
|
||||
+import org.apache.commons.lang3.Validate;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A simple event fired when a teleportAsync was called
|
||||
+ * @see org.bukkit.entity.Entity#teleportAsync(org.bukkit.Location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause)
|
||||
+ * @see org.bukkit.entity.Entity#teleportAsync(org.bukkit.Location)
|
||||
+ * (Also fired when teleportAsync called from nms)
|
||||
+ */
|
||||
+public class EntityTeleportAsyncEvent extends Event {
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ private final Entity entity;
|
||||
+ private final PlayerTeleportEvent.TeleportCause teleportCause;
|
||||
+ private final Location destination;
|
||||
+
|
||||
+ public EntityTeleportAsyncEvent(Entity entity, PlayerTeleportEvent.TeleportCause teleportCause, Location destination) {
|
||||
+ Validate.notNull(entity, "entity cannot be a null value!");
|
||||
+ Validate.notNull(teleportCause, "teleportCause cannot be a null value!");
|
||||
+ Validate.notNull(destination, "destination cannot be a null value!");
|
||||
+
|
||||
+ this.entity = entity;
|
||||
+ this.teleportCause = teleportCause;
|
||||
+ this.destination = destination;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the entity is about to be teleported
|
||||
+ * @return that entity
|
||||
+ */
|
||||
+ public @NotNull Entity getEntity() {
|
||||
+ return this.entity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the cause of the teleport
|
||||
+ * @return the cause
|
||||
+ */
|
||||
+ public @NotNull PlayerTeleportEvent.TeleportCause getTeleportCause() {
|
||||
+ return this.teleportCause;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the destination of the teleport
|
||||
+ * @return the destination
|
||||
+ */
|
||||
+ public @NotNull Location getDestination() {
|
||||
+ return this.destination;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/entity/PostEntityPortalEvent.java b/src/main/java/me/earthme/luminol/api/entity/PostEntityPortalEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..dd3087b407ccf4e96448701e6fbf75705498f982
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/entity/PostEntityPortalEvent.java
|
||||
@@ -0,0 +1,41 @@
|
||||
+package me.earthme.luminol.api.entity;
|
||||
+
|
||||
+import org.apache.commons.lang3.Validate;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A simple event created for missing teleport events api of folia
|
||||
+ * This event is fired when the entity portal process has been done
|
||||
+ */
|
||||
+public class PostEntityPortalEvent extends Event {
|
||||
+ private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
+
|
||||
+ private final Entity teleportedEntity;
|
||||
+
|
||||
+ public PostEntityPortalEvent(Entity teleportedEntity) {
|
||||
+ Validate.notNull(teleportedEntity, "teleportedEntity cannot be null!");
|
||||
+
|
||||
+ this.teleportedEntity = teleportedEntity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the entity which was teleported
|
||||
+ * @return the entity which was teleported
|
||||
+ */
|
||||
+ public Entity getTeleportedEntity() {
|
||||
+ return this.teleportedEntity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull HandlerList getHandlers() {
|
||||
+ return HANDLER_LIST;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLER_LIST;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/entity/PreEntityPortalEvent.java b/src/main/java/me/earthme/luminol/api/entity/PreEntityPortalEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fc844429e3ecfe2529c0a49b8a5d958eeb188ad9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/entity/PreEntityPortalEvent.java
|
||||
@@ -0,0 +1,78 @@
|
||||
+package me.earthme.luminol.api.entity;
|
||||
+
|
||||
+import org.apache.commons.lang3.Validate;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.World;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A simple event created for missing teleport events api of folia
|
||||
+ * This event will be fired when a portal teleportation is about to happen
|
||||
+ */
|
||||
+public class PreEntityPortalEvent extends Event implements Cancellable {
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ private final Entity entity;
|
||||
+ private final Location portalPos;
|
||||
+ private final World destination;
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ public PreEntityPortalEvent(Entity entity, Location portalPos, World destination) {
|
||||
+ Validate.notNull(entity, "entity cannot be null!");
|
||||
+ Validate.notNull(portalPos, "portalPos cannot be null!");
|
||||
+ Validate.notNull(destination, "destination cannot be null!");
|
||||
+
|
||||
+ this.entity = entity;
|
||||
+ this.portalPos = portalPos;
|
||||
+ this.destination = destination;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the entity that is about to teleport
|
||||
+ * @return the entity
|
||||
+ */
|
||||
+ public @NotNull Entity getEntity() {
|
||||
+ return this.entity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the location of the portal
|
||||
+ * @return the portal location
|
||||
+ */
|
||||
+ public @NotNull Location getPortalPos() {
|
||||
+ return this.portalPos;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the destination world
|
||||
+ * @return the destination world
|
||||
+ */
|
||||
+ public @NotNull World getDestination() {
|
||||
+ return this.destination;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/entity/player/PostPlayerRespawnEvent.java b/src/main/java/me/earthme/luminol/api/entity/player/PostPlayerRespawnEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9a561455560dfeee1d8762297ebf15a7c11de4d1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/entity/player/PostPlayerRespawnEvent.java
|
||||
@@ -0,0 +1,40 @@
|
||||
+package me.earthme.luminol.api.entity.player;
|
||||
+
|
||||
+import org.apache.commons.lang3.Validate;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A simple event fired when the respawn process of player is done
|
||||
+ */
|
||||
+public class PostPlayerRespawnEvent extends Event {
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ private final Player player;
|
||||
+
|
||||
+ public PostPlayerRespawnEvent(Player player) {
|
||||
+ Validate.notNull(player, "Player cannot be a null value!");
|
||||
+
|
||||
+ this.player = player;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the respawned player
|
||||
+ * @return the player
|
||||
+ */
|
||||
+ public @NotNull Player getPlayer() {
|
||||
+ return this.player;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/portal/EndPlatformCreateEvent.java b/src/main/java/me/earthme/luminol/api/portal/EndPlatformCreateEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cf87a7cce5d1ebec9709b762595609344807150b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/portal/EndPlatformCreateEvent.java
|
||||
@@ -0,0 +1,35 @@
|
||||
+package me.earthme.luminol.api.portal;
|
||||
+
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A event fired when an end platform is created.
|
||||
+ */
|
||||
+public class EndPlatformCreateEvent extends Event implements Cancellable {
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/portal/PortalLocateEvent.java b/src/main/java/me/earthme/luminol/api/portal/PortalLocateEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e09ffb99aad6f6acca3d6a411877715b90413eb0
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/portal/PortalLocateEvent.java
|
||||
@@ -0,0 +1,53 @@
|
||||
+package me.earthme.luminol.api.portal;
|
||||
+
|
||||
+import org.apache.commons.lang3.Validate;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * A event fired when the portal process started locating the destination position
|
||||
+ * Notice: If you changed the destination to an another position in end teleportation.The end platform won't create under the entity and won't create
|
||||
+ * if the position is out of current tick region
|
||||
+ */
|
||||
+public class PortalLocateEvent extends Event {
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ private final Location original;
|
||||
+ private final Location destination;
|
||||
+
|
||||
+ public PortalLocateEvent(Location original, Location destination) {
|
||||
+ Validate.notNull(original, "original couldn't be null!");
|
||||
+ Validate.notNull(destination, "destination couldn't be null!");
|
||||
+
|
||||
+ this.original = original;
|
||||
+ this.destination = destination;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the destination position of this teleportation
|
||||
+ * @return the destination position
|
||||
+ */
|
||||
+ public Location getDestination() {
|
||||
+ return this.destination;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the original portal position of this teleportation
|
||||
+ * @return the original portal position
|
||||
+ */
|
||||
+ public Location getOriginal() {
|
||||
+ return this.original;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
||||
120
luminol-server/build.gradle.kts.patch
Normal file
120
luminol-server/build.gradle.kts.patch
Normal file
@@ -0,0 +1,120 @@
|
||||
--- a/folia-server/build.gradle.kts
|
||||
+++ b/folia-server/build.gradle.kts
|
||||
@@ -20,8 +_,9 @@
|
||||
minecraftVersion = providers.gradleProperty("mcVersion")
|
||||
// macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java")
|
||||
// gitFilePatches = true
|
||||
-
|
||||
+
|
||||
val fork = forks.register("folia") {
|
||||
+ rootDirectory = upstreamsDirectory().map { it.dir("folia") }
|
||||
upstream.patchDir("paperServer") {
|
||||
upstreamPath = "paper-server"
|
||||
excludes = setOf("src/minecraft", "patches", "build.gradle.kts")
|
||||
@@ -30,7 +_,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
- activeFork = fork
|
||||
+ val luminol = forks.register("luminol") {
|
||||
+ forks = fork
|
||||
+ upstream.patchRepo("paperServer") {
|
||||
+ upstreamRepo = fork.patchedRepo("paperServer")
|
||||
+ patchesDir = rootDirectory.dir("luminol-server/paper-patches")
|
||||
+ outputDir = rootDirectory.dir("paper-server")
|
||||
+ }
|
||||
+
|
||||
+ upstream.patchDir("foliaServer") {
|
||||
+ upstreamPath = "folia-server"
|
||||
+ excludes = setOf("src/minecraft", "paper-patches", "minecraft-patches", "build.gradle.kts", "build.gradle.kts.patch")
|
||||
+ patchesDir = rootDirectory.dir("luminol-server/folia-patches")
|
||||
+ outputDir = rootDirectory.dir("folia-server")
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ activeFork = luminol
|
||||
|
||||
spigot {
|
||||
buildDataRef = "3edaf46ec1eed4115ce1b18d2846cded42577e42"
|
||||
@@ -116,10 +_,14 @@
|
||||
main {
|
||||
java { srcDir("../paper-server/src/main/java") }
|
||||
resources { srcDir("../paper-server/src/main/resources") }
|
||||
+ java { srcDir("../folia-server/src/main/java") }
|
||||
+ resources { srcDir("../folia-server/src/main/resources") }
|
||||
}
|
||||
test {
|
||||
java { srcDir("../paper-server/src/test/java") }
|
||||
resources { srcDir("../paper-server/src/test/resources") }
|
||||
+ java { srcDir("../folia-server/src/test/java") }
|
||||
+ resources { srcDir("../folia-server/src/test/resources") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +_,14 @@
|
||||
}
|
||||
|
||||
dependencies {
|
||||
- implementation(project(":folia-api"))
|
||||
+ implementation(project(":luminol-api")) // Luminol
|
||||
+ implementation("com.electronwill.night-config:toml:3.6.6") // Luminol - Night config
|
||||
+ // Abomination start
|
||||
+ implementation("com.github.luben:zstd-jni:1.5.4-1")
|
||||
+ implementation("org.lz4:lz4-java:1.8.0")
|
||||
+ implementation("net.openhft:zero-allocation-hashing:0.16")
|
||||
+ // Abomination end
|
||||
+ implementation("io.github.classgraph:classgraph:4.8.158") // Kaiiju - Entity throttling & Removal
|
||||
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-jni:3.27.1") // fall back to jni on java 21
|
||||
@@ -201,26 +_,33 @@
|
||||
implementation("me.lucko:spark-paper:1.10.119-20241121.092015-1")
|
||||
}
|
||||
|
||||
+// Pufferfish Start
|
||||
+tasks.withType<JavaCompile> {
|
||||
+ val compilerArgs = options.compilerArgs
|
||||
+ compilerArgs.add("--add-modules=jdk.incubator.vector")
|
||||
+}
|
||||
+// Pufferfish End
|
||||
+
|
||||
tasks.jar {
|
||||
manifest {
|
||||
val git = Git(rootProject.layout.projectDirectory.path)
|
||||
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()
|
||||
attributes(
|
||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||
- "Implementation-Title" to "Folia",
|
||||
+ "Implementation-Title" to "Luminol",
|
||||
"Implementation-Version" to implementationVersion,
|
||||
"Implementation-Vendor" to date,
|
||||
- "Specification-Title" to "Folia",
|
||||
+ "Specification-Title" to "Luminol",
|
||||
"Specification-Version" to project.version,
|
||||
- "Specification-Vendor" to "Paper Team",
|
||||
- "Brand-Id" to "papermc:folia",
|
||||
- "Brand-Name" to "Folia",
|
||||
+ "Specification-Vendor" to "Luminol Team",
|
||||
+ "Brand-Id" to "luminolmc:luminol",
|
||||
+ "Brand-Name" to "Luminol",
|
||||
"Build-Number" to (build ?: ""),
|
||||
"Build-Time" to buildTime.toString(),
|
||||
"Git-Branch" to gitBranch,
|
||||
@@ -351,3 +_,10 @@
|
||||
classpath(tasks.createReobfPaperclipJar.flatMap { it.outputZip })
|
||||
mainClass.set(null as String?)
|
||||
}
|
||||
+
|
||||
+// Pufferfish Start
|
||||
+tasks.withType<JavaCompile> {
|
||||
+ val compilerArgs = options.compilerArgs
|
||||
+ compilerArgs.add("--add-modules=jdk.incubator.vector")
|
||||
+}
|
||||
+// Pufferfish End
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <mrhua269@gmail.com>
|
||||
Date: Sat, 22 Mar 2025 17:36:17 +0800
|
||||
Subject: [PATCH] Luminol config base
|
||||
|
||||
|
||||
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 e3b7184e20bda4983ee1fc5463d91ca0cdd8ec1f..375f4a59333ee1d75fb1acb8c2cbada7866bd48e 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()) {
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:17:52 +0800
|
||||
Subject: [PATCH] Add config for server mod name
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index be82a6b43b1f0c644c53d08a6e16bc2876c8c1e0..9261d83f28af5e057d060741ab900f8cde8f992b 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1968,7 +1968,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@DontObfuscate
|
||||
public String getServerModName() {
|
||||
- return io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
|
||||
+ return me.earthme.luminol.config.modules.misc.ServerModNameConfig.fakeVanilla ? "vanilla" : me.earthme.luminol.config.modules.misc.ServerModNameConfig.serverModName; // Paper // Luminol - Add config for this
|
||||
}
|
||||
|
||||
public SystemReport fillSystemReport(SystemReport systemReport) {
|
||||
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:23:13 +0800
|
||||
Subject: [PATCH] Add config for unsafe teleportation
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/item/FallingBlockEntity.java b/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
index 1fa5e6a12b943e889bde566038a632a6adcf319e..c1f6a3b3a8fa990b8e9b052341ab31bde7c04e7a 100644
|
||||
--- a/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
@@ -65,7 +65,7 @@ public class FallingBlockEntity extends Entity {
|
||||
public float fallDamagePerDistance;
|
||||
@Nullable
|
||||
public CompoundTag blockData;
|
||||
- public boolean forceTickAfterTeleportToDuplicate;
|
||||
+ public boolean forceTickAfterTeleportToDuplicate = me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled; // Luminol - Unsafe teleportation
|
||||
protected static final EntityDataAccessor<BlockPos> DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS);
|
||||
public boolean autoExpire = true; // Paper - Expand FallingBlock API
|
||||
|
||||
@@ -401,7 +401,7 @@ public class FallingBlockEntity extends Entity {
|
||||
ResourceKey<Level> resourceKey1 = this.level().dimension();
|
||||
boolean flag = (resourceKey1 == Level.END || resourceKey == Level.END) && resourceKey1 != resourceKey;
|
||||
Entity entity = super.teleport(teleportTransition);
|
||||
- this.forceTickAfterTeleportToDuplicate = entity != null && flag && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation; // Paper
|
||||
+ this.forceTickAfterTeleportToDuplicate = entity != null && flag && (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation || me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled); // Paper // Luminol - Unsafe teleportation
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/EndPortalBlock.java b/net/minecraft/world/level/block/EndPortalBlock.java
|
||||
index 554d75ac1374d7d93977a10e06fcf51259830c97..17c1ce4397c5953bb92aaa3b56c179b7c24a0736 100644
|
||||
--- a/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 {
|
||||
if (level.paperConfig().misc.disableEndCredits) {serverPlayer.seenCredits = true; return;} // Paper - Option to disable end credits
|
||||
serverPlayer.showEndCredits();
|
||||
} else {
|
||||
+ // Luminol start - unsafe teleportation
|
||||
+ if (me.earthme.luminol.config.modules.fixes.UnsafeTeleportationConfig.enabled && !(entity instanceof net.minecraft.world.entity.player.Player)) {
|
||||
+ entity.endPortalLogicAsync(pos);
|
||||
+ }
|
||||
+ // Luminol end
|
||||
entity.setAsInsidePortal(this, pos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:24:50 +0800
|
||||
Subject: [PATCH] Add config for vanilla random
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 2cd2ce1060f567be6c72b7bc9d02651ec7166203..f69fd922fa67cd366dbb93c34fa15659ba76c844 100644
|
||||
--- a/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
|
||||
public double zOld;
|
||||
public boolean noPhysics;
|
||||
private boolean wasOnFire;
|
||||
- public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random
|
||||
+ public final RandomSource random = me.earthme.luminol.config.modules.fixes.VanillaRandomSourceConfig.useLegacyRandomSourceForPlayers ? RandomSource.create() : SHARED_RANDOM; // Paper - Share random for entities to make them more random // Luminol - Add config for vanilla random SHARED_RANDOM
|
||||
public int tickCount;
|
||||
private int remainingFireTicks = -this.getFireImmuneTicks();
|
||||
public boolean wasTouchingWater;
|
||||
@@ -0,0 +1,339 @@
|
||||
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 tpsbar with chunkhot membar and regionbar
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
index 8d67b4629c69d3039b199aaad45533d1acde114e..f7bfeca4b11b9860241d5eb80b6df420868c7bea 100644
|
||||
--- a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
+++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
@@ -136,6 +136,7 @@ public abstract class BaseChunkSystemHooks implements ca.spottedleaf.moonrise.co
|
||||
|
||||
@Override
|
||||
public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+ chunk.getChunkHot().clear(); // KioCG
|
||||
chunk.getLevel().getCurrentWorldData().removeTickingChunk(chunk.moonrise$getChunkAndHolder()); // Folia - region threading
|
||||
((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
|
||||
index 9261d83f28af5e057d060741ab900f8cde8f992b..fc088edaa36e7e68ddd23c57e351ef3b31ed5ad8 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1666,7 +1666,44 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia end - region threading
|
||||
//this.tickCount++; // Folia - region threading
|
||||
//this.tickRateManager.tick(); // Folia - region threading
|
||||
+ // KioCG start - ChunkHot
|
||||
+ final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<net.minecraft.world.level.chunk.LevelChunk> chunks = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>();
|
||||
+ if (region != null){
|
||||
+ for (net.minecraft.server.level.ServerChunkCache.ChunkAndHolder chunkAndHolder : region.world.getCurrentWorldData().getTickingChunks()){
|
||||
+ final net.minecraft.world.level.chunk.LevelChunk chunk = chunkAndHolder.chunk();
|
||||
+
|
||||
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(region.world, chunk.locX, chunk.locZ)){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ chunks.add(chunk);
|
||||
+ }
|
||||
+ }
|
||||
+ if (region != null && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % 20 == 0){
|
||||
+ final java.util.Iterator<net.minecraft.world.level.chunk.LevelChunk> chunkIterator = chunks.unsafeIterator();
|
||||
+ while (chunkIterator.hasNext()){
|
||||
+ final net.minecraft.world.level.chunk.LevelChunk targetChunk = chunkIterator.next();
|
||||
+
|
||||
+ targetChunk.getChunkHot().nextTick();
|
||||
+ targetChunk.getChunkHot().start();
|
||||
+ }
|
||||
+ }
|
||||
+ //KioCG end
|
||||
this.tickChildren(hasTimeLeft, region); // Folia - region threading
|
||||
+ // KioCG start - ChunkHot
|
||||
+ if (region != null && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % 20 == 0){
|
||||
+ final java.util.Iterator<net.minecraft.world.level.chunk.LevelChunk> chunkIterator = chunks.unsafeIterator();
|
||||
+ while (chunkIterator.hasNext()){
|
||||
+ final net.minecraft.world.level.chunk.LevelChunk targetChunk = chunkIterator.next();
|
||||
+
|
||||
+ if (!targetChunk.getChunkHot().isStarted()){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ targetChunk.getChunkHot().stop();
|
||||
+ }
|
||||
+ }
|
||||
+ //KioCG end
|
||||
if (false && nanos - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) { // Folia - region threading
|
||||
this.lastServerStatus = nanos;
|
||||
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
|
||||
index f2d2ddfd964bff914e41c0b4150fe1aad7866ebf..7defcd15c44601bfd2f7f55046038693264defee 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1339,6 +1339,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
|
||||
profiler.startTimer(timerId);
|
||||
+ LevelChunk levelChunk = entity.shouldTickHot() ? this.getChunkIfLoaded(entity.moonrise$getSectionX(),entity.moonrise$getSectionZ()) : null; // KioCG
|
||||
+ if (levelChunk != null) levelChunk.getChunkHot().startTicking(); try { // KioCG
|
||||
try {
|
||||
// Folia end - profiler
|
||||
if (isActive) { // Paper - EAR 2
|
||||
@@ -1356,6 +1358,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
} else {entity.inactiveTick();} // Paper - EAR 2
|
||||
profilerFiller.pop();
|
||||
} finally { profiler.stopTimer(timerId); } // Folia - profiler
|
||||
+ } finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
|
||||
|
||||
for (Entity entity1 : entity.getPassengers()) {
|
||||
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
|
||||
@@ -1375,6 +1378,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
final int timerId = isActive ? passengerEntity.getType().tickTimerId : passengerEntity.getType().inactiveTickTimerId;
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
|
||||
profiler.startTimer(timerId);
|
||||
+ LevelChunk levelChunk = !(passengerEntity instanceof Player) ? this.getChunkIfLoaded(passengerEntity.blockPosition()) : null; // KioCG
|
||||
+ if (levelChunk != null) levelChunk.getChunkHot().startTicking(); try { // KioCG
|
||||
try {
|
||||
// Folia end - profiler
|
||||
passengerEntity.setOldPosAndRot();
|
||||
@@ -1409,6 +1414,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2
|
||||
}
|
||||
} finally { profiler.stopTimer(timerId); } // Folia - profiler
|
||||
+ } finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index dbf9231b1f01576906b90a3ddf0bf2cbbeb4590a..b17ace9118c94a756fa2901621c6b2b9bd9e5764 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -400,7 +400,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();
|
||||
@@ -1013,8 +1015,35 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.trackEnteredOrExitedLavaOnVehicle();
|
||||
this.updatePlayerAttributes();
|
||||
this.advancements.flushDirty(this);
|
||||
+
|
||||
+ // KioCG start - ChunkHot
|
||||
+ if (this.tickCount % 20 == 0){
|
||||
+ this.nearbyChunkHot = this.refreshNearbyChunkHot();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
|
||||
+ // KioCG start - ChunkHot
|
||||
+ private volatile long nearbyChunkHot = 0;
|
||||
+
|
||||
+ public long getNearbyChunkHot() { return this.nearbyChunkHot; }
|
||||
+
|
||||
+ private long refreshNearbyChunkHot() {
|
||||
+ long total = 0L;
|
||||
+ int searchRadius = ((ServerLevel) this.level()).moonrise$getViewDistanceHolder().getViewDistances().tickViewDistance();
|
||||
+ for (int i = this.moonrise$getSectionX() - searchRadius; i <= this.moonrise$getSectionX() + searchRadius; ++i) {
|
||||
+ for (int j = this.moonrise$getSectionZ() - searchRadius; j <= this.moonrise$getSectionZ() + searchRadius; ++j) {
|
||||
+ net.minecraft.world.level.chunk.LevelChunk targetChunk = this.level().getChunkIfLoaded(i, j);
|
||||
+ if (targetChunk != null) {
|
||||
+ total += targetChunk.getChunkHot().getAverage();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return total;
|
||||
+ }
|
||||
+ // KioCG end
|
||||
+
|
||||
+
|
||||
private void updatePlayerAttributes() {
|
||||
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
|
||||
index 23b342cc31c7e72ade0e1ccad86a9ccf34380f13..249cb7326c8e4012dcffdb6bbb7bfc1f1eeb7b33 100644
|
||||
--- a/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
@@ -415,4 +415,11 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
|
||||
public final boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index f69fd922fa67cd366dbb93c34fa15659ba76c844..cc8efa162fbe7ce6a91629239bf18d7b6b096a8a 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -5919,4 +5919,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition());
|
||||
}
|
||||
// Paper end - Expose entity id counter
|
||||
+
|
||||
+ public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/LightningBolt.java b/net/minecraft/world/entity/LightningBolt.java
|
||||
index f003a65b34027dff14455860815c7d719c5289fa..6f9f8e52d2311343a0c0c3900a466c6a84f7de73 100644
|
||||
--- a/net/minecraft/world/entity/LightningBolt.java
|
||||
+++ b/net/minecraft/world/entity/LightningBolt.java
|
||||
@@ -287,4 +287,11 @@ public class LightningBolt extends Entity {
|
||||
public final boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index da922d4c0ffa0f40d5e8dd69487bf30dbbbeed87..94a7b95f41c2954561f9c3cb0f61210c0c058f1d 100644
|
||||
--- a/net/minecraft/world/entity/Mob.java
|
||||
+++ b/net/minecraft/world/entity/Mob.java
|
||||
@@ -1722,4 +1722,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||
public float[] getArmorDropChances() {
|
||||
return this.armorDropChances;
|
||||
}
|
||||
+
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return super.shouldTickHot() && (!this.removeWhenFarAway(0.0) || this.isPersistenceRequired() || this.requiresCustomPersistence());
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/animal/horse/TraderLlama.java b/net/minecraft/world/entity/animal/horse/TraderLlama.java
|
||||
index c5b11a63bb2ab660efcc386ad9b4697e2a5efc97..f139822cb3e90b9d5fac6971e2ef1a8569d9849b 100644
|
||||
--- a/net/minecraft/world/entity/animal/horse/TraderLlama.java
|
||||
+++ b/net/minecraft/world/entity/animal/horse/TraderLlama.java
|
||||
@@ -157,4 +157,11 @@ public class TraderLlama extends Llama {
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return super.shouldTickHot() && !this.canDespawn();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
index 6655d06e2011e20e7346dfe57527795269094d8a..48aa6fcb5c16fdbb4ae902cbb72c6b8e02820c88 100644
|
||||
--- a/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
+++ b/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
@@ -320,4 +320,11 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
|
||||
return !pos.closerToCenterThan(this.trader.position(), distance);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index e70919757dee4b02384ded3551c8f580d289584a..ae049c5c3593525b991d865fec695c00ad408a59 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1546,6 +1546,13 @@ public abstract class Player extends LivingEntity {
|
||||
return true;
|
||||
}
|
||||
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // KioCG end
|
||||
+
|
||||
public Either<Player.BedSleepingProblem, Unit> startSleepInBed(BlockPos bedPos) {
|
||||
// CraftBukkit start
|
||||
return this.startSleepInBed(bedPos, false);
|
||||
diff --git a/net/minecraft/world/entity/projectile/Projectile.java b/net/minecraft/world/entity/projectile/Projectile.java
|
||||
index abfe6765faec49d4b8897608582d738c7b09522d..6e1de9252ac1236e0c5196e2511c72c0d7eb3502 100644
|
||||
--- a/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -516,4 +516,11 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
public interface ProjectileFactory<T extends Projectile> {
|
||||
T create(ServerLevel level, LivingEntity owner, ItemStack spawnedFrom);
|
||||
}
|
||||
+
|
||||
+ // KioCG start
|
||||
+ @Override
|
||||
+ public boolean shouldTickHot() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 78211c68bf52c0cd402fee7bcdde223130d49b5c..83b0e91165024697f6b7d41d43142b2b33641968 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -103,6 +103,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
// Paper start - rewrite chunk system
|
||||
private boolean postProcessingDone;
|
||||
private net.minecraft.server.level.ServerChunkCache.ChunkAndHolder chunkAndHolder;
|
||||
+ private final com.kiocg.ChunkHot chunkHot = new com.kiocg.ChunkHot(); public com.kiocg.ChunkHot getChunkHot() { return this.chunkHot; } // KioCG
|
||||
|
||||
@Override
|
||||
public final boolean moonrise$isPostProcessingDone() {
|
||||
@@ -926,6 +927,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
try {
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push(this::getType);
|
||||
+ LevelChunk.this.chunkHot.startTicking(); // KioCG
|
||||
profiler.startTimer(timerId); try { // Folia - profiler
|
||||
BlockState blockState = LevelChunk.this.getBlockState(blockPos);
|
||||
if (this.blockEntity.getType().isValid(blockState)) {
|
||||
@@ -940,7 +942,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
}
|
||||
// Paper end - Remove the Block Entity if it's invalid
|
||||
}
|
||||
- } finally { profiler.stopTimer(timerId); } // Folia - profiler
|
||||
+ } finally { profiler.stopTimer(timerId); LevelChunk.this.chunkHot.stopTickingAndCount(); } // Folia - profiler // KioCG
|
||||
|
||||
profilerFiller.pop();
|
||||
} catch (Throwable var5) {
|
||||
diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
index 26c15c60d358273a3b369c286771c81d6f0979dd..715580a893ba9dd34ee562b81350b81f9da3f905 100644
|
||||
--- a/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
+++ b/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
@@ -60,7 +60,10 @@ public interface NeighborUpdater {
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ net.minecraft.world.level.chunk.LevelChunk levelChunk = level.getChunkIfLoaded(pos); // KioCG
|
||||
+ if (levelChunk != null) levelChunk.getChunkHot().startTicking(); try { // KioCG
|
||||
state.handleNeighborChanged(level, pos, neighborBlock, orientation, movedByPiston);
|
||||
+ } finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
|
||||
// Spigot start
|
||||
} catch (StackOverflowError ex) {
|
||||
level.lastPhysicsProblem = new BlockPos(pos);
|
||||
@@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:29:26 +0800
|
||||
Subject: [PATCH] Add config for username check
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 159f2f169d26b436a70006f7bc9bdc481315dd32..2b366fea4d8d376b150786fdc00fd5e2413388f6 100644
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -176,7 +176,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
public void handleHello(ServerboundHelloPacket packet) {
|
||||
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet");
|
||||
// Paper start - Validate usernames
|
||||
- if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
|
||||
+ if (me.earthme.luminol.config.modules.misc.UsernameCheckConfig.enabled // Luminol - Add config for username check
|
||||
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()
|
||||
&& io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation
|
||||
&& !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) {
|
||||
Validate.validState(StringUtil.isReasonablePlayerName(packet.name()), "Invalid characters in username");
|
||||
diff --git a/net/minecraft/server/players/GameProfileCache.java b/net/minecraft/server/players/GameProfileCache.java
|
||||
index 6fb3712f33a84a3612752dcfd9e97d67066f610e..1999188b5667035362ba579a80b30336c5c7fc38 100644
|
||||
--- a/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -77,7 +77,7 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
private static Optional<GameProfile> lookupGameProfile(GameProfileRepository profileRepo, String name) {
|
||||
- if (!StringUtil.isValidPlayerName(name)) {
|
||||
+ if (!StringUtil.isValidPlayerName(name, false)) { // Luminol - Add config for username check - Directly return, skip unnecessary following logic
|
||||
return createUnknownProfile(name);
|
||||
} else {
|
||||
final AtomicReference<GameProfile> atomicReference = new AtomicReference<>();
|
||||
diff --git a/net/minecraft/util/StringUtil.java b/net/minecraft/util/StringUtil.java
|
||||
index 77947e6915facee44588943fcd3e5b513de37e77..d9f95c5cf4bd2946244c153db0fd21c8d51ae20d 100644
|
||||
--- a/net/minecraft/util/StringUtil.java
|
||||
+++ b/net/minecraft/util/StringUtil.java
|
||||
@@ -62,8 +62,14 @@ public class StringUtil {
|
||||
public static boolean isAllowedChatCharacter(char character) {
|
||||
return character != 167 && character >= ' ' && character != 127;
|
||||
}
|
||||
+ // Luminol start - Add config for username checks
|
||||
+ public static boolean isValidPlayerName(String username){
|
||||
+ return isValidPlayerName(username, !me.earthme.luminol.config.modules.misc.UsernameCheckConfig.enabled);
|
||||
+ }
|
||||
+ // Luminol end
|
||||
|
||||
- public static boolean isValidPlayerName(String playerName) {
|
||||
+ public static boolean isValidPlayerName(String playerName, boolean byPass) { // Luminol - Add config for username checks
|
||||
+ if (byPass) return playerName.length() <= 16; // Luminol - Add config for username checks
|
||||
return playerName.length() <= 16 && playerName.chars().filter(i -> i <= 32 || i >= 127).findAny().isEmpty();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
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/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 3abe2881e8a80bd6c128e96b976deebe3ada4678..a0a8b0c7d091f63f023f15a2620b03ae2126782e 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -285,7 +285,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
|
||||
String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";
|
||||
// Paper end - Add Velocity IP Forwarding Support
|
||||
- if (!this.usesAuthentication()) {
|
||||
+ if (!this.usesAuthentication() && me.earthme.luminol.config.modules.misc.OfflineModeWarningConfig.enabled) { //Luminol - Add config for offline mod warning
|
||||
LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
|
||||
LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
|
||||
// Spigot start
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:30:02 +0800
|
||||
Subject: [PATCH] Add config for out-of-order chat checks
|
||||
|
||||
|
||||
diff --git a/net/minecraft/network/chat/SignedMessageChain.java b/net/minecraft/network/chat/SignedMessageChain.java
|
||||
index f6eed34b2fd72ab74cc9dc4b99ca184d512c0a66..73ef2de5efa8fb48975f70998195df76f6161d16 100644
|
||||
--- a/net/minecraft/network/chat/SignedMessageChain.java
|
||||
+++ b/net/minecraft/network/chat/SignedMessageChain.java
|
||||
@@ -45,7 +45,7 @@ public class SignedMessageChain {
|
||||
SignedMessageLink signedMessageLink = SignedMessageChain.this.nextLink;
|
||||
if (signedMessageLink == null) {
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN);
|
||||
- } else if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) {
|
||||
+ } else if (me.earthme.luminol.config.modules.misc.InorderChatConfig.enabled && body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { // Luminol - Add config for out-of-order chat checks
|
||||
this.setChainBroken();
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes
|
||||
} else {
|
||||
@@ -0,0 +1,19 @@
|
||||
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/net/minecraft/world/entity/player/ProfilePublicKey.java b/net/minecraft/world/entity/player/ProfilePublicKey.java
|
||||
index 41a9cc693183e96c83837692e93b177a521d6789..f4a2d1a2d467808b9cb75fc32765ddc27be5fdba 100644
|
||||
--- a/net/minecraft/world/entity/player/ProfilePublicKey.java
|
||||
+++ b/net/minecraft/world/entity/player/ProfilePublicKey.java
|
||||
@@ -23,7 +23,7 @@ public record ProfilePublicKey(ProfilePublicKey.Data data) {
|
||||
public static final Codec<ProfilePublicKey> TRUSTED_CODEC = ProfilePublicKey.Data.CODEC.xmap(ProfilePublicKey::new, ProfilePublicKey::data);
|
||||
|
||||
public static ProfilePublicKey createValidated(SignatureValidator signatureValidator, UUID profileId, ProfilePublicKey.Data data) throws ProfilePublicKey.ValidationException {
|
||||
- if (!data.validateSignature(signatureValidator, profileId)) {
|
||||
+ if (!data.validateSignature(signatureValidator, profileId) && (org.bukkit.Bukkit.getServer().getOnlineMode() && me.earthme.luminol.config.modules.misc.PublickeyVerifyConfig.enabled)) { // Luminol - Verify signature only in online-mode
|
||||
throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE, org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PUBLIC_KEY_SIGNATURE); // Paper - kick event causes
|
||||
} else {
|
||||
return new ProfilePublicKey(data);
|
||||
@@ -0,0 +1,18 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:35:13 +0800
|
||||
Subject: [PATCH] Add config to disable entity tick catchers
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 78f4dd7032d18b8e020a4576e4ac012c1d472e67..120e25ca0544980d1bfc1498e1386f965dae7044 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1547,6 +1547,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
try {
|
||||
consumerEntity.accept(entity);
|
||||
} catch (Throwable var6) {
|
||||
+ if (me.earthme.luminol.config.modules.experiment.DisableEntityCatchConfig.enabled) throw var6; // Luminol
|
||||
// Paper start - Prevent block entity and entity crashes
|
||||
final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
|
||||
MinecraftServer.LOGGER.error(msg, var6);
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:51:21 +0800
|
||||
Subject: [PATCH] Add config for watchdog timeout
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/FoliaWatchdogThread.java b/io/papermc/paper/threadedregions/FoliaWatchdogThread.java
|
||||
index 258d82ab2c78482e1561343e8e1f81fc33f1895e..967107c0f4a18a29877883ccddb4d7962f4b5788 100644
|
||||
--- a/io/papermc/paper/threadedregions/FoliaWatchdogThread.java
|
||||
+++ b/io/papermc/paper/threadedregions/FoliaWatchdogThread.java
|
||||
@@ -65,7 +65,7 @@ public final class FoliaWatchdogThread extends Thread {
|
||||
|
||||
for (final RunningTick tick : ticks) {
|
||||
final long elapsed = now - tick.lastPrint;
|
||||
- if (elapsed <= TimeUnit.SECONDS.toNanos(5L)) {
|
||||
+ if (elapsed <= TimeUnit.MILLISECONDS.toNanos(me.earthme.luminol.config.modules.misc.FoliaWatchogConfig.tickRegionTimeOutMs)) { // Luminol - Add config for watchdog timeout
|
||||
continue;
|
||||
}
|
||||
tick.lastPrint = now;
|
||||
@@ -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] Add config for 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:36:31 +0800
|
||||
Subject: [PATCH] Add experiment config for command block command execution
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/BaseCommandBlock.java b/net/minecraft/world/level/BaseCommandBlock.java
|
||||
index b02b79ccedb8b87bc22270377dfc36e21ebe1724..3786e8288c3a66a5e986ae2a150d03ce2dd5ed16 100644
|
||||
--- a/net/minecraft/world/level/BaseCommandBlock.java
|
||||
+++ b/net/minecraft/world/level/BaseCommandBlock.java
|
||||
@@ -114,7 +114,7 @@ public abstract class BaseCommandBlock implements CommandSource {
|
||||
}
|
||||
|
||||
public boolean performCommand(Level level) {
|
||||
- if (true) return false; // Folia - region threading
|
||||
+ if (!me.earthme.luminol.config.modules.experiment.CommandBlockConfig.enabled) return false; // Folia - region threading // Luminol
|
||||
if (level.isClientSide || level.getGameTime() == this.lastExecution) {
|
||||
return false;
|
||||
} else if ("Searge".equalsIgnoreCase(this.command)) {
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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 experiment config for force enabling data command
|
||||
|
||||
|
||||
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);
|
||||
@@ -0,0 +1,381 @@
|
||||
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/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
|
||||
index a814512fcfb85312474ae2c2c21443843bf57831..2e084a5b28cbe4737f48c25e10af589213525362 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
|
||||
@@ -8,9 +8,9 @@ public interface ChunkSystemRegionFileStorage {
|
||||
|
||||
public boolean moonrise$doesRegionFileNotExistNoIO(final int chunkX, final int chunkZ);
|
||||
|
||||
- public RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ);
|
||||
+ public abomination.IRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ); // Luminol - Configurable region file format
|
||||
|
||||
- public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException;
|
||||
+ public abomination.IRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; // Luminol - Configurable region file format
|
||||
|
||||
public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(
|
||||
final int chunkX, final int chunkZ, final CompoundTag compound
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||
index 98fbc5c8044bd945d64569f13412a6e7e49a4e7f..9709d60d3b2a5478cd6c711669e32f28ac105667 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||
@@ -1260,7 +1260,7 @@ public final class MoonriseRegionFileIO {
|
||||
this.regionDataController.finishWrite(this.chunkX, this.chunkZ, writeData);
|
||||
// Paper start - flush regionfiles on save
|
||||
if (this.world.paperConfig().chunks.flushRegionsOnSave) {
|
||||
- final RegionFile regionFile = this.regionDataController.getCache().moonrise$getRegionFileIfLoaded(this.chunkX, this.chunkZ);
|
||||
+ final abomination.IRegionFile regionFile = this.regionDataController.getCache().moonrise$getRegionFileIfLoaded(this.chunkX, this.chunkZ); // Luminol - Add configurable region file
|
||||
if (regionFile != null) {
|
||||
regionFile.flush();
|
||||
} // else: evicted from cache, which should have called flush
|
||||
@@ -1470,7 +1470,7 @@ public final class MoonriseRegionFileIO {
|
||||
|
||||
public static interface IORunnable {
|
||||
|
||||
- public void run(final RegionFile regionFile) throws IOException;
|
||||
+ public void run(final abomination.IRegionFile regionFile) throws IOException; // Luminol - Configurable region file format
|
||||
|
||||
}
|
||||
}
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java b/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java
|
||||
index 51c126735ace8fdde89ad97b5cab62f244212db0..c7d4d944eb198ac53a3eeae717a25c7d5815c8c1 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/storage/ChunkSystemChunkBuffer.java
|
||||
@@ -8,5 +8,5 @@ public interface ChunkSystemChunkBuffer {
|
||||
|
||||
public void moonrise$setWriteOnClose(final boolean value);
|
||||
|
||||
- public void moonrise$write(final RegionFile regionFile) throws IOException;
|
||||
+ 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
|
||||
index fc088edaa36e7e68ddd23c57e351ef3b31ed5ad8..5d709b3b47702e7607dafa4a38380c801b228e2d 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -986,10 +986,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// CraftBukkit end
|
||||
if (flush) {
|
||||
for (ServerLevel serverLevel2 : this.getAllLevels()) {
|
||||
- LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName());
|
||||
+ LOGGER.info("ThreadedChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName()); // Luminol - configurable region format
|
||||
}
|
||||
|
||||
- LOGGER.info("ThreadedAnvilChunkStorage: All dimensions are saved");
|
||||
+ LOGGER.info("ThreadedChunkStorage: All dimensions are saved"); // Luminol - configurable region format
|
||||
}
|
||||
|
||||
return flag;
|
||||
diff --git a/net/minecraft/util/worldupdate/WorldUpgrader.java b/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
index e0bcda2ddea0d6633445a7440fbf0d18e50a7653..57ed3f61b265fc5c231ef0f2b7c4d33b4f3f6cba 100644
|
||||
--- a/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
+++ b/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
@@ -72,7 +72,7 @@ public class WorldUpgrader implements AutoCloseable {
|
||||
volatile int skipped;
|
||||
final Reference2FloatMap<ResourceKey<Level>> progressMap = Reference2FloatMaps.synchronize(new Reference2FloatOpenHashMap<>());
|
||||
volatile Component status = Component.translatable("optimizeWorld.stage.counting");
|
||||
- static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$");
|
||||
+ static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\\\"+ net.minecraft.world.level.chunk.storage.RegionFileStorage.getExtensionName() +"$"); // Luminol - Configurable region file format
|
||||
final DimensionDataStorage overworldDataStorage;
|
||||
|
||||
public WorldUpgrader(
|
||||
@@ -261,7 +261,7 @@ public class WorldUpgrader implements AutoCloseable {
|
||||
}
|
||||
|
||||
private static List<WorldUpgrader.FileToUpgrade> getAllChunkPositions(RegionStorageInfo regionStorageInfo, Path path) {
|
||||
- File[] files = path.toFile().listFiles((directory, filename) -> filename.endsWith(".mca"));
|
||||
+ File[] files = path.toFile().listFiles((directory, filename) -> filename.endsWith(net.minecraft.world.level.chunk.storage.RegionFileStorage.getExtensionName())); // Luminol - Configurable region file format
|
||||
if (files == null) {
|
||||
return List.of();
|
||||
} else {
|
||||
@@ -274,7 +274,7 @@ public class WorldUpgrader implements AutoCloseable {
|
||||
int i1 = Integer.parseInt(matcher.group(2)) << 5;
|
||||
List<ChunkPos> list1 = Lists.newArrayList();
|
||||
|
||||
- try (RegionFile regionFile = new RegionFile(regionStorageInfo, file.toPath(), path, true)) {
|
||||
+ try (abomination.IRegionFile regionFile = net.minecraft.world.level.chunk.storage.RegionFileStorage.createNew(regionStorageInfo, file.toPath(), path, true)) { // Luminol - Configurable region file format
|
||||
for (int i2 = 0; i2 < 32; i2++) {
|
||||
for (int i3 = 0; i3 < 32; i3++) {
|
||||
ChunkPos chunkPos = new ChunkPos(i2 + i, i3 + i1);
|
||||
@@ -322,7 +322,7 @@ public class WorldUpgrader implements AutoCloseable {
|
||||
|
||||
protected abstract boolean tryProcessOnePosition(T chunkStorage, ChunkPos chunkPos, ResourceKey<Level> dimension);
|
||||
|
||||
- private void onFileFinished(RegionFile regionFile) {
|
||||
+ private void onFileFinished(abomination.IRegionFile regionFile) { // Luminol - Configurable region file format
|
||||
if (WorldUpgrader.this.recreateRegionFiles) {
|
||||
if (this.previousWriteFuture != null) {
|
||||
this.previousWriteFuture.join();
|
||||
@@ -424,7 +424,7 @@ public class WorldUpgrader implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
- record FileToUpgrade(RegionFile file, List<ChunkPos> chunksToUpgrade) {
|
||||
+ record FileToUpgrade(abomination.IRegionFile file, List<ChunkPos> chunksToUpgrade) { // Luminol - Configurable region file format
|
||||
}
|
||||
|
||||
class PoiUpgrader extends WorldUpgrader.SimpleRegionStorageUpgrader {
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 0c41177462cca5c4bbab6490e323b9535fd6300f..39b3c3ca7248fe60833f04aee89c8851b21d5008 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
-public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system
|
||||
+public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile , abomination.IRegionFile{ // Paper - rewrite chunk system // Luminol - Configurable region file format
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Paper - don't write garbage data to disk if writing serialization fails
|
||||
private static final int SECTOR_BYTES = 4096;
|
||||
@@ -124,7 +124,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||
}
|
||||
|
||||
// note: only call for CHUNK regionfiles
|
||||
- boolean recalculateHeader() throws IOException {
|
||||
+ public boolean recalculateHeader() throws IOException { // Luminol - Configurable region file format // Luminol - Configurable region file format
|
||||
if (!this.canRecalcHeader) {
|
||||
return false;
|
||||
}
|
||||
@@ -786,7 +786,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||
}
|
||||
}
|
||||
|
||||
- protected synchronized void write(ChunkPos chunkPos, ByteBuffer chunkData) throws IOException {
|
||||
+ public synchronized void write(ChunkPos chunkPos, ByteBuffer chunkData) throws IOException { // Luminol - Configurable region file format
|
||||
int offsetIndex = getOffsetIndex(chunkPos);
|
||||
int i = this.offsets.get(offsetIndex);
|
||||
int sectorNumber = getSectorNumber(i);
|
||||
@@ -904,7 +904,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||
}
|
||||
|
||||
@Override
|
||||
- public final void moonrise$write(final RegionFile regionFile) throws IOException {
|
||||
+ public final void moonrise$write(final abomination.IRegionFile regionFile) throws IOException { // Luminol - Configurable region file format
|
||||
regionFile.write(this.pos, ByteBuffer.wrap(this.buf, 0, this.count));
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
@@ -970,11 +970,11 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||
return (x & 31) + (z & 31) * 32;
|
||||
}
|
||||
|
||||
- synchronized boolean isOversized(int x, int z) {
|
||||
+ public synchronized boolean isOversized(int x, int z) { // Luminol - Configurable region file format
|
||||
return this.oversized[getChunkIndex(x, z)] == 1;
|
||||
}
|
||||
|
||||
- synchronized void setOversized(int x, int z, boolean oversized) throws IOException {
|
||||
+ public synchronized void setOversized(int x, int z, boolean oversized) throws IOException { // Luminol - Configurable region file format
|
||||
final int offset = getChunkIndex(x, z);
|
||||
boolean previous = this.oversized[offset] == 1;
|
||||
this.oversized[offset] = (byte) (oversized ? 1 : 0);
|
||||
@@ -1013,7 +1013,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||
return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt");
|
||||
}
|
||||
|
||||
- synchronized net.minecraft.nbt.CompoundTag getOversizedData(int x, int z) throws IOException {
|
||||
+ public synchronized net.minecraft.nbt.CompoundTag getOversizedData(int x, int z) throws IOException { // Luminol - Configurable region file format
|
||||
Path file = getOversizedFile(x, z);
|
||||
try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new java.util.zip.InflaterInputStream(Files.newInputStream(file))))) {
|
||||
return net.minecraft.nbt.NbtIo.read((java.io.DataInput) out);
|
||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index dad7f94b611cf0fc68b1a3878c458233f6bb6d61..437fff55b565e469f6a4e41288b6f805e125be60 100644
|
||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -18,7 +18,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper
|
||||
public static final String ANVIL_EXTENSION = ".mca";
|
||||
private static final int MAX_CACHE_SIZE = 256;
|
||||
- public final Long2ObjectLinkedOpenHashMap<RegionFile> regionCache = new Long2ObjectLinkedOpenHashMap<>();
|
||||
+ public final Long2ObjectLinkedOpenHashMap<abomination.IRegionFile> regionCache = new Long2ObjectLinkedOpenHashMap<>(); // Luminol - Configurable region file format
|
||||
private final RegionStorageInfo info;
|
||||
private final Path folder;
|
||||
private final boolean sync;
|
||||
@@ -33,7 +33,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
@Nullable
|
||||
public static ChunkPos getRegionFileCoordinates(Path file) {
|
||||
String fileName = file.getFileName().toString();
|
||||
- if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) {
|
||||
+ if (!fileName.startsWith("r.") || !fileName.endsWith(getExtensionName())) { // Luminol - Configurable region file format
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -58,8 +58,27 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
private static final int MAX_NON_EXISTING_CACHE = 1024 * 4;
|
||||
private final it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet nonExistingRegionFiles = new it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet();
|
||||
private static String getRegionFileName(final int chunkX, final int chunkZ) {
|
||||
- return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + ".mca";
|
||||
+ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + getExtensionName(); // Luminol - Configurable region file format
|
||||
}
|
||||
+ // Luminol start - Configurable region file format
|
||||
+ public static abomination.IRegionFile createNew(RegionStorageInfo info, Path filePath, Path folder, boolean sync) throws IOException{
|
||||
+ final me.earthme.luminol.utils.EnumRegionFormat regionFormat = me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormat;
|
||||
+ final String fullFileName = filePath.getFileName().toString();
|
||||
+ final String[] fullNameSplit = fullFileName.split("\\.");
|
||||
+ final String extensionName = fullNameSplit[fullNameSplit.length - 1];
|
||||
+
|
||||
+ if (!regionFormat.getArgument().equalsIgnoreCase(extensionName)) {
|
||||
+ net.minecraft.server.MinecraftServer.setFatalException(new RuntimeException("Invalid region file format: " + extensionName + " expected " + regionFormat.getArgument()));
|
||||
+ throw new IOException("Invalid region file format: " + extensionName + " expected " + regionFormat.getArgument());
|
||||
+ }
|
||||
+
|
||||
+ return regionFormat.getCreator().create(new me.earthme.luminol.utils.RegionCreatorInfo(info, filePath, folder, sync));
|
||||
+ }
|
||||
+
|
||||
+ public static String getExtensionName() {
|
||||
+ return "." + me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormat.getArgument();
|
||||
+ }
|
||||
+ // Luminol end
|
||||
|
||||
private boolean doesRegionFilePossiblyExist(final long position) {
|
||||
synchronized (this.nonExistingRegionFiles) {
|
||||
@@ -93,15 +112,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
}
|
||||
|
||||
@Override
|
||||
- public synchronized final RegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) {
|
||||
+ public synchronized final abomination.IRegionFile moonrise$getRegionFileIfLoaded(final int chunkX, final int chunkZ) { // Luminol - Configurable region file format
|
||||
return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
- public synchronized final RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException {
|
||||
+ public synchronized final abomination.IRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException { // Luminol - Configurable region file format
|
||||
final long key = ChunkPos.asLong(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT);
|
||||
|
||||
- RegionFile ret = this.regionCache.getAndMoveToFirst(key);
|
||||
+ abomination.IRegionFile ret = this.regionCache.getAndMoveToFirst(key); // Luminol - Configurable region file format
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
@@ -125,7 +144,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
|
||||
FileUtil.createDirectoriesSafe(this.folder);
|
||||
|
||||
- ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
|
||||
+ ret = this.createNew(this.info, regionPath, this.folder, this.sync); // Luminol - Configurable region file format
|
||||
|
||||
this.regionCache.putAndMoveToFirst(key, ret);
|
||||
|
||||
@@ -144,7 +163,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
}
|
||||
|
||||
final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
|
||||
- final RegionFile regionFile = this.getRegionFile(pos);
|
||||
+ final abomination.IRegionFile regionFile = this.getRegionFile(pos); // Luminol - Configurable region file format
|
||||
|
||||
// note: not required to keep regionfile loaded after this call, as the write param takes a regionfile as input
|
||||
// (and, the regionfile parameter is unused for writing until the write call)
|
||||
@@ -178,7 +197,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
) throws IOException {
|
||||
final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
|
||||
if (writeData.result() == ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.DELETE) {
|
||||
- final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ);
|
||||
+ final abomination.IRegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); // Luminol - Configurable region file format
|
||||
if (regionFile != null) {
|
||||
regionFile.clear(pos);
|
||||
} // else: didn't exist
|
||||
@@ -193,7 +212,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData moonrise$readData(
|
||||
final int chunkX, final int chunkZ
|
||||
) throws IOException {
|
||||
- final RegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ);
|
||||
+ final abomination.IRegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); // Luminol - Configurable region file format
|
||||
|
||||
final DataInputStream input = regionFile == null ? null : regionFile.getChunkDataInputStream(new ChunkPos(chunkX, chunkZ));
|
||||
|
||||
@@ -237,7 +256,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
// Paper start - rewrite chunk system
|
||||
- public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException {
|
||||
+ public abomination.IRegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { // Luminol - Configurable region file format
|
||||
return this.getRegionFile(chunkcoordintpair, false);
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
@@ -249,7 +268,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers
|
||||
}
|
||||
|
||||
- @org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private RegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
|
||||
+ @org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private abomination.IRegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
|
||||
// Paper start - rewrite chunk system
|
||||
if (existingOnly) {
|
||||
return this.moonrise$getRegionFileIfExists(chunkPos.x, chunkPos.z);
|
||||
@@ -257,7 +276,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
synchronized (this) {
|
||||
final long key = ChunkPos.asLong(chunkPos.x >> REGION_SHIFT, chunkPos.z >> REGION_SHIFT);
|
||||
|
||||
- RegionFile ret = this.regionCache.getAndMoveToFirst(key);
|
||||
+ abomination.IRegionFile ret = this.regionCache.getAndMoveToFirst(key); // Luminol - Configurable region file format
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
@@ -272,7 +291,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
|
||||
FileUtil.createDirectoriesSafe(this.folder);
|
||||
|
||||
- ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
|
||||
+ ret = this.createNew(this.info, regionPath, this.folder, this.sync); // Luminol - Configurable region file format
|
||||
|
||||
this.regionCache.putAndMoveToFirst(key, ret);
|
||||
|
||||
@@ -286,7 +305,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
|
||||
}
|
||||
|
||||
- private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
|
||||
+ private static CompoundTag readOversizedChunk(abomination.IRegionFile regionfile, ChunkPos chunkCoordinate) throws IOException { // Luminol - Configurable region file format
|
||||
synchronized (regionfile) {
|
||||
try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) {
|
||||
CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z);
|
||||
@@ -321,7 +340,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
@Nullable
|
||||
public CompoundTag read(ChunkPos chunkPos) throws IOException {
|
||||
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
|
||||
- RegionFile regionFile = this.getRegionFile(chunkPos, true);
|
||||
+ abomination.IRegionFile regionFile = this.getRegionFile(chunkPos, true); // Luminol - Configurable region file format
|
||||
if (regionFile == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -360,7 +379,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
|
||||
public void scanChunk(ChunkPos chunkPos, StreamTagVisitor visitor) throws IOException {
|
||||
// CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing
|
||||
- RegionFile regionFile = this.getRegionFile(chunkPos, true);
|
||||
+ abomination.IRegionFile regionFile = this.getRegionFile(chunkPos, true); // Luminol - Configurable region file format
|
||||
if (regionFile == null) {
|
||||
return;
|
||||
}
|
||||
@@ -374,7 +393,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
}
|
||||
|
||||
public void write(ChunkPos chunkPos, @Nullable CompoundTag chunkData) throws IOException { // Paper - rewrite chunk system - public
|
||||
- RegionFile regionFile = this.getRegionFile(chunkPos, chunkData == null); // CraftBukkit // Paper - rewrite chunk system
|
||||
+ abomination.IRegionFile regionFile = this.getRegionFile(chunkPos, chunkData == null); // CraftBukkit // Paper - rewrite chunk system // Luminol - Configurable region file format
|
||||
// Paper start - rewrite chunk system
|
||||
if (regionFile == null) {
|
||||
// if the RegionFile doesn't exist, no point in deleting from it
|
||||
@@ -404,7 +423,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
// Paper start - rewrite chunk system
|
||||
synchronized (this) {
|
||||
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
|
||||
- for (final RegionFile regionFile : this.regionCache.values()) {
|
||||
+ for (final abomination.IRegionFile regionFile : this.regionCache.values()) { // Luminol - Configurable region file format
|
||||
try {
|
||||
regionFile.close();
|
||||
} catch (final IOException ex) {
|
||||
@@ -420,7 +439,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||
// Paper start - rewrite chunk system
|
||||
synchronized (this) {
|
||||
final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
|
||||
- for (final RegionFile regionFile : this.regionCache.values()) {
|
||||
+ for (final abomination.IRegionFile regionFile : this.regionCache.values()) { // Luminol - Configurable region file format
|
||||
try {
|
||||
regionFile.flush();
|
||||
} catch (final IOException ex) {
|
||||
@@ -0,0 +1,54 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:53:41 +0800
|
||||
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
|
||||
index cc8efa162fbe7ce6a91629239bf18d7b6b096a8a..4026d465687604965f105ded21a8206fd52bd375 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1100,6 +1100,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
// Paper end - detailed watchdog information
|
||||
|
||||
+ //Luminol start - Fix large pos moving
|
||||
+ private volatile boolean preventMoving = false;
|
||||
+ //Luminol end
|
||||
+
|
||||
public void move(MoverType type, Vec3 movement) {
|
||||
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
|
||||
// Paper start - detailed watchdog information
|
||||
@@ -1110,6 +1114,32 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.moveStartZ = this.getZ();
|
||||
this.moveVector = movement;
|
||||
}
|
||||
+ //Luminol start - Fix high position moving
|
||||
+ if (me.earthme.luminol.config.modules.fixes.FoliaEntityMovingFixConfig.enabled && ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()){ //Except the threads because it may be called by the chunk system worker thread
|
||||
+ var finalPosition = movement.add(this.position);
|
||||
+ if (this.preventMoving || Double.isNaN(finalPosition.x) || Double.isNaN(finalPosition.y) || Double.isNaN(finalPosition.z)){
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(((ServerLevel) this.level),finalPosition)){
|
||||
+ this.preventMoving = true;
|
||||
+ this.teleportAsync(
|
||||
+ (ServerLevel) this.level(),
|
||||
+ finalPosition,
|
||||
+ this.getYRot(), this.getXRot(),
|
||||
+ null, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN,
|
||||
+ Entity.TELEPORT_FLAG_LOAD_CHUNK | Entity.TELEPORT_FLAG_TELEPORT_PASSENGERS,
|
||||
+ result -> {
|
||||
+ this.preventMoving = false;
|
||||
+ }
|
||||
+ );
|
||||
+ if (me.earthme.luminol.config.modules.fixes.FoliaEntityMovingFixConfig.warnOnDetected){
|
||||
+ MinecraftServer.LOGGER.warn("Entity {} with entityId {} has tried moving to another region!",this.type.getCategory().getName(),this.getId());
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ //Luminol end
|
||||
try {
|
||||
// Paper end - detailed watchdog information
|
||||
if (this.noPhysics) {
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:56:59 +0800
|
||||
Subject: [PATCH] Try fixing folia off region POI accessing issue
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/net/minecraft/world/entity/ai/village/poi/PoiManager.java
|
||||
index c10810bf00d75f459c3c6a9415c1e09f0519d50e..3adafa43367cd6648ecbccb92ba5bd509740d5a4 100644
|
||||
--- a/net/minecraft/world/entity/ai/village/poi/PoiManager.java
|
||||
+++ b/net/minecraft/world/entity/ai/village/poi/PoiManager.java
|
||||
@@ -212,7 +212,7 @@ public class PoiManager extends SectionStorage<PoiSection, PoiSection.Packed> im
|
||||
|
||||
public Stream<PoiRecord> getInSquare(Predicate<Holder<PoiType>> typePredicate, BlockPos pos, int distance, PoiManager.Occupancy status) {
|
||||
int i = Math.floorDiv(distance, 16) + 1;
|
||||
- return ChunkPos.rangeClosed(new ChunkPos(pos), i).flatMap(chunkPos -> this.getInChunk(typePredicate, chunkPos, status)).filter(poiRecord -> {
|
||||
+ return ChunkPos.rangeClosed(new ChunkPos(pos), i).filter(cpos -> me.earthme.luminol.config.modules.fixes.FoliaPOIAccessOffRegionFixConfig.enabled ? ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.world,cpos) : true).flatMap(chunkPos -> this.getInChunk(typePredicate, chunkPos, status)).filter(poiRecord -> { // Luminol - Fix off region POI access
|
||||
BlockPos pos1 = poiRecord.getPos();
|
||||
return Math.abs(pos1.getX() - pos.getX()) <= distance && Math.abs(pos1.getZ() - pos.getZ()) <= distance;
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <mrhua269@gmail.com>
|
||||
Date: Sat, 22 Mar 2025 17:36:44 +0800
|
||||
Subject: [PATCH] Force disable builtin spark plugin
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 5d709b3b47702e7607dafa4a38380c801b228e2d..c2027b8d4a5f9fccacb93ba108e34c36285aec7b 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -783,8 +783,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Paper end - Configurable player collision
|
||||
|
||||
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
|
||||
- this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
|
||||
- this.server.spark.enableAfterPlugins(this.server); // Paper - spark
|
||||
+ if (false) this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark // Luminol - Force disable builtin spark
|
||||
+ if (false) this.server.spark.enableAfterPlugins(this.server); // Paper - spark // Luminol - Force disable builtin spark
|
||||
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
|
||||
io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setValid(); // Paper - reset invalid state for event fire below
|
||||
io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent(io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents.COMMANDS, io.papermc.paper.command.brigadier.PaperCommands.INSTANCE, org.bukkit.plugin.Plugin.class, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - call commands event for regular plugins
|
||||
@@ -1072,7 +1072,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
|
||||
// CraftBukkit start
|
||||
if (this.server != null) {
|
||||
- this.server.spark.disable(); // Paper - spark
|
||||
+ if (false) this.server.spark.disable(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
this.server.disablePlugins();
|
||||
this.server.waitForAsyncTasksShutdown(); // Paper - Wait for Async Tasks during shutdown
|
||||
}
|
||||
@@ -1250,7 +1250,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.statusIcon = this.loadStatusIcon().orElse(null);
|
||||
this.status = this.buildServerStatus();
|
||||
|
||||
- this.server.spark.enableBeforePlugins(); // Paper - spark
|
||||
+ if (false) this.server.spark.enableBeforePlugins(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
// Folia start - region threading
|
||||
if (true) {
|
||||
io.papermc.paper.threadedregions.RegionizedServer.getInstance().init(); // Folia - region threading - only after loading worlds
|
||||
@@ -1593,7 +1593,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
if (this.emptyTicks >= i) {
|
||||
- this.server.spark.tickStart(); // Paper - spark
|
||||
+ if (false) this.server.spark.tickStart(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
if (this.emptyTicks == i) {
|
||||
LOGGER.info("Server empty for {} seconds, pausing", this.pauseWhileEmptySeconds());
|
||||
this.autoSave();
|
||||
@@ -1612,7 +1612,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Paper end - avoid issues with certain tasks not processing during sleep
|
||||
//this.server.spark.executeMainThreadTasks(); // Paper - spark // Folia - region threading
|
||||
this.tickConnection();
|
||||
- this.server.spark.tickEnd(((double)(System.nanoTime() - lastTick) / 1000000D)); // Paper - spark
|
||||
+ if (false) this.server.spark.tickEnd(((double)(System.nanoTime() - lastTick) / 1000000D)); // Paper - spark // Luminol - Force disable builtin spark
|
||||
+ // Paper end - Server Tick Events
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1635,7 +1636,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
};
|
||||
// Folia end - region threading
|
||||
|
||||
- this.server.spark.tickStart(); // Paper - spark
|
||||
+ if (false) this.server.spark.tickStart(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper - Server Tick Events // Folia - region threading
|
||||
// Folia start - region threading
|
||||
if (region != null) {
|
||||
@@ -1744,7 +1745,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
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
|
||||
// Paper end - Server Tick Events
|
||||
- this.server.spark.tickEnd(((double)(endTime - startTime) / 1000000D)); // Paper - spark // Folia - region threading
|
||||
+ if (false) this.server.spark.tickEnd(((double)(endTime - startTime) / 1000000D)); // Paper - spark // Folia - region threading // Luminol - Force disable builtin spark
|
||||
// Folia - region threading
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index a0a8b0c7d091f63f023f15a2620b03ae2126782e..d7c922540b46e289395aeed514c98e43dc298e7b 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -214,7 +214,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
// 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
|
||||
+ if (false) this.server.spark.enableEarlyIfRequested(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||
if (this.convertOldUsers()) {
|
||||
this.getProfileCache().save(false); // Paper
|
||||
@@ -224,7 +224,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread
|
||||
thread.start(); // Paper - Enhance console tab completions for brigadier commands; start console thread after MinecraftServer.console & PaperConfig are initialized
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
|
||||
- this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
|
||||
+ if (false) this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark // Luminol - Force disable builtin spark
|
||||
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:03:09 +0800
|
||||
Subject: [PATCH] Merge Paper #11945 for temporary hopper behavior fix
|
||||
|
||||
A hopper optimization fix on Paper's pr : https://github.com/PaperMC/Paper/pull/11945
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index ae988c4910421fb720177178ef6136e595ae6946..72a81e29be6570fb119b159210453a86f003f893 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -698,6 +698,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
} else if (canMergeItems(item, stack)) {
|
||||
int i = Math.min(stack.getMaxStackSize(), destination.getMaxStackSize()) - item.getCount(); // Paper - Make hoppers respect inventory max stack size
|
||||
int min = Math.min(stack.getCount(), i);
|
||||
+ stack = stack.copy(true); // Luminol
|
||||
stack.shrink(min);
|
||||
item.grow(min);
|
||||
flag = min > 0;
|
||||
@@ -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 acca8c51d2030c675c157b10d0bbc6af631afe61..d0b688e69979c5e7b8267ac96bd71bcd33444c41 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -689,7 +689,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);
|
||||
@@ -0,0 +1,104 @@
|
||||
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/BabyFollowAdult.java b/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java
|
||||
index a9be3acbf4ea52d2988347abfa6f4f8c02b1da26..751f3dde8e6bc2c0365e8672f5079af0379a69de 100644
|
||||
--- a/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java
|
||||
@@ -25,6 +25,14 @@ public class BabyFollowAdult {
|
||||
return false;
|
||||
} else {
|
||||
LivingEntity ageableMob = instance.get(nearestVisibleAdult); // CraftBukkit - type
|
||||
+
|
||||
+ // Luminol start - Fix off world entity following which caused async issue
|
||||
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(ageableMob)) {
|
||||
+ nearestVisibleAdult.erase();
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Luminol end
|
||||
+
|
||||
if (mob.closerThan(ageableMob, followRange.getMaxValue() + 1) && !mob.closerThan(ageableMob, followRange.getMinValue())) {
|
||||
// CraftBukkit start
|
||||
org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(mob, ageableMob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <mrhua269@gmail.com>
|
||||
Date: Sat, 22 Mar 2025 20:48:24 +0800
|
||||
Subject: [PATCH] Use the correct list length while generating tick report
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/TickData.java b/io/papermc/paper/threadedregions/TickData.java
|
||||
index 0383e4dcd611a7568597f46308060f3d7288a564..f53c37d047856f1569b6f637c54ebad03c42006e 100644
|
||||
--- a/io/papermc/paper/threadedregions/TickData.java
|
||||
+++ b/io/papermc/paper/threadedregions/TickData.java
|
||||
@@ -178,7 +178,8 @@ public final class TickData {
|
||||
} else {
|
||||
long totalTickTime = 0L;
|
||||
long totalCpuTime = 0L;
|
||||
- for (int k = 0, len2 = collapsedData.size(); k < len2; ++k) {
|
||||
+ //for (int k = 0, len2 = collapsedData.size(); k < len2; ++k) {
|
||||
+ for (int k = 0, len2 = toCollapse.size(); k < len2; ++k) { // Luminol - Use the correct list length
|
||||
final TickRegionScheduler.TickTime time = toCollapse.get(k);
|
||||
totalTickTime += time.tickLength();
|
||||
totalCpuTime += time.supportCPUTime() ? time.tickCpuTime() : 0L;
|
||||
@@ -0,0 +1,124 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <mrhua269@gmail.com>
|
||||
Date: Sun, 23 Mar 2025 15:51:35 +0800
|
||||
Subject: [PATCH] Try rewriting update queue polling
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ThreadedTicketLevelPropagator.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ThreadedTicketLevelPropagator.java
|
||||
index 310a8f80debadd64c2d962ebf83b7d0505ce6e42..59d77f04fd0f1c7b7af0314e533b72e1858a7e21 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ThreadedTicketLevelPropagator.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ThreadedTicketLevelPropagator.java
|
||||
@@ -151,6 +151,15 @@ public abstract class ThreadedTicketLevelPropagator {
|
||||
private boolean performUpdate(final Section section, final UpdateQueue.UpdateQueueNode node, final Propagator propagator,
|
||||
final ReentrantAreaLock ticketLock, final ReentrantAreaLock schedulingLock,
|
||||
final List<ChunkProgressionTask> scheduledTasks, final List<NewChunkHolder> changedFullStatus) {
|
||||
+ // Luminol - Try rewriting update queue polling
|
||||
+ if (section == null) {
|
||||
+ if (node != null) {
|
||||
+ this.updateQueue.remove(node);
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Luminol end
|
||||
+
|
||||
final int sectionX = section.sectionX;
|
||||
final int sectionZ = section.sectionZ;
|
||||
|
||||
@@ -334,6 +343,7 @@ public abstract class ThreadedTicketLevelPropagator {
|
||||
|
||||
// finished
|
||||
if (node != null) {
|
||||
+ node.releaseUpdating(); // Luminol - Try rewriting update queue polling
|
||||
this.updateQueue.remove(node);
|
||||
}
|
||||
|
||||
@@ -468,7 +478,8 @@ public abstract class ThreadedTicketLevelPropagator {
|
||||
}
|
||||
}
|
||||
|
||||
- public UpdateQueueNode acquireNextOrWait(final long maxOrder) {
|
||||
+ // Luminol start - Try rewriting update queue polling
|
||||
+ /*public UpdateQueueNode acquireNextOrWait(final long maxOrder) {
|
||||
final List<UpdateQueueNode> blocking = new ArrayList<>();
|
||||
|
||||
node_search:
|
||||
@@ -502,8 +513,63 @@ public abstract class ThreadedTicketLevelPropagator {
|
||||
await(blocking.get(0));
|
||||
}
|
||||
|
||||
+ return null;
|
||||
+ }*/
|
||||
+
|
||||
+ public UpdateQueueNode acquireNextOrWait(final long maxOrder) {
|
||||
+ UpdateQueueNode firstConflict = null;
|
||||
+ UpdateQueueNode prevProcessed = null;
|
||||
+
|
||||
+ for (UpdateQueueNode curr = this.getHeadAcquire(); curr != null && curr.order <= maxOrder; curr = curr.getNextVolatile()) {
|
||||
+ if (curr.getSectionVolatile() == null) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!curr.tryAcquireUpdating()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (curr.getSectionVolatile() == null) {
|
||||
+ curr.releaseUpdating();
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ boolean hasConflict = false;
|
||||
+ for (UpdateQueueNode checked = prevProcessed; checked != null; checked = checked.getNextVolatile()) {
|
||||
+ if (checked != curr && curr.intersects(checked)) {
|
||||
+ hasConflict = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (hasConflict) {
|
||||
+ if (firstConflict == null) {
|
||||
+ firstConflict = curr;
|
||||
+ }
|
||||
+ curr.releaseUpdating();
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (firstConflict != null) {
|
||||
+ this.append(firstConflict);
|
||||
+ }
|
||||
+
|
||||
+ if (prevProcessed == null) {
|
||||
+ prevProcessed = curr;
|
||||
+ } else {
|
||||
+ prevProcessed.setNextPlain(curr);
|
||||
+ }
|
||||
+
|
||||
+ return curr;
|
||||
+ }
|
||||
+
|
||||
+ if (firstConflict != null) {
|
||||
+ this.append(firstConflict);
|
||||
+ }
|
||||
+
|
||||
return null;
|
||||
}
|
||||
+ // Luminol end
|
||||
|
||||
public UpdateQueueNode peek() {
|
||||
for (UpdateQueueNode head = this.getHeadOpaque(), curr = head;;) {
|
||||
@@ -689,6 +755,15 @@ public abstract class ThreadedTicketLevelPropagator {
|
||||
private final boolean getAndSetUpdatingVolatile(final boolean value) {
|
||||
return (boolean)UPDATING_HANDLE.getAndSet(this, value);
|
||||
}
|
||||
+ // Luminol - Try rewriting update queue polling
|
||||
+ public final boolean tryAcquireUpdating() {
|
||||
+ return (boolean) UPDATING_HANDLE.compareAndSet(this, false, true);
|
||||
+ }
|
||||
+
|
||||
+ public final void releaseUpdating() {
|
||||
+ UPDATING_HANDLE.setVolatile(this, false);
|
||||
+ }
|
||||
+ // Luminol end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:03:59 +0800
|
||||
Subject: [PATCH] Kaiiju Don't pathfind outside region
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
|
||||
index 621ba76784f2b92790eca62be4d0688834335ab6..52b3f1795843f40fdb3298cfd1a570a211a08739 100644
|
||||
--- a/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
|
||||
@@ -119,7 +119,9 @@ public class MoveToTargetSink extends Behavior<Mob> {
|
||||
|
||||
private boolean tryComputePath(Mob mob, WalkTarget target, long time) {
|
||||
BlockPos blockPos = target.getTarget().currentBlockPosition();
|
||||
+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(mob.level(), blockPos)) // Kaiiju - Don't pathfind outside region
|
||||
this.path = mob.getNavigation().createPath(blockPos, 0);
|
||||
+ else this.path = null; // Kaiiju - Don't pathfind outside region
|
||||
this.speedModifier = target.getSpeedModifier();
|
||||
Brain<?> brain = mob.getBrain();
|
||||
if (this.reachedTarget(mob, target)) {
|
||||
@@ -0,0 +1,78 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:04:12 +0800
|
||||
Subject: [PATCH] Kaiiju Vanilla end portal teleportation
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 4026d465687604965f105ded21a8206fd52bd375..8ec2b94add58d64d9b83d632427923720ec74990 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -4275,14 +4275,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
targetPos, 16, // load 16 blocks to be safe from block physics
|
||||
ca.spottedleaf.concurrentutil.util.Priority.HIGH,
|
||||
(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); // Kaiiju - Vanilla end teleportation - moved down
|
||||
+ // Kaiiju start - Vanilla end teleportation
|
||||
+ Vec3 finalPos;
|
||||
+ if (this instanceof Player) finalPos = Vec3.atBottomCenterOf(targetPos.below());
|
||||
+ else finalPos = Vec3.atBottomCenterOf(targetPos);
|
||||
+ // Kaiiju end
|
||||
// the portal obsidian is placed at targetPos.y - 2, so if we want to place the entity
|
||||
// on the obsidian, we need to spawn at targetPos.y - 1
|
||||
portalInfoCompletable.complete(
|
||||
new net.minecraft.world.level.portal.TeleportTransition(
|
||||
- destination, Vec3.atBottomCenterOf(targetPos.below()), Vec3.ZERO, Direction.WEST.toYRot(), 0.0f,
|
||||
- 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),
|
||||
org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL
|
||||
)
|
||||
@@ -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)) {
|
||||
return false;
|
||||
}
|
||||
+ // Kaiiju start - sync end platform spawning & entity teleportation
|
||||
+ 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;
|
||||
+ // Kaiiju end
|
||||
|
||||
Vec3 initialPosition = this.position();
|
||||
ChunkPos initialPositionChunk = new ChunkPos(
|
||||
@@ -4543,9 +4555,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
info.postTeleportTransition().onTransition(teleported);
|
||||
}
|
||||
|
||||
- if (teleportComplete != null) {
|
||||
+ // Kaiiju start - vanilla end teleportation
|
||||
+ /*if (teleportComplete != null) {
|
||||
teleportComplete.accept(teleported);
|
||||
+ }*/
|
||||
+ if (tpComplete != null){
|
||||
+ tpComplete.accept(teleported);
|
||||
}
|
||||
+ // Kaiiju end
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:07:08 +0800
|
||||
Subject: [PATCH] Kaiiju Entity tick and removal limiter
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index b8f1f042342d3fed5fa26df0de07e8e2b0937130..4d9837f11da4dc59fdb945fdb4849c4d1519f5dc 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -358,6 +358,7 @@ public final class RegionizedWorldData {
|
||||
private final IteratorSafeOrderedReferenceSet<Mob> navigatingMobs = new IteratorSafeOrderedReferenceSet<>();
|
||||
public final ReferenceList<Entity> trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker
|
||||
public final ReferenceList<Entity> trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker
|
||||
+ public final dev.kaiijumc.kaiiju.KaiijuEntityThrottler entityThrottler = new dev.kaiijumc.kaiiju.KaiijuEntityThrottler(); // Kaiiju
|
||||
|
||||
// block ticking
|
||||
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 7defcd15c44601bfd2f7f55046038693264defee..5a87825606047f058df8de84bf933d216b5878b0 100644
|
||||
--- a/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
|
||||
}
|
||||
|
||||
profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); try { // Folia - profiler
|
||||
+ if (dev.kaiijumc.kaiiju.KaiijuEntityLimits.enabled) regionizedWorldData.entityThrottler.tickLimiterStart(); // Kaiiju
|
||||
io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
|
||||
} finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); } // Folia - profiler
|
||||
profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler
|
||||
@@ -829,6 +830,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
entity.stopRiding();
|
||||
}
|
||||
+ // Kaiiju start
|
||||
+ if (dev.kaiijumc.kaiiju.KaiijuEntityLimits.enabled) {
|
||||
+ dev.kaiijumc.kaiiju.KaiijuEntityThrottler.EntityThrottlerReturn throttle = regionizedWorldData.entityThrottler.tickLimiterShouldSkip(entity);
|
||||
+ if (throttle.remove && !entity.hasCustomName()) entity.remove(Entity.RemovalReason.DISCARDED);
|
||||
+ if (throttle.skip) return;
|
||||
+ }
|
||||
+ // Kaiiju end
|
||||
|
||||
profilerFiller.push("tick");
|
||||
this.guardEntityTick(this::tickNonPassenger, entity);
|
||||
@@ -838,6 +846,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
}
|
||||
);
|
||||
+ if (dev.kaiijumc.kaiiju.KaiijuEntityLimits.enabled) regionizedWorldData.entityThrottler.tickLimiterFinish(regionizedWorldData); // Kaiiju
|
||||
} finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); } // Folia - profiler
|
||||
profilerFiller.pop();
|
||||
profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY); try { // Folia - profiler
|
||||
@@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:43:15 +0800
|
||||
Subject: [PATCH] Purpur Use alternative keep alive
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index f7f89695f40e4aff39d324e6a7948a8a3a8c04b3..bceef2e8cd9a84ca32f17085839dff0232f2ee31 100644
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -41,6 +41,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
private long keepAliveChallenge;
|
||||
private long closedListenerTime;
|
||||
private boolean closed = false;
|
||||
+ private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur
|
||||
private int latency;
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
// CraftBukkit start
|
||||
@@ -131,6 +132,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
|
||||
@Override
|
||||
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
|
||||
+ // Purpur start
|
||||
+ if (me.earthme.luminol.config.modules.optimizations.PurpurAlternativeKeepaliveConfig.useAlternateKeepAlive) {
|
||||
+ if (this.keepAlivePending && !keepAlives.isEmpty() && keepAlives.contains(packet.getId())) {
|
||||
+ int ping = (int) (Util.getMillis() - packet.getId());
|
||||
+ this.latency = (this.latency * 3 + ping) / 4;
|
||||
+ this.keepAlivePending = false;
|
||||
+ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest
|
||||
+ }
|
||||
+ } else
|
||||
+ // Purpur end
|
||||
if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) {
|
||||
int i = (int)(Util.getMillis() - this.keepAliveTime);
|
||||
this.latency = (this.latency * 3 + i) / 4;
|
||||
@@ -255,7 +266,22 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
// Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||
// This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
||||
final long elapsedTime = millis - this.keepAliveTime;
|
||||
- if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets
|
||||
+ // Purpur start
|
||||
+ if (me.earthme.luminol.config.modules.optimizations.PurpurAlternativeKeepaliveConfig.useAlternateKeepAlive) {
|
||||
+ if (elapsedTime >= 1000L) { // 1 second
|
||||
+ if (this.keepAlivePending && !this.processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) {
|
||||
+ LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName());
|
||||
+ this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT);
|
||||
+ } else if (this.checkIfClosed(millis)) {
|
||||
+ this.keepAlivePending = true;
|
||||
+ this.keepAliveTime = millis; // hijack this field for 1 second intervals
|
||||
+ this.keepAlives.add(millis); // currentTime is ID
|
||||
+ this.send(new ClientboundKeepAlivePacket(millis));
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+
|
||||
+ if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets
|
||||
if (this.keepAlivePending) {
|
||||
if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
||||
this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
|
||||
@@ -268,6 +294,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||
this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge));
|
||||
}
|
||||
}
|
||||
+ } // Purpur end
|
||||
|
||||
Profiler.get().pop();
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Thu, 30 Jan 2025 08:42:29 +0800
|
||||
Subject: [PATCH] Purpur Lobotomize stuck villagers
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
||||
index 7ea74aeb905b95e5919d74df5fbc5e8f7a9985e3..b61da3d0d7d24b674cae155b95f7fab0669f4a20 100644
|
||||
--- a/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -193,6 +193,53 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
this.setVillagerData(this.getVillagerData().setType(villagerType).setProfession(VillagerProfession.NONE));
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur
|
||||
+ private int notLobotomizedCount = 0; // Purpur
|
||||
+
|
||||
+ private boolean checkLobotomized() {
|
||||
+ int interval = me.earthme.luminol.config.modules.optimizations.LobotomizeVillageConfig.villagerLobotomizeCheckInterval;
|
||||
+ boolean shouldCheckForTradeLocked = me.earthme.luminol.config.modules.optimizations.LobotomizeVillageConfig.villagerLobotomizeWaitUntilTradeLocked;
|
||||
+ if (this.notLobotomizedCount > 3) {
|
||||
+ // check half as often if not lobotomized for the last 3+ consecutive checks
|
||||
+ interval *= 2;
|
||||
+ }
|
||||
+ if (this.level().getGameTime() % interval == 0) {
|
||||
+ // offset Y for short blocks like dirt_path/farmland
|
||||
+ this.isLobotomized = !(shouldCheckForTradeLocked && this.getVillagerXp() == 0) && !canTravelFrom(BlockPos.containing(this.position().x, this.getBoundingBox().minY + 0.0625D, this.position().z));
|
||||
+
|
||||
+ if (this.isLobotomized) {
|
||||
+ this.notLobotomizedCount = 0;
|
||||
+ } else {
|
||||
+ this.notLobotomizedCount++;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.isLobotomized;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
+ private boolean canTravelFrom(BlockPos pos) {
|
||||
+ return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south());
|
||||
+ }
|
||||
+
|
||||
+ private boolean canTravelTo(BlockPos pos) {
|
||||
+ net.minecraft.world.level.block.state.BlockState state = this.level().getBlockStateIfLoaded(pos);
|
||||
+ if (state == null) {
|
||||
+ // chunk not loaded
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.level.block.Block bottom = state.getBlock();
|
||||
+ if (bottom instanceof net.minecraft.world.level.block.FenceBlock ||
|
||||
+ bottom instanceof net.minecraft.world.level.block.FenceGateBlock ||
|
||||
+ bottom instanceof net.minecraft.world.level.block.WallBlock) {
|
||||
+ // bottom block is too tall to get over
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.level.block.Block top = level().getBlockState(pos.above()).getBlock();
|
||||
+ // only if both blocks have no collision
|
||||
+ return !bottom.hasCollision && !top.hasCollision;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public Brain<Villager> getBrain() {
|
||||
return (Brain<Villager>)super.getBrain();
|
||||
@@ -289,11 +336,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
// Paper start - EAR 2
|
||||
this.customServerAiStep(level, false);
|
||||
}
|
||||
- protected void customServerAiStep(ServerLevel level, final boolean inactive) {
|
||||
+ protected void customServerAiStep(ServerLevel level, boolean inactive) { // Purpur - not final
|
||||
// Paper end - EAR 2
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("villagerBrain");
|
||||
- if (!inactive) this.getBrain().tick(level, this); // Paper - EAR 2
|
||||
+ // Purpur start
|
||||
+ if (me.earthme.luminol.config.modules.optimizations.LobotomizeVillageConfig.villagerLobotomizeEnabled) {
|
||||
+ // treat as inactive if lobotomized
|
||||
+ inactive = inactive || checkLobotomized();
|
||||
+ } else {
|
||||
+ this.isLobotomized = false;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+ if (!inactive) {
|
||||
+ this.getBrain().tick(level, this); // Paper - EAR 2
|
||||
+ } else if (this.isLobotomized && shouldRestock()) restock(); // Purpur - Lobotomize stuck villagers
|
||||
profilerFiller.pop();
|
||||
if (this.assignProfessionWhenSpawned) {
|
||||
this.assignProfessionWhenSpawned = false;
|
||||
@@ -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 751b011701d6ae373099226ea63ffbafcd24ce6a..e5e946462da9e56344428139768075b7bd228ec0 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 ae049c5c3593525b991d865fec695c00ad408a59..c6252a245e9701f69db1fe167f6590095237553a 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
|
||||
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 12:21:59 +0800
|
||||
Subject: [PATCH] Petal Reduce sensor work
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
||||
index 94a7b95f41c2954561f9c3cb0f61210c0c058f1d..dbe0fc0c46f66c61a2f286d521302719b28917c1 100644
|
||||
--- a/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
|
||||
return;
|
||||
}
|
||||
// Paper end - Allow nerfed mobs to jump and float
|
||||
+ int i = this.tickCount + this.getId(); //Luminol - Petal - Move up
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("sensing");
|
||||
- this.sensing.tick();
|
||||
+ if (i % me.earthme.luminol.config.modules.optimizations.PetalReduceSensorWorkConfig.delayTicks == 0 || !me.earthme.luminol.config.modules.optimizations.PetalReduceSensorWorkConfig.enabled) this.sensing.tick(); // Luminol - Petal - Reduce sensor work
|
||||
profilerFiller.pop();
|
||||
- int i = this.tickCount + this.getId();
|
||||
if (i % 2 != 0 && this.tickCount > 1) {
|
||||
profilerFiller.push("targetSelector");
|
||||
this.targetSelector.tickRunningGoals(false);
|
||||
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 12:25:44 +0800
|
||||
Subject: [PATCH] Pufferfish Cache climbing check for activation
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
index c260741a87513b89a5cc62c543fb9f990f86491e..beb9b3b3cd5ca60bd2cdada937bff8a1da639da5 100644
|
||||
--- a/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
+++ b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
@@ -225,7 +225,7 @@ public final class ActivationRange {
|
||||
}
|
||||
// special cases.
|
||||
if (entity instanceof final LivingEntity living) {
|
||||
- if (living.onClimbable() || living.jumping || living.hurtTime > 0 || !living.activeEffects.isEmpty() || living.isFreezing()) {
|
||||
+ if ( living.onClimableCached() || living.onClimbable() || living.jumping || living.hurtTime > 0 || !living.activeEffects.isEmpty() || living.isFreezing()) { // Pufferfish - use cached
|
||||
return 1;
|
||||
}
|
||||
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
|
||||
index 6258b008ad3e00d41e9f3014572d6f7a06b1847c..2293c3db45e9ecce4e0d4b2f87b8e90228e44d94 100644
|
||||
--- a/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 {
|
||||
return this.lastClimbablePos;
|
||||
}
|
||||
|
||||
+
|
||||
+ // Pufferfish start
|
||||
+ private boolean cachedOnClimable = false;
|
||||
+ private BlockPos lastClimbingPosition = null;
|
||||
+
|
||||
+ public boolean onClimableCached() {
|
||||
+ if (!this.blockPosition().equals(this.lastClimbingPosition)) {
|
||||
+ this.cachedOnClimable = this.onClimbable();
|
||||
+ this.lastClimbingPosition = this.blockPosition();
|
||||
+ }
|
||||
+ return this.cachedOnClimable;
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
+
|
||||
public boolean onClimbable() {
|
||||
if (this.isSpectator()) {
|
||||
return false;
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 12:27:17 +0800
|
||||
Subject: [PATCH] Pufferfish Reduce chunk loading & lookups
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/EnderMan.java b/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 4b5ffd278e0e9d47100e5452949e8d757bbfece4..772ccc4dc66253a84a6d24d00e271d9b4916f052 100644
|
||||
--- a/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -309,11 +309,18 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
private boolean teleport(double x, double y, double z) {
|
||||
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(x, y, z);
|
||||
|
||||
- while (mutableBlockPos.getY() > this.level().getMinY() && !this.level().getBlockState(mutableBlockPos).blocksMotion()) {
|
||||
+ // Pufferfish start - single chunk lookup
|
||||
+ net.minecraft.world.level.chunk.LevelChunk chunk = this.level().getChunkIfLoaded(mutableBlockPos);
|
||||
+ if (chunk == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Pufferfish end
|
||||
+ while (mutableBlockPos.getY() > this.level().getMinY() && !chunk.getBlockState(mutableBlockPos).blocksMotion()) { // Pufferfish
|
||||
+
|
||||
mutableBlockPos.move(Direction.DOWN);
|
||||
}
|
||||
|
||||
- BlockState blockState = this.level().getBlockState(mutableBlockPos);
|
||||
+ BlockState blockState = chunk.getBlockState(mutableBlockPos); // Pufferfish
|
||||
boolean flag = blockState.blocksMotion();
|
||||
boolean isWater = blockState.getFluidState().is(FluidTags.WATER);
|
||||
if (flag && !isWater) {
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <novau233@163.com>
|
||||
Date: Sun, 28 Jan 2024 09:31:27 +0000
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 14:15:24 +0800
|
||||
Subject: [PATCH] Gale Use platform math functions
|
||||
|
||||
License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
@@ -98,90 +98,62 @@ public class Main {
|
||||
}
|
||||
```
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
index 2034c67f5702b7b8d093ef2dd7601901c5fef363..2a88165dd4edbc2ca1acd2f6e0a4b99ec61cf958 100644
|
||||
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
@@ -168,13 +168,11 @@ public final class MCUtil {
|
||||
}
|
||||
|
||||
public static int fastFloor(double x) {
|
||||
- int truncated = (int)x;
|
||||
- return x < (double)truncated ? truncated - 1 : truncated;
|
||||
+ return (int) Math.floor(x); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static int fastFloor(float x) {
|
||||
- int truncated = (int)x;
|
||||
- return x < (double)truncated ? truncated - 1 : truncated;
|
||||
+ return (int) Math.floor(x); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static float normalizeYaw(float f) {
|
||||
@@ -235,11 +233,11 @@ public final class MCUtil {
|
||||
}
|
||||
|
||||
public static int getChunkCoordinate(final double coordinate) {
|
||||
- return MCUtil.fastFloor(coordinate) >> 4;
|
||||
+ return ((int) Math.floor(coordinate)) >> 4; // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static int getBlockCoordinate(final double coordinate) {
|
||||
- return MCUtil.fastFloor(coordinate);
|
||||
+ return (int) Math.floor(coordinate); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static long getBlockKey(final int x, final int y, final int z) {
|
||||
diff --git a/src/main/java/net/minecraft/util/Mth.java b/src/main/java/net/minecraft/util/Mth.java
|
||||
index 990ea96de8e940390b67e9462fcfd6025f2f5770..e102c109d01e0f992808a6096b5f6a323b52d970 100644
|
||||
--- a/src/main/java/net/minecraft/util/Mth.java
|
||||
+++ b/src/main/java/net/minecraft/util/Mth.java
|
||||
@@ -58,13 +58,11 @@ public class Mth {
|
||||
diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java
|
||||
index d5d8134da9423cec199cf44762460104677194d6..e0eed27cb33348fcb46858c40014b5fe5dbaf426 100644
|
||||
--- a/net/minecraft/util/Mth.java
|
||||
+++ b/net/minecraft/util/Mth.java
|
||||
@@ -58,18 +58,15 @@ public class Mth {
|
||||
}
|
||||
|
||||
public static int floor(float value) {
|
||||
- int i = (int)value;
|
||||
- return value < (float)i ? i - 1 : i;
|
||||
- return value < i ? i - 1 : i;
|
||||
+ return (int) Math.floor(value); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static int floor(double value) {
|
||||
- int i = (int)value;
|
||||
- return value < (double)i ? i - 1 : i;
|
||||
- return value < i ? i - 1 : i;
|
||||
+ return (int) Math.floor(value); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static long lfloor(double value) {
|
||||
@@ -81,13 +79,11 @@ public class Mth {
|
||||
- long l = (long)value;
|
||||
- return value < l ? l - 1L : l;
|
||||
+ return (long) Math.floor(value); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static float abs(float value) {
|
||||
@@ -81,13 +78,11 @@ public class Mth {
|
||||
}
|
||||
|
||||
public static int ceil(float value) {
|
||||
- int i = (int)value;
|
||||
- return value > (float)i ? i + 1 : i;
|
||||
- return value > i ? i + 1 : i;
|
||||
+ return (int) Math.ceil(value); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static int ceil(double value) {
|
||||
- int i = (int)value;
|
||||
- return value > (double)i ? i + 1 : i;
|
||||
- return value > i ? i + 1 : i;
|
||||
+ return (int) Math.ceil(value); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static int clamp(int value, int min, int max) {
|
||||
@@ -123,15 +119,7 @@ public class Mth {
|
||||
@@ -123,15 +118,7 @@ public class Mth {
|
||||
}
|
||||
|
||||
public static double absMax(double a, double b) {
|
||||
- if (a < 0.0) {
|
||||
- a = -a;
|
||||
public static double absMax(double x, double y) {
|
||||
- if (x < 0.0) {
|
||||
- x = -x;
|
||||
- }
|
||||
-
|
||||
- if (b < 0.0) {
|
||||
- b = -b;
|
||||
- if (y < 0.0) {
|
||||
- y = -y;
|
||||
- }
|
||||
-
|
||||
- return Math.max(a, b);
|
||||
+ return Math.max(Math.abs(a), Math.abs(b)); // Gale - use platform math functions
|
||||
- return Math.max(x, y);
|
||||
+ return Math.max(Math.abs(x), Math.abs(y)); // Gale - use platform math functions
|
||||
}
|
||||
|
||||
public static int floorDiv(int dividend, int divisor) {
|
||||
@@ -1,40 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <novau233@163.com>
|
||||
Date: Wed, 7 Feb 2024 06:00:22 +0000
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 15:31:52 +0800
|
||||
Subject: [PATCH] Gale Variable entity wake-up duration
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/GaleVariableEntityWakeupConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/GaleVariableEntityWakeupConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fa30e8dc39a2d4bd1399e41230b307b19eeb716a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/GaleVariableEntityWakeupConfig.java
|
||||
@@ -0,0 +1,20 @@
|
||||
+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 GaleVariableEntityWakeupConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "entity_wakeup_duration_ratio_standard_deviation")
|
||||
+ public static double entityWakeUpDurationRatioStandardDeviation = 0.2;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.OPTIMIZATIONS;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "variable_entity_waking_up";
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
index 9628cc2b7f200e0bab4fed48997dde3e266200ee..3a6ae320891f1e3202c59b63a5f2c96c18727314 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -75,28 +75,41 @@ public class ActivationRange
|
||||
diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
index beb9b3b3cd5ca60bd2cdada937bff8a1da639da5..3c9fc433155dd235668ded700d51d95434ba745f 100644
|
||||
--- a/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
+++ b/io/papermc/paper/entity/activation/ActivationRange.java
|
||||
@@ -54,27 +54,39 @@ public final class ActivationRange {
|
||||
if (entity.activationType == ActivationType.VILLAGER) {
|
||||
if (inactiveFor > config.wakeUpInactiveVillagersEvery && worldData.wakeupInactiveRemainingVillagers > 0) { // Folia - threaded regions
|
||||
worldData.wakeupInactiveRemainingVillagers--; // Folia - threaded regions
|
||||
@@ -62,7 +36,6 @@ index 9628cc2b7f200e0bab4fed48997dde3e266200ee..3a6ae320891f1e3202c59b63a5f2c96c
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Gale start - variable entity wake-up duration
|
||||
+ private static final java.util.concurrent.ThreadLocalRandom wakeUpDurationRandom = java.util.concurrent.ThreadLocalRandom.current();
|
||||
@@ -76,7 +49,6 @@ index 9628cc2b7f200e0bab4fed48997dde3e266200ee..3a6ae320891f1e3202c59b63a5f2c96c
|
||||
+ }
|
||||
+ // Gale end - variable entity wake-up duration
|
||||
+
|
||||
+
|
||||
// Folia - threaded regions - replaced by local variable
|
||||
//static AABB maxBB = new AABB(0, 0, 0, 0, 0, 0); // Folia - threaded regions - replaced by local variable
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 15:35:15 +0800
|
||||
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
|
||||
index 8ec2b94add58d64d9b83d632427923720ec74990..3ad00cc095588574218ca6d729ead119403202e0 100644
|
||||
--- a/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
|
||||
private volatile boolean preventMoving = false;
|
||||
//Luminol end
|
||||
|
||||
+ private boolean boundingBoxChanged = false; // Gale - VMP - skip entity move if movement is zero
|
||||
+
|
||||
public void move(MoverType type, Vec3 movement) {
|
||||
+ // Gale start - VMP - skip entity move if movement is zero
|
||||
+ if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Gale end - VMP - skip entity move if movement is zero
|
||||
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
|
||||
// Paper start - detailed watchdog information
|
||||
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main");
|
||||
@@ -5045,6 +5052,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
public final void setBoundingBox(AABB bb) {
|
||||
+ // Gale start - VMP - skip entity move if movement is zero
|
||||
+ if (!this.bb.equals(bb)) {
|
||||
+ this.boundingBoxChanged = true;
|
||||
+ }
|
||||
+ // Gale end - VMP - skip entity move if movement is zero
|
||||
// CraftBukkit start - block invalid bounding boxes
|
||||
double minX = bb.minX,
|
||||
minY = bb.minY,
|
||||
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 22 Jan 2025 17:18:00 +0800
|
||||
Subject: [PATCH] Gale Replace AI attributes with optimized collections
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
index 4c808c7ef336de74048f40bd1cc8b14131a9325d..8dfd32a8ec590c688dc8d64f18b6b59378c17880 100644
|
||||
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
||||
@@ -19,9 +19,11 @@ import org.slf4j.Logger;
|
||||
|
||||
public class AttributeMap {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
- private final Map<Holder<Attribute>, AttributeInstance> attributes = new Object2ObjectOpenHashMap<>();
|
||||
- private final Set<AttributeInstance> attributesToSync = new ObjectOpenHashSet<>();
|
||||
- private final Set<AttributeInstance> attributesToUpdate = new ObjectOpenHashSet<>();
|
||||
+ // Gale start - Lithium - replace AI attributes with optimized collections
|
||||
+ private final Map<Holder<Attribute>, AttributeInstance> attributes = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0);
|
||||
+ private final Set<AttributeInstance> attributesToSync = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ private final Set<AttributeInstance> attributesToUpdate = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0);
|
||||
+ // Gale end - Lithium - replace AI attributes with optimized collections
|
||||
private final AttributeSupplier supplier;
|
||||
|
||||
public AttributeMap(AttributeSupplier supplier) {
|
||||
@@ -0,0 +1,230 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 22 Jan 2025 17:23:16 +0800
|
||||
Subject: [PATCH] Gale Optimize noise generation
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
||||
index fb11a2eea540d55e50eab59f9857ca5d99f556f8..dcc1a3f8b611c9f103b848db90b077b984b60ada 100644
|
||||
--- a/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
||||
+++ b/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
|
||||
@@ -11,6 +11,27 @@ public final class ImprovedNoise {
|
||||
public final double yo;
|
||||
public final double zo;
|
||||
|
||||
+ // Gale start - C2ME - optimize noise generation
|
||||
+ private static final double[] FLAT_SIMPLEX_GRAD = new double[]{
|
||||
+ 1, 1, 0, 0,
|
||||
+ -1, 1, 0, 0,
|
||||
+ 1, -1, 0, 0,
|
||||
+ -1, -1, 0, 0,
|
||||
+ 1, 0, 1, 0,
|
||||
+ -1, 0, 1, 0,
|
||||
+ 1, 0, -1, 0,
|
||||
+ -1, 0, -1, 0,
|
||||
+ 0, 1, 1, 0,
|
||||
+ 0, -1, 1, 0,
|
||||
+ 0, 1, -1, 0,
|
||||
+ 0, -1, -1, 0,
|
||||
+ 1, 1, 0, 0,
|
||||
+ 0, -1, 1, 0,
|
||||
+ -1, 1, 0, 0,
|
||||
+ 0, -1, -1, 0,
|
||||
+ };
|
||||
+ // Gale end - C2ME - optimize noise generation
|
||||
+
|
||||
public ImprovedNoise(RandomSource random) {
|
||||
this.xo = random.nextDouble() * 256.0;
|
||||
this.yo = random.nextDouble() * 256.0;
|
||||
@@ -38,9 +59,11 @@ public final class ImprovedNoise {
|
||||
double d = x + this.xo;
|
||||
double d1 = y + this.yo;
|
||||
double d2 = z + this.zo;
|
||||
- int floor = Mth.floor(d);
|
||||
- int floor1 = Mth.floor(d1);
|
||||
- int floor2 = Mth.floor(d2);
|
||||
+ // Gale start - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
+ double floor = Math.floor(d);
|
||||
+ double floor1 = Math.floor(d1);
|
||||
+ double floor2 = Math.floor(d2);
|
||||
+ // Gale end - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
double d3 = d - floor;
|
||||
double d4 = d1 - floor1;
|
||||
double d5 = d2 - floor2;
|
||||
@@ -53,25 +76,27 @@ public final class ImprovedNoise {
|
||||
d6 = d4;
|
||||
}
|
||||
|
||||
- d7 = Mth.floor(d6 / yScale + 1.0E-7F) * yScale;
|
||||
+ d7 = Math.floor(d6 / yScale + 1.0E-7F) * yScale; // Gale - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
} else {
|
||||
d7 = 0.0;
|
||||
}
|
||||
|
||||
- return this.sampleAndLerp(floor, floor1, floor2, d3, d4 - d7, d5, d4);
|
||||
+ return this.sampleAndLerp((int) floor, (int) floor1, (int) floor2, d3, d4 - d7, d5, d4); // Gale - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
}
|
||||
|
||||
public double noiseWithDerivative(double x, double y, double z, double[] values) {
|
||||
double d = x + this.xo;
|
||||
double d1 = y + this.yo;
|
||||
double d2 = z + this.zo;
|
||||
- int floor = Mth.floor(d);
|
||||
- int floor1 = Mth.floor(d1);
|
||||
- int floor2 = Mth.floor(d2);
|
||||
+ // Gale start - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
+ double floor = Math.floor(d);
|
||||
+ double floor1 = Math.floor(d1);
|
||||
+ double floor2 = Math.floor(d2);
|
||||
+ // Gale end - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
double d3 = d - floor;
|
||||
double d4 = d1 - floor1;
|
||||
double d5 = d2 - floor2;
|
||||
- return this.sampleWithDerivative(floor, floor1, floor2, d3, d4, d5, values);
|
||||
+ return this.sampleWithDerivative((int) floor, (int) floor1, (int) floor2, d3, d4, d5, values); // Gale - C2ME - optimize noise generation - optimize: remove frequent type conversions
|
||||
}
|
||||
|
||||
private static double gradDot(int gradIndex, double xFactor, double yFactor, double zFactor) {
|
||||
@@ -83,24 +108,69 @@ public final class ImprovedNoise {
|
||||
}
|
||||
|
||||
private double sampleAndLerp(int gridX, int gridY, int gridZ, double deltaX, double weirdDeltaY, double deltaZ, double deltaY) {
|
||||
- int i = this.p(gridX);
|
||||
- int i1 = this.p(gridX + 1);
|
||||
- int i2 = this.p(i + gridY);
|
||||
- int i3 = this.p(i + gridY + 1);
|
||||
- int i4 = this.p(i1 + gridY);
|
||||
- int i5 = this.p(i1 + gridY + 1);
|
||||
- double d = gradDot(this.p(i2 + gridZ), deltaX, weirdDeltaY, deltaZ);
|
||||
- double d1 = gradDot(this.p(i4 + gridZ), deltaX - 1.0, weirdDeltaY, deltaZ);
|
||||
- double d2 = gradDot(this.p(i3 + gridZ), deltaX, weirdDeltaY - 1.0, deltaZ);
|
||||
- double d3 = gradDot(this.p(i5 + gridZ), deltaX - 1.0, weirdDeltaY - 1.0, deltaZ);
|
||||
- double d4 = gradDot(this.p(i2 + gridZ + 1), deltaX, weirdDeltaY, deltaZ - 1.0);
|
||||
- double d5 = gradDot(this.p(i4 + gridZ + 1), deltaX - 1.0, weirdDeltaY, deltaZ - 1.0);
|
||||
- double d6 = gradDot(this.p(i3 + gridZ + 1), deltaX, weirdDeltaY - 1.0, deltaZ - 1.0);
|
||||
- double d7 = gradDot(this.p(i5 + gridZ + 1), deltaX - 1.0, weirdDeltaY - 1.0, deltaZ - 1.0);
|
||||
- double d8 = Mth.smoothstep(deltaX);
|
||||
- double d9 = Mth.smoothstep(deltaY);
|
||||
- double d10 = Mth.smoothstep(deltaZ);
|
||||
- return Mth.lerp3(d8, d9, d10, d, d1, d2, d3, d4, d5, d6, d7);
|
||||
+ // Gale start - C2ME - optimize noise generation - inline math & small optimization: remove frequent type conversions and redundant ops
|
||||
+ final int var0 = gridX & 0xFF;
|
||||
+ final int var1 = (gridX + 1) & 0xFF;
|
||||
+ final int var2 = this.p[var0] & 0xFF;
|
||||
+ final int var3 = this.p[var1] & 0xFF;
|
||||
+ final int var4 = (var2 + gridY) & 0xFF;
|
||||
+ final int var5 = (var3 + gridY) & 0xFF;
|
||||
+ final int var6 = (var2 + gridY + 1) & 0xFF;
|
||||
+ final int var7 = (var3 + gridY + 1) & 0xFF;
|
||||
+ final int var8 = this.p[var4] & 0xFF;
|
||||
+ final int var9 = this.p[var5] & 0xFF;
|
||||
+ final int var10 = this.p[var6] & 0xFF;
|
||||
+ final int var11 = this.p[var7] & 0xFF;
|
||||
+
|
||||
+ final int var12 = (var8 + gridZ) & 0xFF;
|
||||
+ final int var13 = (var9 + gridZ) & 0xFF;
|
||||
+ final int var14 = (var10 + gridZ) & 0xFF;
|
||||
+ final int var15 = (var11 + gridZ) & 0xFF;
|
||||
+ final int var16 = (var8 + gridZ + 1) & 0xFF;
|
||||
+ final int var17 = (var9 + gridZ + 1) & 0xFF;
|
||||
+ final int var18 = (var10 + gridZ + 1) & 0xFF;
|
||||
+ final int var19 = (var11 + gridZ + 1) & 0xFF;
|
||||
+ final int var20 = (this.p[var12] & 15) << 2;
|
||||
+ final int var21 = (this.p[var13] & 15) << 2;
|
||||
+ final int var22 = (this.p[var14] & 15) << 2;
|
||||
+ final int var23 = (this.p[var15] & 15) << 2;
|
||||
+ final int var24 = (this.p[var16] & 15) << 2;
|
||||
+ final int var25 = (this.p[var17] & 15) << 2;
|
||||
+ final int var26 = (this.p[var18] & 15) << 2;
|
||||
+ final int var27 = (this.p[var19] & 15) << 2;
|
||||
+ final double var60 = deltaX - 1.0;
|
||||
+ final double var61 = weirdDeltaY - 1.0;
|
||||
+ final double var62 = deltaZ - 1.0;
|
||||
+ final double var87 = FLAT_SIMPLEX_GRAD[(var20) | 0] * deltaX + FLAT_SIMPLEX_GRAD[(var20) | 1] * weirdDeltaY + FLAT_SIMPLEX_GRAD[(var20) | 2] * deltaZ;
|
||||
+ final double var88 = FLAT_SIMPLEX_GRAD[(var21) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var21) | 1] * weirdDeltaY + FLAT_SIMPLEX_GRAD[(var21) | 2] * deltaZ;
|
||||
+ final double var89 = FLAT_SIMPLEX_GRAD[(var22) | 0] * deltaX + FLAT_SIMPLEX_GRAD[(var22) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var22) | 2] * deltaZ;
|
||||
+ final double var90 = FLAT_SIMPLEX_GRAD[(var23) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var23) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var23) | 2] * deltaZ;
|
||||
+ final double var91 = FLAT_SIMPLEX_GRAD[(var24) | 0] * deltaX + FLAT_SIMPLEX_GRAD[(var24) | 1] * weirdDeltaY + FLAT_SIMPLEX_GRAD[(var24) | 2] * var62;
|
||||
+ final double var92 = FLAT_SIMPLEX_GRAD[(var25) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var25) | 1] * weirdDeltaY + FLAT_SIMPLEX_GRAD[(var25) | 2] * var62;
|
||||
+ final double var93 = FLAT_SIMPLEX_GRAD[(var26) | 0] * deltaX + FLAT_SIMPLEX_GRAD[(var26) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var26) | 2] * var62;
|
||||
+ final double var94 = FLAT_SIMPLEX_GRAD[(var27) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var27) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var27) | 2] * var62;
|
||||
+
|
||||
+ final double var95 = deltaX * 6.0 - 15.0;
|
||||
+ final double var96 = deltaY * 6.0 - 15.0;
|
||||
+ final double var97 = deltaZ * 6.0 - 15.0;
|
||||
+ final double var98 = deltaX * var95 + 10.0;
|
||||
+ final double var99 = deltaY * var96 + 10.0;
|
||||
+ final double var100 = deltaZ * var97 + 10.0;
|
||||
+ final double var101 = deltaX * deltaX * deltaX * var98;
|
||||
+ final double var102 = deltaY * deltaY * deltaY * var99;
|
||||
+ final double var103 = deltaZ * deltaZ * deltaZ * var100;
|
||||
+
|
||||
+ final double var113 = var87 + var101 * (var88 - var87);
|
||||
+ final double var114 = var93 + var101 * (var94 - var93);
|
||||
+ final double var115 = var91 + var101 * (var92 - var91);
|
||||
+ final double var116 = var89 + var101 * (var90 - var89);
|
||||
+ final double var117 = var114 - var115;
|
||||
+ final double var118 = var102 * (var116 - var113);
|
||||
+ final double var119 = var102 * var117;
|
||||
+ final double var120 = var113 + var118;
|
||||
+ final double var121 = var115 + var119;
|
||||
+ return var120 + (var103 * (var121 - var120));
|
||||
+ // Gale end - C2ME - optimize noise generation - inline math & small optimization: remove frequent type conversions and redundant ops
|
||||
}
|
||||
|
||||
private double sampleWithDerivative(int gridX, int gridY, int gridZ, double deltaX, double deltaY, double deltaZ, double[] noiseValues) {
|
||||
diff --git a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
||||
index da3c26fbad32d75d71f7e59c8c3341316a754756..2c28bb2fed04542a2ee126fe0c1c1f0253a3e2eb 100644
|
||||
--- a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
||||
+++ b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
|
||||
@@ -26,6 +26,10 @@ public class PerlinNoise {
|
||||
private final double lowestFreqValueFactor;
|
||||
private final double lowestFreqInputFactor;
|
||||
private final double maxValue;
|
||||
+ // Gale start - C2ME - optimize noise generation
|
||||
+ private final int octaveSamplersCount;
|
||||
+ private final double [] amplitudesArray;
|
||||
+ // Gale end - C2ME - optimize noise generation
|
||||
|
||||
@Deprecated
|
||||
public static PerlinNoise createLegacyForBlendedNoise(RandomSource random, IntStream octaves) {
|
||||
@@ -127,6 +131,10 @@ public class PerlinNoise {
|
||||
this.lowestFreqInputFactor = Math.pow(2.0, -i);
|
||||
this.lowestFreqValueFactor = Math.pow(2.0, size - 1) / (Math.pow(2.0, size) - 1.0);
|
||||
this.maxValue = this.edgeValue(2.0);
|
||||
+ // Gale start - C2ME - optimize noise generation
|
||||
+ this.octaveSamplersCount = this.noiseLevels.length;
|
||||
+ this.amplitudesArray = this.amplitudes.toDoubleArray();
|
||||
+ // Gale end - C2ME - optimize noise generation
|
||||
}
|
||||
|
||||
protected double maxValue() {
|
||||
@@ -138,7 +146,27 @@ public class PerlinNoise {
|
||||
}
|
||||
|
||||
public double getValue(double x, double y, double z) {
|
||||
- return this.getValue(x, y, z, 0.0, 0.0, false);
|
||||
+ // Gale start - C2ME - optimize noise generation - optimize for common cases
|
||||
+ double d = 0.0;
|
||||
+ double e = this.lowestFreqInputFactor;
|
||||
+ double f = this.lowestFreqValueFactor;
|
||||
+
|
||||
+ for (int i = 0; i < this.octaveSamplersCount; ++i) {
|
||||
+ ImprovedNoise perlinNoiseSampler = this.noiseLevels[i];
|
||||
+ if (perlinNoiseSampler != null) {
|
||||
+ @SuppressWarnings("deprecation")
|
||||
+ double g = perlinNoiseSampler.noise(
|
||||
+ wrap(x * e), wrap(y * e), wrap(z * e), 0.0, 0.0
|
||||
+ );
|
||||
+ d += this.amplitudesArray[i] * g * f;
|
||||
+ }
|
||||
+
|
||||
+ e *= 2.0;
|
||||
+ f /= 2.0;
|
||||
+ }
|
||||
+
|
||||
+ return d;
|
||||
+ // Gale end - C2ME - optimize noise generation - optimize for common cases
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 15:35:43 +0800
|
||||
Subject: [PATCH] SparklyPaper Optimize canSee checks
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 5c507be097051de9a43a31bbc6190c3db7688667..7eff847790394aecd058e7a61905da86163b4c6e 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1224,7 +1224,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
// Folia end - region threading
|
||||
// CraftBukkit start - respect vanish API
|
||||
- if (flag && (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSee(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading
|
||||
+ if (flag && (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSeeChunkMapUpdatePlayer(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading // SparklyPaper - optimize canSee checks
|
||||
flag = false;
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 15:37:25 +0800
|
||||
Subject: [PATCH] SparklyPaper Skip "distanceToSqr" call in
|
||||
"ServerEntity#sendChanges" if the delta movement hasn't changed
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||
index 0fb253aa55a24b56b17f524b3261c5b75c7d7e59..1de43a4969a2a4535239b15a7bc30d99eb6934c6 100644
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -195,6 +195,8 @@ public class ServerEntity {
|
||||
|
||||
if (this.entity.hasImpulse || this.trackDelta || this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isFallFlying()) {
|
||||
Vec3 deltaMovement = this.entity.getDeltaMovement();
|
||||
+
|
||||
+ if (deltaMovement != this.lastSentMovement) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed
|
||||
double d = deltaMovement.distanceToSqr(this.lastSentMovement);
|
||||
if (d > 1.0E-7 || d > 0.0 && deltaMovement.lengthSqr() == 0.0) {
|
||||
this.lastSentMovement = deltaMovement;
|
||||
@@ -212,6 +214,7 @@ public class ServerEntity {
|
||||
this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
|
||||
}
|
||||
}
|
||||
+ } // SparklyPaper end
|
||||
}
|
||||
|
||||
if (packet != null) {
|
||||
@@ -0,0 +1,419 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 28 Jan 2025 18:56:53 +0800
|
||||
Subject: [PATCH] Leaf Secure seed and matter seed command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/commands/SeedCommand.java b/net/minecraft/server/commands/SeedCommand.java
|
||||
index a65affc41a4fc299bc2281f0f53f2e075633899d..f071e469468b768bd9c063d78c222b1b3e3b13bd 100644
|
||||
--- a/net/minecraft/server/commands/SeedCommand.java
|
||||
+++ b/net/minecraft/server/commands/SeedCommand.java
|
||||
@@ -12,6 +12,17 @@ public class SeedCommand {
|
||||
long seed = context.getSource().getLevel().getSeed();
|
||||
Component component = ComponentUtils.copyOnClickText(String.valueOf(seed));
|
||||
context.getSource().sendSuccess(() -> Component.translatable("commands.seed.success", component), false);
|
||||
+
|
||||
+ // Leaf start - Matter - SecureSeed Command
|
||||
+ if (me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
+ su.plo.matter.Globals.setupGlobals(context.getSource().getLevel());
|
||||
+ String seedStr = su.plo.matter.Globals.seedToString(su.plo.matter.Globals.worldSeed);
|
||||
+ Component featureSeedComponent = ComponentUtils.copyOnClickText(seedStr);
|
||||
+
|
||||
+ context.getSource().sendSuccess(() -> Component.translatable(("Feature seed: %s"), featureSeedComponent), false);
|
||||
+ }
|
||||
+ // Leaf end - Matter - SecureSeed Command
|
||||
+
|
||||
return (int)seed;
|
||||
}));
|
||||
}
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServerProperties.java b/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
index f6518e29f805018c72222f5aaa7b662071665b65..8d082996a0f361cfd12af6a2138efd7057732fc8 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -113,7 +113,17 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
String string = this.get("level-seed", "");
|
||||
boolean flag = this.get("generate-structures", true);
|
||||
long l = WorldOptions.parseSeed(string).orElse(WorldOptions.randomSeed());
|
||||
- this.worldOptions = new WorldOptions(l, flag, false);
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ if (me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
+ String featureSeedStr = this.get("feature-level-seed", "");
|
||||
+ long[] featureSeed = su.plo.matter.Globals.parseSeed(featureSeedStr)
|
||||
+ .orElse(su.plo.matter.Globals.createRandomWorldSeed());
|
||||
+
|
||||
+ this.worldOptions = new WorldOptions(l, featureSeed, flag, false);
|
||||
+ } else {
|
||||
+ this.worldOptions = new WorldOptions(l, flag, false);
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
this.worldDimensionData = new DedicatedServerProperties.WorldDimensionData(
|
||||
this.get("generator-settings", property -> GsonHelper.parse(!property.isEmpty() ? property : "{}"), new JsonObject()),
|
||||
this.get("level-type", property -> property.toLowerCase(Locale.ROOT), WorldPresets.NORMAL.location().toString())
|
||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
||||
index ac06b8a4813716a8d136be5731cbd96113976a7e..82d95005fc67336458b50c47d44ec4047fffcd1e 100644
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -680,6 +680,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
||||
}
|
||||
|
||||
public ChunkGenerator getGenerator() {
|
||||
+ su.plo.matter.Globals.setupGlobals(level); // Leaf - Matter - Secure Seed
|
||||
return this.chunkMap.generator();
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 5a87825606047f058df8de84bf933d216b5878b0..d8e1febfa14be1c0f4869ae647bd17113660432b 100644
|
||||
--- a/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
|
||||
chunkGenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkGenerator, gen);
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ su.plo.matter.Globals.setupGlobals(this); // Leaf - Matter - Secure Seed
|
||||
boolean flag = server.forceSynchronousWrites();
|
||||
DataFixer fixerUpper = server.getFixerUpper();
|
||||
// Paper - rewrite chunk system
|
||||
diff --git a/net/minecraft/world/entity/monster/Slime.java b/net/minecraft/world/entity/monster/Slime.java
|
||||
index 8db4cba1be6d7a5538295ba8da1fdaf7a77a16d0..25ef938623e2e4f65f6554731b756995638e4231 100644
|
||||
--- a/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -340,7 +340,12 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = new ChunkPos(pos);
|
||||
- boolean flag = level.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) level).getSeed(), level.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ boolean isSlimeChunk = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? level.getChunk(chunkPos.x, chunkPos.z).isSlimeChunk()
|
||||
+ : WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) level).getSeed(), level.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
+ boolean flag = level.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
// Paper start - Replace rules for Height in Slime Chunks
|
||||
final double maxHeightSlimeChunk = level.getMinecraftWorld().paperConfig().entities.spawning.slimeSpawnHeight.slimeChunk.maximum;
|
||||
if (random.nextInt(10) == 0 && flag && pos.getY() < maxHeightSlimeChunk) {
|
||||
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index 6d565b52552534ce9cacfc35ad1bf4adcb69eac3..3a6db5bc0c8be7d68e15317a621c1965fdc3a9bd 100644
|
||||
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -87,6 +87,10 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY);
|
||||
// CraftBukkit end
|
||||
public final Registry<Biome> biomeRegistry; // CraftBukkit
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ private boolean slimeChunk;
|
||||
+ private boolean hasComputedSlimeChunk;
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
|
||||
// Paper start - rewrite chunk system
|
||||
private volatile ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles;
|
||||
@@ -191,6 +195,17 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
return GameEventListenerRegistry.NOOP;
|
||||
}
|
||||
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ public boolean isSlimeChunk() {
|
||||
+ if (!hasComputedSlimeChunk) {
|
||||
+ hasComputedSlimeChunk = true;
|
||||
+ slimeChunk = su.plo.matter.WorldgenCryptoRandom.seedSlimeChunk(chunkPos.x, chunkPos.z).nextInt(10) == 0;
|
||||
+ }
|
||||
+
|
||||
+ return slimeChunk;
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+
|
||||
public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving);
|
||||
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
index b85c547f281c58bf45c9062d0b886cb4ff7b386b..55df64f9069496010841bfc373887d27fc5c2162 100644
|
||||
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -343,7 +343,11 @@ public abstract class ChunkGenerator {
|
||||
Registry<Structure> registry = level.registryAccess().lookupOrThrow(Registries.STRUCTURE);
|
||||
Map<Integer, List<Structure>> map = registry.stream().collect(Collectors.groupingBy(structure1 -> structure1.step().ordinal()));
|
||||
List<FeatureSorter.StepFeatureData> list = this.featuresPerStep.get();
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldgenRandom worldgenRandom = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? new su.plo.matter.WorldgenCryptoRandom(blockPos.getX(), blockPos.getZ(), su.plo.matter.Globals.Salt.UNDEFINED, 0)
|
||||
+ : new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed()));
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
long l = worldgenRandom.setDecorationSeed(level.getSeed(), blockPos.getX(), blockPos.getZ());
|
||||
Set<Holder<Biome>> set = new ObjectArraySet<>();
|
||||
ChunkPos.rangeClosed(sectionPos.chunk(), 1).forEach(chunkPos -> {
|
||||
@@ -556,8 +560,15 @@ public abstract class ChunkGenerator {
|
||||
} else {
|
||||
ArrayList<StructureSet.StructureSelectionEntry> list1 = new ArrayList<>(list.size());
|
||||
list1.addAll(list);
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
- worldgenRandom.setLargeFeatureSeed(structureState.getLevelSeed(), pos.x, pos.z);
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldgenRandom worldgenRandom;
|
||||
+ if (me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
+ worldgenRandom = new su.plo.matter.WorldgenCryptoRandom(pos.x, pos.z, su.plo.matter.Globals.Salt.GENERATE_FEATURE, 0);
|
||||
+ } else {
|
||||
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+ worldgenRandom.setLargeFeatureSeed(structureState.getLevelSeed(), pos.x, pos.z);
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
int i = 0;
|
||||
|
||||
for (StructureSet.StructureSelectionEntry structureSelectionEntry1 : list1) {
|
||||
diff --git a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
index 619b98e42e254c0c260c171a26a2472ddf59b885..7abafc6f9f89159277ff84aa79a2edc4abcd7da3 100644
|
||||
--- a/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
+++ b/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java
|
||||
@@ -205,7 +205,12 @@ public class ChunkGeneratorStructureState {
|
||||
List<CompletableFuture<ChunkPos>> list = new ArrayList<>(count);
|
||||
int spread = placement.spread();
|
||||
HolderSet<Biome> holderSet = placement.preferredBiomes();
|
||||
- RandomSource randomSource = RandomSource.create();
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ RandomSource randomSource = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? new su.plo.matter.WorldgenCryptoRandom(0, 0, su.plo.matter.Globals.Salt.STRONGHOLDS, 0)
|
||||
+ : RandomSource.create();
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+ if (!me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
// Paper start - Add missing structure set seed configs
|
||||
if (this.conf.strongholdSeed != null && structureSet.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) {
|
||||
randomSource.setSeed(this.conf.strongholdSeed);
|
||||
@@ -213,6 +218,7 @@ public class ChunkGeneratorStructureState {
|
||||
// Paper end - Add missing structure set seed configs
|
||||
randomSource.setSeed(this.concentricRingsSeed);
|
||||
} // Paper - Add missing structure set seed configs
|
||||
+ } // Leaf - Matter - Secure Seed
|
||||
double d = randomSource.nextDouble() * Math.PI * 2.0;
|
||||
int i = 0;
|
||||
int i1 = 0;
|
||||
diff --git a/net/minecraft/world/level/chunk/status/ChunkStep.java b/net/minecraft/world/level/chunk/status/ChunkStep.java
|
||||
index b8348976e80578d9eff64eea68c04c603fed49ad..bc5c6ea1f1e4f1608a70116f03fb2a58ca3252c3 100644
|
||||
--- a/net/minecraft/world/level/chunk/status/ChunkStep.java
|
||||
+++ b/net/minecraft/world/level/chunk/status/ChunkStep.java
|
||||
@@ -60,6 +60,7 @@ public final class ChunkStep implements ca.spottedleaf.moonrise.patches.chunk_sy
|
||||
}
|
||||
|
||||
public CompletableFuture<ChunkAccess> apply(WorldGenContext worldGenContext, StaticCache2D<GenerationChunkHolder> cache, ChunkAccess chunk) {
|
||||
+ su.plo.matter.Globals.setupGlobals(worldGenContext.level()); // Leaf - Matter - Secure Seed
|
||||
if (chunk.getPersistedStatus().isBefore(this.targetStatus)) {
|
||||
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE
|
||||
.onChunkGenerate(chunk.getPos(), worldGenContext.level().dimension(), this.targetStatus.getName());
|
||||
diff --git a/net/minecraft/world/level/levelgen/WorldOptions.java b/net/minecraft/world/level/levelgen/WorldOptions.java
|
||||
index c92508741439a8d0d833ea02d0104416adb83c92..a4063fe0c8e113f0fbd751b84aefaaad68e08ca0 100644
|
||||
--- a/net/minecraft/world/level/levelgen/WorldOptions.java
|
||||
+++ b/net/minecraft/world/level/levelgen/WorldOptions.java
|
||||
@@ -9,8 +9,20 @@ import net.minecraft.util.RandomSource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class WorldOptions {
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ private static final com.google.gson.Gson gson = new com.google.gson.Gson();
|
||||
+ private static final boolean isSecureSeedEnabled = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled;
|
||||
public static final MapCodec<WorldOptions> CODEC = RecordCodecBuilder.mapCodec(
|
||||
- instance -> instance.group(
|
||||
+ instance -> isSecureSeedEnabled
|
||||
+ ? instance.group(
|
||||
+ Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
|
||||
+ Codec.STRING.fieldOf("feature_seed").orElse(gson.toJson(su.plo.matter.Globals.createRandomWorldSeed())).stable().forGetter(WorldOptions::featureSeedSerialize),
|
||||
+ Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
|
||||
+ Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
|
||||
+ Codec.STRING.lenientOptionalFieldOf("legacy_custom_options").stable().forGetter(worldOptions -> worldOptions.legacyCustomOptions)
|
||||
+ )
|
||||
+ .apply(instance, instance.stable(WorldOptions::new))
|
||||
+ : instance.group(
|
||||
Codec.LONG.fieldOf("seed").stable().forGetter(WorldOptions::seed),
|
||||
Codec.BOOL.fieldOf("generate_features").orElse(true).stable().forGetter(WorldOptions::generateStructures),
|
||||
Codec.BOOL.fieldOf("bonus_chest").orElse(false).stable().forGetter(WorldOptions::generateBonusChest),
|
||||
@@ -18,8 +30,14 @@ public class WorldOptions {
|
||||
)
|
||||
.apply(instance, instance.stable(WorldOptions::new))
|
||||
);
|
||||
- public static final WorldOptions DEMO_OPTIONS = new WorldOptions("North Carolina".hashCode(), true, true);
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ public static final WorldOptions DEMO_OPTIONS = isSecureSeedEnabled
|
||||
+ ? new WorldOptions((long) "North Carolina".hashCode(), su.plo.matter.Globals.createRandomWorldSeed(), true, true)
|
||||
+ : new WorldOptions("North Carolina".hashCode(), true, true);
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
private final long seed;
|
||||
+ private long[] featureSeed = su.plo.matter.Globals.createRandomWorldSeed(); // Leaf - Matter - Secure Seed
|
||||
private final boolean generateStructures;
|
||||
private final boolean generateBonusChest;
|
||||
private final Optional<String> legacyCustomOptions;
|
||||
@@ -28,14 +46,35 @@ public class WorldOptions {
|
||||
this(seed, generateStructures, generateBonusChest, Optional.empty());
|
||||
}
|
||||
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ public WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest) {
|
||||
+ this(seed, featureSeed, generateStructures, bonusChest, Optional.empty());
|
||||
+ }
|
||||
+
|
||||
+ private WorldOptions(long seed, String featureSeedJson, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
|
||||
+ this(seed, gson.fromJson(featureSeedJson, long[].class), generateStructures, bonusChest, legacyCustomOptions);
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+
|
||||
public static WorldOptions defaultWithRandomSeed() {
|
||||
- return new WorldOptions(randomSeed(), true, false);
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(randomSeed(), su.plo.matter.Globals.createRandomWorldSeed(), true, false)
|
||||
+ : new WorldOptions(randomSeed(), true, false);
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
}
|
||||
|
||||
public static WorldOptions testWorldWithRandomSeed() {
|
||||
return new WorldOptions(randomSeed(), false, false);
|
||||
}
|
||||
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ private WorldOptions(long seed, long[] featureSeed, boolean generateStructures, boolean bonusChest, Optional<String> legacyCustomOptions) {
|
||||
+ this(seed, generateStructures, bonusChest, legacyCustomOptions);
|
||||
+ this.featureSeed = featureSeed;
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+
|
||||
private WorldOptions(long seed, boolean generateStructures, boolean generateBonusChest, Optional<String> legacyCustomOptions) {
|
||||
this.seed = seed;
|
||||
this.generateStructures = generateStructures;
|
||||
@@ -47,6 +86,16 @@ public class WorldOptions {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ public long[] featureSeed() {
|
||||
+ return this.featureSeed;
|
||||
+ }
|
||||
+
|
||||
+ private String featureSeedSerialize() {
|
||||
+ return gson.toJson(this.featureSeed);
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+
|
||||
public boolean generateStructures() {
|
||||
return this.generateStructures;
|
||||
}
|
||||
@@ -59,17 +108,25 @@ public class WorldOptions {
|
||||
return this.legacyCustomOptions.isPresent();
|
||||
}
|
||||
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
public WorldOptions withBonusChest(boolean generateBonusChest) {
|
||||
- return new WorldOptions(this.seed, this.generateStructures, generateBonusChest, this.legacyCustomOptions);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(this.seed, this.featureSeed, this.generateStructures, generateBonusChest, this.legacyCustomOptions)
|
||||
+ : new WorldOptions(this.seed, this.generateStructures, generateBonusChest, this.legacyCustomOptions);
|
||||
}
|
||||
|
||||
public WorldOptions withStructures(boolean generateStructures) {
|
||||
- return new WorldOptions(this.seed, generateStructures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(this.seed, this.featureSeed, generateStructures, this.generateBonusChest, this.legacyCustomOptions)
|
||||
+ : new WorldOptions(this.seed, generateStructures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
}
|
||||
|
||||
public WorldOptions withSeed(OptionalLong seed) {
|
||||
- return new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
+ return isSecureSeedEnabled
|
||||
+ ? new WorldOptions(seed.orElse(randomSeed()), su.plo.matter.Globals.createRandomWorldSeed(), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions)
|
||||
+ : new WorldOptions(seed.orElse(randomSeed()), this.generateStructures, this.generateBonusChest, this.legacyCustomOptions);
|
||||
}
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
|
||||
public static OptionalLong parseSeed(String seed) {
|
||||
seed = seed.trim();
|
||||
diff --git a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
|
||||
index 38475f6975533909924c8d54f438cf43cdfe31a3..db58fa5d2ee42711ae5ab8b7384fccdfe756e2dc 100644
|
||||
--- a/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
|
||||
+++ b/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
|
||||
@@ -41,7 +41,11 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
|
||||
int i1 = geodeConfiguration.maxGenOffset;
|
||||
List<Pair<BlockPos, Integer>> list = Lists.newLinkedList();
|
||||
int i2 = geodeConfiguration.distributionPoints.sample(randomSource);
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldgenRandom worldgenRandom = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? new su.plo.matter.WorldgenCryptoRandom(0, 0, su.plo.matter.Globals.Salt.GEODE_FEATURE, 0)
|
||||
+ : new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed()));
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
NormalNoise normalNoise = NormalNoise.create(worldgenRandom, -4, 1.0);
|
||||
List<BlockPos> list1 = Lists.newLinkedList();
|
||||
double d = (double)i2 / geodeConfiguration.outerWallDistance.getMaxValue();
|
||||
diff --git a/net/minecraft/world/level/levelgen/structure/Structure.java b/net/minecraft/world/level/levelgen/structure/Structure.java
|
||||
index 8328e864c72b7a358d6bb1f33459b8c4df2ecb1a..05a0e97edd828ce998226fd651929b04bbb461f7 100644
|
||||
--- a/net/minecraft/world/level/levelgen/structure/Structure.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/Structure.java
|
||||
@@ -249,6 +249,11 @@ public abstract class Structure {
|
||||
}
|
||||
|
||||
private static WorldgenRandom makeRandom(long seed, ChunkPos chunkPos) {
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ if (me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
+ return new su.plo.matter.WorldgenCryptoRandom(chunkPos.x, chunkPos.z, su.plo.matter.Globals.Salt.GENERATE_FEATURE, seed);
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
worldgenRandom.setLargeFeatureSeed(seed, chunkPos.x, chunkPos.z);
|
||||
return worldgenRandom;
|
||||
diff --git a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
|
||||
index ee0d9dddb36b6879fa113299e24f1aa3b2b151cc..8a93a4eb0a4935af169ff4d4108a8c6e715187bd 100644
|
||||
--- a/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/placement/RandomSpreadStructurePlacement.java
|
||||
@@ -67,8 +67,15 @@ public class RandomSpreadStructurePlacement extends StructurePlacement {
|
||||
public ChunkPos getPotentialStructureChunk(long seed, int regionX, int regionZ) {
|
||||
int i = Math.floorDiv(regionX, this.spacing);
|
||||
int i1 = Math.floorDiv(regionZ, this.spacing);
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
- worldgenRandom.setLargeFeatureWithSalt(seed, i, i1, this.salt());
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldgenRandom worldgenRandom;
|
||||
+ if (me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
+ worldgenRandom = new su.plo.matter.WorldgenCryptoRandom(i, i1, su.plo.matter.Globals.Salt.POTENTIONAL_FEATURE, this.salt);
|
||||
+ } else {
|
||||
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+ worldgenRandom.setLargeFeatureWithSalt(seed, i, i1, this.salt());
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
int i2 = this.spacing - this.separation;
|
||||
int i3 = this.spreadType.evaluate(worldgenRandom, i2);
|
||||
int i4 = this.spreadType.evaluate(worldgenRandom, i2);
|
||||
diff --git a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
index 670335a7bbfbc9da64c389977498c22dfcd03251..d684a7c8e6455a9154b16e2c8bca5217cd1f597a 100644
|
||||
--- a/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/placement/StructurePlacement.java
|
||||
@@ -118,8 +118,16 @@ public abstract class StructurePlacement {
|
||||
public abstract StructurePlacementType<?> type();
|
||||
|
||||
private static boolean probabilityReducer(long levelSeed, int regionX, int regionZ, int salt, float probability, @org.jetbrains.annotations.Nullable Integer saltOverride) { // Paper - Add missing structure set seed configs; ignore here
|
||||
- WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
- worldgenRandom.setLargeFeatureWithSalt(levelSeed, regionX, regionZ, salt);
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldgenRandom worldgenRandom;
|
||||
+ if (me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) {
|
||||
+ worldgenRandom = new su.plo.matter.WorldgenCryptoRandom(regionX, regionZ, su.plo.matter.Globals.Salt.UNDEFINED, salt);
|
||||
+ } else {
|
||||
+ worldgenRandom = new WorldgenRandom(new LegacyRandomSource(0L));
|
||||
+ worldgenRandom.setLargeFeatureWithSalt(levelSeed, salt, regionX, regionZ);
|
||||
+ }
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
+
|
||||
return worldgenRandom.nextFloat() < probability;
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
|
||||
index eb85edaa3b7fab4f11545b0fa8bfea882dedb67d..a5b8abc06adbfcbffccfc005a625b952d8729470 100644
|
||||
--- a/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
|
||||
+++ b/net/minecraft/world/level/levelgen/structure/pools/JigsawPlacement.java
|
||||
@@ -64,7 +64,11 @@ public class JigsawPlacement {
|
||||
ChunkGenerator chunkGenerator = context.chunkGenerator();
|
||||
StructureTemplateManager structureTemplateManager = context.structureTemplateManager();
|
||||
LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
|
||||
- WorldgenRandom worldgenRandom = context.random();
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldgenRandom worldgenRandom = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? new su.plo.matter.WorldgenCryptoRandom(context.chunkPos().x, context.chunkPos().z, su.plo.matter.Globals.Salt.JIGSAW_PLACEMENT, 0)
|
||||
+ : context.random();
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
Registry<StructureTemplatePool> registry = registryAccess.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
Rotation random = Rotation.getRandom(worldgenRandom);
|
||||
StructureTemplatePool structureTemplatePool = startPool.unwrapKey()
|
||||
@@ -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 e5e946462da9e56344428139768075b7bd228ec0..9777a5b7ba9916e426ba87d6ee7cd56f0e43c195 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1420,6 +1420,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();
|
||||
@@ -1427,6 +1429,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
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Mon, 27 Jan 2025 13:01:55 +0800
|
||||
Subject: [PATCH] Tick regions api
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/ThreadedRegionizer.java b/io/papermc/paper/threadedregions/ThreadedRegionizer.java
|
||||
index 604385af903845d966382ad0a4168798e4ed4a0e..7ac803ba9706b65a0125b6e00983fe6a7947991a 100644
|
||||
--- a/io/papermc/paper/threadedregions/ThreadedRegionizer.java
|
||||
+++ b/io/papermc/paper/threadedregions/ThreadedRegionizer.java
|
||||
@@ -819,7 +819,7 @@ public final class ThreadedRegionizer<R extends ThreadedRegionizer.ThreadedRegio
|
||||
return this.deadSections.size() == this.sectionByKey.size();
|
||||
}
|
||||
|
||||
- private final double getDeadSectionPercent() {
|
||||
+ public final double getDeadSectionPercent() { // Luminol - Threaded regions api
|
||||
return (double)this.deadSections.size() / (double)this.sectionByKey.size();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Fri, 31 Jan 2025 20:28:45 +0800
|
||||
Subject: [PATCH] Add missing teleportation apis for folia
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index b17ace9118c94a756fa2901621c6b2b9bd9e5764..8a728a3af515da522cd5fab1e731bbc0607f0596 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1660,6 +1660,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
if (respawnComplete != null) {
|
||||
respawnComplete.accept(ServerPlayer.this);
|
||||
}
|
||||
+ // Luminol - Add missing teleportation apis
|
||||
+ new me.earthme.luminol.api.entity.player.PostPlayerRespawnEvent(ServerPlayer.this.getBukkitEntity()).callEvent();
|
||||
+ // Luminol end
|
||||
}
|
||||
);
|
||||
});
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 3ad00cc095588574218ca6d729ead119403202e0..ccf1914b4f48ecc0f4fe980510f42d5415ec1daa 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -4160,6 +4160,31 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
// TODO any events that can modify go HERE
|
||||
+ // Luminol start - Add missing teleportation apis
|
||||
+ org.bukkit.Location destinationLoc;
|
||||
+
|
||||
+ if (pitch == null) {
|
||||
+ if (yaw == null) {
|
||||
+ destinationLoc = io.papermc.paper.util.MCUtil.toLocation(destination, pos, Float.NaN, Float.NaN);
|
||||
+ } else {
|
||||
+ destinationLoc = io.papermc.paper.util.MCUtil.toLocation(destination, pos, yaw, Float.NaN);
|
||||
+ }
|
||||
+ }else {
|
||||
+ if (yaw == null) {
|
||||
+ destinationLoc = io.papermc.paper.util.MCUtil.toLocation(destination, pos, Float.NaN, pitch);
|
||||
+ }else {
|
||||
+ destinationLoc = io.papermc.paper.util.MCUtil.toLocation(destination, pos, yaw, pitch);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final me.earthme.luminol.api.entity.EntityTeleportAsyncEvent wrapped = new me.earthme.luminol.api.entity.EntityTeleportAsyncEvent(
|
||||
+ this.getBukkitEntity(),
|
||||
+ cause,
|
||||
+ destinationLoc
|
||||
+ );
|
||||
+
|
||||
+ wrapped.callEvent();
|
||||
+ // Luminol end
|
||||
|
||||
// check for same region
|
||||
if (destination == this.level()) {
|
||||
@@ -4276,7 +4301,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// we just select the spawn position
|
||||
case END: {
|
||||
if (destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END) {
|
||||
- BlockPos targetPos = ServerLevel.END_SPAWN_POINT;
|
||||
+ BlockPos targetPos = ServerLevel.END_SPAWN_POINT; // Luminol - Rename
|
||||
+ // Luminol start - Add missing teleportation apis
|
||||
+ final org.bukkit.Location orginalPortalLocation = io.papermc.paper.util.MCUtil.toLocation(origin, originPortal);
|
||||
+ final org.bukkit.Location targetPortalLocation = io.papermc.paper.util.MCUtil.toLocation(destination, targetPos);
|
||||
+
|
||||
+ final me.earthme.luminol.api.portal.PortalLocateEvent portalLocateEvent = new me.earthme.luminol.api.portal.PortalLocateEvent(
|
||||
+ orginalPortalLocation,
|
||||
+ targetPortalLocation
|
||||
+ );
|
||||
+
|
||||
+ portalLocateEvent.callEvent();
|
||||
+ // Luminol end
|
||||
// need to load chunks so we can create the platform
|
||||
destination.moonrise$loadChunksAsync(
|
||||
targetPos, 16, // load 16 blocks to be safe from block physics
|
||||
@@ -4301,7 +4337,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
);
|
||||
} else {
|
||||
- BlockPos spawnPos = destination.getSharedSpawnPos();
|
||||
+ BlockPos spawnPos = destination.getSharedSpawnPos(); // Luminol - Rename
|
||||
+ // Luminol start - Add missing teleportation apis
|
||||
+ final org.bukkit.Location orginalPortalLocation = io.papermc.paper.util.MCUtil.toLocation(origin, originPortal);
|
||||
+ final org.bukkit.Location targetPortalLocation = io.papermc.paper.util.MCUtil.toLocation(destination, spawnPos);
|
||||
+
|
||||
+ final me.earthme.luminol.api.portal.PortalLocateEvent portalLocateEvent = new me.earthme.luminol.api.portal.PortalLocateEvent(
|
||||
+ orginalPortalLocation,
|
||||
+ targetPortalLocation
|
||||
+ );
|
||||
+
|
||||
+ portalLocateEvent.callEvent();
|
||||
+ // Luminol end
|
||||
// need to load chunk for heightmap
|
||||
destination.moonrise$loadChunksAsync(
|
||||
spawnPos, 0,
|
||||
@@ -4356,8 +4403,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
WorldBorder destinationBorder = destination.getWorldBorder();
|
||||
double dimensionScale = net.minecraft.world.level.dimension.DimensionType.getTeleportationScale(origin.dimensionType(), destination.dimensionType());
|
||||
- BlockPos targetPos = destination.getWorldBorder().clampToBounds(this.getX() * dimensionScale, this.getY(), this.getZ() * dimensionScale);
|
||||
+ BlockPos targetPos = destination.getWorldBorder().clampToBounds(this.getX() * dimensionScale, this.getY(), this.getZ() * dimensionScale); // Luminol - Rename
|
||||
+ // Luminol start - Add missing teleportation apis
|
||||
+ final org.bukkit.Location orginalPortalLocation = io.papermc.paper.util.MCUtil.toLocation(origin, originPortal);
|
||||
+ final org.bukkit.Location targetPortalLocation = io.papermc.paper.util.MCUtil.toLocation(destination, targetPos);
|
||||
+
|
||||
+ final me.earthme.luminol.api.portal.PortalLocateEvent portalLocateEvent = new me.earthme.luminol.api.portal.PortalLocateEvent(
|
||||
+ orginalPortalLocation,
|
||||
+ targetPortalLocation
|
||||
+ );
|
||||
|
||||
+ portalLocateEvent.callEvent();
|
||||
+ // Luminol end
|
||||
ca.spottedleaf.concurrentutil.completable.CallbackCompletable<BlockUtil.FoundRectangle> portalFound
|
||||
= new ca.spottedleaf.concurrentutil.completable.CallbackCompletable<>();
|
||||
|
||||
@@ -4494,9 +4551,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (!this.canPortalAsync(destination, takePassengers)) {
|
||||
return false;
|
||||
}
|
||||
+ // Luminol start - Add missing teleportation events
|
||||
+ if (!new me.earthme.luminol.api.entity.PreEntityPortalEvent(
|
||||
+ this.getBukkitEntity(),
|
||||
+ io.papermc.paper.util.MCUtil.toLocation(this.level, portalPos),
|
||||
+ destination.getWorld()
|
||||
+ ).callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Luminol end
|
||||
// Kaiiju start - sync end platform spawning & entity teleportation
|
||||
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 -> { 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
|
||||
|
||||
Vec3 initialPosition = this.position();
|
||||
@@ -4570,6 +4636,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
tpComplete.accept(teleported);
|
||||
}
|
||||
// Kaiiju end
|
||||
+ // Luminol start - Add missing teleportation events
|
||||
+ new me.earthme.luminol.api.entity.PostEntityPortalEvent(teleported.getBukkitEntity()).callEvent();
|
||||
+ // Luminol end
|
||||
}
|
||||
);
|
||||
});
|
||||
diff --git a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
index 95e2dff6782bf7767ecb1a23e618862919ea71aa..386c38273e21ba6b48f9fad67fddc39255138e14 100644
|
||||
--- a/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 {
|
||||
portalTile.trySearchForExit(portalWorld, portalPos);
|
||||
return false;
|
||||
}
|
||||
+ // Luminol start - Add missing teleportation apis
|
||||
+ final org.bukkit.Location orginalPortalLocation = io.papermc.paper.util.MCUtil.toLocation(toTeleport.level(), portalPos);
|
||||
+ final org.bukkit.Location targetPortalLocation = io.papermc.paper.util.MCUtil.toLocation(portalWorld, teleportPos);
|
||||
+
|
||||
+ final me.earthme.luminol.api.portal.PortalLocateEvent portalLocateEvent = new me.earthme.luminol.api.portal.PortalLocateEvent(
|
||||
+ orginalPortalLocation,
|
||||
+ targetPortalLocation
|
||||
+ );
|
||||
+
|
||||
+ portalLocateEvent.callEvent();
|
||||
+ // Luminol end
|
||||
+
|
||||
|
||||
// note: we handle the position from the TeleportTransition
|
||||
net.minecraft.world.level.portal.TeleportTransition teleport = net.minecraft.world.level.block.EndGatewayBlock.getTeleportTransition(
|
||||
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: adabugra <57899270+adabugra@users.noreply.github.com>
|
||||
Date: Fri, 31 Jan 2025 19:17:01 +0300
|
||||
Subject: [PATCH] Leaves Disable moved wrongly threshold
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index a107d9ee24d0e39ce3e3e09bf27af1ea4ae35b96..225045400f152a9a8f030d6fe367764b00d99b24 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -581,7 +581,7 @@ public class ServerGamePacketListenerImpl
|
||||
return;
|
||||
}
|
||||
// Paper end - Prevent moving into unloaded chunks
|
||||
- if (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
|
||||
+ if (!me.earthme.luminol.config.modules.misc.DisableMovedWronglyThreshold.enabled && d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // Leaves - disable can
|
||||
// CraftBukkit end
|
||||
LOGGER.warn(
|
||||
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
|
||||
@@ -611,7 +611,7 @@ public class ServerGamePacketListenerImpl
|
||||
d5 = d2 - rootVehicle.getZ();
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag2 = false;
|
||||
- if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
|
||||
+ if (!me.earthme.luminol.config.modules.misc.DisableMovedWronglyThreshold.enabled && d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot / Leaves - disable can
|
||||
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));
|
||||
}
|
||||
@@ -1437,7 +1437,7 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
if (this.shouldCheckPlayerMovement(isFallFlying)) {
|
||||
float f2 = isFallFlying ? 300.0F : 100.0F;
|
||||
- if (d7 - d6 > Math.max(f2, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed))) {
|
||||
+ if (!me.earthme.luminol.config.modules.misc.DisableMovedWronglyThreshold.enabled && d7 - d6 > Math.max(f2, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed))) { // Leaves - disable can
|
||||
// CraftBukkit end
|
||||
// Paper start - Add fail move event
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY,
|
||||
@@ -1509,7 +1509,8 @@ public class ServerGamePacketListenerImpl
|
||||
d5 = d2 - this.player.getZ();
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean movedWrongly = false; // Paper - Add fail move event; rename
|
||||
- if (!this.player.isChangingDimension()
|
||||
+ if (!me.earthme.luminol.config.modules.misc.DisableMovedWronglyThreshold.enabled // Leaves - disable can
|
||||
+ && !this.player.isChangingDimension()
|
||||
&& d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold // Spigot
|
||||
&& !this.player.isSleeping()
|
||||
&& !this.player.gameMode.isCreative()
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 5 Feb 2025 15:22:19 +0800
|
||||
Subject: [PATCH] Raytracing tracker experiment
|
||||
|
||||
Based on the framework of EntityCulling(((((((
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff717d9a86 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1208,7 +1208,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
double d1 = vec3_dx * vec3_dx + vec3_dz * vec3_dz; // Paper
|
||||
double d2 = d * d;
|
||||
// Paper start - Configurable entity tracking range by Y
|
||||
- boolean flag = d1 <= d2;
|
||||
+ boolean flag = d1 <= d2 && !entity.isCulled(); // Luminol - Ray tracing entity tracker
|
||||
if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
|
||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
if (rangeY != -1) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index ccf1914b4f48ecc0f4fe980510f42d5415ec1daa..ceca76a5791e319dd7cc4048c9860b1df065b95a 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
|
||||
import net.minecraft.world.scores.Team;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
-public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker
|
||||
+public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity, dev.tr7zw.entityculling.versionless.access.Cullable { // Paper - rewrite chunk system // Paper - optimise entity tracker // Luminol - Ray tracing entity tracker
|
||||
|
||||
// CraftBukkit start
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
@@ -6049,4 +6049,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// Paper end - Expose entity id counter
|
||||
|
||||
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||
+
|
||||
+ private long lasttime = 0;
|
||||
+ private boolean culled = false;
|
||||
+ private boolean outOfCamera = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTimeout() {
|
||||
+ this.lasttime = System.currentTimeMillis() + 1000;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isForcedVisible() {
|
||||
+ return this.lasttime > System.currentTimeMillis();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCulled(boolean value) {
|
||||
+ this.culled = value;
|
||||
+ if (!value) {
|
||||
+ setTimeout();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCulled() {
|
||||
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled)
|
||||
+ return false;
|
||||
+ return this.culled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setOutOfCamera(boolean value) {
|
||||
+ this.outOfCamera = value;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOutOfCamera() {
|
||||
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled)
|
||||
+ return false;
|
||||
+ return this.outOfCamera;
|
||||
+ }
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
|
||||
index d9cc1d7e56c37d5ce92544edc10e89dbc89dd15d..39e7689be243b9c99b507d665f6591359115287b 100644
|
||||
--- a/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/net/minecraft/world/entity/EntityType.java
|
||||
@@ -1097,6 +1097,9 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
public final int passengerTickTimerId;
|
||||
public final int passengerInactiveTickTimerId;
|
||||
// Folia end - profiler
|
||||
+ // Luminol - Raytracing entity tracker
|
||||
+ public boolean skipRaytracningCheck = false;
|
||||
+ // Luminol end
|
||||
|
||||
public EntityType(
|
||||
EntityType.EntityFactory<T> factory,
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index c6252a245e9701f69db1fe167f6590095237553a..40b91234fd2e4f4f134d309590ea6b605f764e83 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -211,6 +211,25 @@ public abstract class Player extends LivingEntity {
|
||||
return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity();
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Luminol start - Raytracing entity tracker
|
||||
+ public dev.tr7zw.entityculling.CullTask cullTask;
|
||||
+ {
|
||||
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled) {
|
||||
+ this.cullTask = null;
|
||||
+ }else {
|
||||
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
|
||||
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance,
|
||||
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(this.level())
|
||||
+ );
|
||||
+
|
||||
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
|
||||
+ culling, this,
|
||||
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.hitboxLimit,
|
||||
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.checkIntervalMs
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ // Luminol end
|
||||
|
||||
public Player(Level level, BlockPos pos, float yRot, GameProfile gameProfile) {
|
||||
super(EntityType.PLAYER, level);
|
||||
@@ -263,6 +282,26 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Luminol start - Ray tracing entity tracker
|
||||
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled) {
|
||||
+ if (this.cullTask != null) this.cullTask.signalStop();
|
||||
+ this.cullTask = null;
|
||||
+ }else {
|
||||
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
|
||||
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance,
|
||||
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(this.level())
|
||||
+ );
|
||||
+
|
||||
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
|
||||
+ culling, this,
|
||||
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.hitboxLimit,
|
||||
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.checkIntervalMs
|
||||
+ );
|
||||
+ }
|
||||
+ if (this.cullTask != null) this.cullTask.setup();
|
||||
+ if (this.cullTask != null) this.cullTask.requestCullSignal(); // Luminol - Ray tracing entity tracker
|
||||
+ // Luminol end
|
||||
+
|
||||
this.noPhysics = this.isSpectator();
|
||||
if (this.isSpectator() || this.isPassenger()) {
|
||||
this.setOnGround(false);
|
||||
@@ -1505,6 +1544,7 @@ public abstract class Player extends LivingEntity {
|
||||
if (this.containerMenu != null && this.hasContainerOpen()) {
|
||||
this.doCloseContainer();
|
||||
}
|
||||
+ if (this.cullTask != null) this.cullTask.signalStop(); // Luminol - Ray tracing entity tracker
|
||||
}
|
||||
|
||||
// Folia start - region threading
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <mrhua269@gmail.com>
|
||||
Date: Fri, 4 Apr 2025 08:17:32 +0800
|
||||
Subject: [PATCH] Correct isWatched method in ScheduledTaskThreadPool
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/ScheduledTaskThreadPool.java b/io/papermc/paper/threadedregions/ScheduledTaskThreadPool.java
|
||||
index 5c591b0d6eac45d6094ce44bf62ad976bf995e66..287d8b929d1c0802705a7ff276e4146682203061 100644
|
||||
--- a/io/papermc/paper/threadedregions/ScheduledTaskThreadPool.java
|
||||
+++ b/io/papermc/paper/threadedregions/ScheduledTaskThreadPool.java
|
||||
@@ -1229,7 +1229,7 @@ public final class ScheduledTaskThreadPool {
|
||||
}
|
||||
|
||||
public boolean isWatched() {
|
||||
- return (boolean)TAKEN_HANDLE.getVolatile(this);
|
||||
+ return (boolean)WATCHED_HANDLE.getVolatile(this); // Luminol - Try fixing scheduling call issue
|
||||
}
|
||||
|
||||
public long getLastTaskNotify() {
|
||||
@@ -0,0 +1,105 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 11 Apr 2025 16:53:57 +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..8672757a4d5fb5c247599782fece6b8d7d6ec921 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/Raid.java b/net/minecraft/world/entity/raid/Raid.java
|
||||
index 2f45befbb50645f1bfb5961ad725f3670ff0d592..84c6eb2c27510938f590f6c6baa5a94c4c08c4ad 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raid.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raid.java
|
||||
@@ -674,7 +674,7 @@ public class Raid {
|
||||
int i2 = this.center.getX() + Mth.floor(Mth.cos(f2) * 32.0F * f) + this.level.random.nextInt(3) * Mth.floor(f);
|
||||
int i3 = this.center.getZ() + Mth.floor(Mth.sin(f2) * 32.0F * f) + this.level.random.nextInt(3) * Mth.floor(f);
|
||||
int height = this.level.getHeight(Heightmap.Types.WORLD_SURFACE, i2, i3);
|
||||
- if (Mth.abs(height - this.center.getY()) <= 96) {
|
||||
+ if (me.earthme.luminol.config.modules.misc.RaidChangesConfig.height_check || Mth.abs(height - this.center.getY()) <= 96) { // Disable height check
|
||||
mutableBlockPos.set(i2, height, i3);
|
||||
if (!this.level.isVillage(mutableBlockPos) || i <= 7) {
|
||||
int i4 = 10;
|
||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||
index 7c385baae81b9a987c0e1e4deb017884600331bc..a0d86c3cc86da734a3cd10d554aaecb5c0b82e59 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 && !this.hasRaid()) {
|
||||
+ 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, me.earthme.luminol.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 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);
|
||||
diff --git a/net/minecraft/world/item/component/OminousBottleAmplifier.java b/net/minecraft/world/item/component/OminousBottleAmplifier.java
|
||||
index 318f24d67be4daf6993ba547da0540be9c221a75..9a6820fce3977419fd81d802720c318ac15d07c4 100644
|
||||
--- a/net/minecraft/world/item/component/OminousBottleAmplifier.java
|
||||
+++ b/net/minecraft/world/item/component/OminousBottleAmplifier.java
|
||||
@@ -28,7 +28,7 @@ public record OminousBottleAmplifier(int value) implements ConsumableListener, T
|
||||
|
||||
@Override
|
||||
public void onConsume(Level level, LivingEntity entity, ItemStack stack, Consumable consumable) {
|
||||
- entity.addEffect(new MobEffectInstance(MobEffects.BAD_OMEN, 120000, this.value, false, false, true)); // Paper - properly resend entities - diff on change for below
|
||||
+ entity.addEffect(new MobEffectInstance(MobEffects.BAD_OMEN, me.earthme.luminol.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 120000, this.value, false, false, true)); // Paper - properly resend entities - diff on change for below
|
||||
}
|
||||
|
||||
// Paper start - properly resend entities - collect packets for bundle
|
||||
@@ -40,7 +40,7 @@ public record OminousBottleAmplifier(int value) implements ConsumableListener, T
|
||||
|
||||
@Override
|
||||
public void addToTooltip(Item.TooltipContext context, Consumer<Component> tooltipAdder, TooltipFlag tooltipFlag) {
|
||||
- List<MobEffectInstance> list = List.of(new MobEffectInstance(MobEffects.BAD_OMEN, 120000, this.value, false, false, true));
|
||||
+ List<MobEffectInstance> list = List.of(new MobEffectInstance(MobEffects.BAD_OMEN, me.earthme.luminol.config.modules.misc.RaidChangesConfig.infinite ? net.minecraft.world.effect.MobEffectInstance.INFINITE_DURATION : 120000, this.value, false, false, true));
|
||||
PotionContents.addPotionTooltip(list, tooltipAdder, 1.0F, context.tickRate());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 13 Apr 2025 11:07:04 +0800
|
||||
Subject: [PATCH] Disable Heightmap Warning
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/levelgen/Heightmap.java b/net/minecraft/world/level/levelgen/Heightmap.java
|
||||
index 3b27bcfbbe0529d1526adc30760c846b4011645f..95747ae41cea0d4b577c58ef44959a18e0a46672 100644
|
||||
--- a/net/minecraft/world/level/levelgen/Heightmap.java
|
||||
+++ b/net/minecraft/world/level/levelgen/Heightmap.java
|
||||
@@ -123,7 +123,8 @@ public class Heightmap {
|
||||
if (raw.length == data.length) {
|
||||
System.arraycopy(data, 0, raw, 0, data.length);
|
||||
} else {
|
||||
- LOGGER.warn("Ignoring heightmap data for chunk " + chunk.getPos() + ", size does not match; expected: " + raw.length + ", got: " + data.length);
|
||||
+ if (!me.earthme.luminol.config.modules.misc.DisableHeightmapWarnConfig.enabled)
|
||||
+ LOGGER.warn("Ignoring heightmap data for chunk " + chunk.getPos() + ", size does not match; expected: " + raw.length + ", got: " + data.length);
|
||||
primeHeightmaps(chunk, EnumSet.of(type));
|
||||
}
|
||||
}
|
||||
@@ -1,57 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <novau233@163.com>
|
||||
Date: Tue, 6 Feb 2024 01:35:36 +0000
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 09:56:38 +0800
|
||||
Subject: [PATCH] Rebrand to Luminol
|
||||
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 32bfe781e5298e5ad1bd2ed4471fb824c49f0ab4..f9919b9da90317bd615d7e57607df73ebcc1d077 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -80,14 +80,14 @@ tasks.jar {
|
||||
val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper
|
||||
attributes(
|
||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||
- "Implementation-Title" to "Folia", // Folia
|
||||
+ "Implementation-Title" to "Luminol", // Folia // Luminol
|
||||
"Implementation-Version" to implementationVersion,
|
||||
"Implementation-Vendor" to date, // Paper
|
||||
- "Specification-Title" to "Folia", // Folia
|
||||
+ "Specification-Title" to "Luminol", // Folia // Luminol
|
||||
"Specification-Version" to project.version,
|
||||
- "Specification-Vendor" to "Paper Team",
|
||||
- "Brand-Id" to "papermc:folia", // Folia
|
||||
- "Brand-Name" to "Folia", // Folia
|
||||
+ "Specification-Vendor" to "LuminolMC Team", // Luminol
|
||||
+ "Brand-Id" to "luminolmc:luminol", // Folia // Luminol
|
||||
+ "Brand-Name" to "Luminol", // Folia // Luminol
|
||||
"Build-Number" to (build ?: ""),
|
||||
"Build-Time" to Instant.now().toString(),
|
||||
"Git-Branch" to gitBranch, // Paper
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
|
||||
index cb60d58d4a7556dd896f31d0cd249f860bb3ef84..b52a805150e95d7d27403d3c18088b335a355011 100644
|
||||
index f5ff71e31516327be71924926938f1c9f0e503df..338e61f5cfa0c556245228462df45954ac52bc4f 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
|
||||
@@ -593,7 +593,7 @@ public class Metrics {
|
||||
@@ -592,7 +592,7 @@ public class Metrics {
|
||||
boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
// Only start Metrics, if it's enabled in the config
|
||||
if (config.getBoolean("enabled", true)) {
|
||||
- Metrics metrics = new Metrics("Folia", serverUUID, logFailedRequests, Bukkit.getLogger()); // Folia - we have our own bstats page
|
||||
+ Metrics metrics = new Metrics("Luminol", serverUUID, logFailedRequests, Bukkit.getLogger()); // Folia - we have our own bstats page //Luminol
|
||||
+ Metrics metrics = new Metrics("Luminol", serverUUID, logFailedRequests, Bukkit.getLogger()); // Folia - we have our own bstats page // Luminol
|
||||
|
||||
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
|
||||
String minecraftVersion = Bukkit.getVersion();
|
||||
@@ -611,7 +611,7 @@ public class Metrics {
|
||||
@@ -606,11 +606,11 @@ public class Metrics {
|
||||
final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion();
|
||||
if (implVersion != null) {
|
||||
final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1);
|
||||
- paperVersion = "git-Folia-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Folia - we have our own bstats page
|
||||
+ paperVersion = "git-Luminol-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Folia - we have our own bstats page // Luminol - Rebrand to Luminol
|
||||
} else {
|
||||
paperVersion = "unknown";
|
||||
}
|
||||
- metrics.addCustomChart(new Metrics.SimplePie("folia_version", () -> paperVersion)); // Folia - we have our own bstats page
|
||||
+ metrics.addCustomChart(new Metrics.SimplePie("luminol_version", () -> paperVersion)); // Folia - we have our own bstats page //Luminol
|
||||
+ metrics.addCustomChart(new Metrics.SimplePie("luminol_version", () -> paperVersion)); // Folia - we have our own bstats page // Luminol
|
||||
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
|
||||
Map<String, Map<String, Integer>> map = new HashMap<>();
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
||||
index 29bd788ae8bc61c1e62a4f84b9e259931a7041ce..2f37873738ab542980d13f36356b04b4904e625b 100644
|
||||
index 29bd788ae8bc61c1e62a4f84b9e259931a7041ce..1676ac5e6c8369836bf719f338603fbbc3105b1e 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
||||
@@ -35,7 +35,7 @@ public class PaperVersionFetcher implements VersionFetcher {
|
||||
@@ -72,6 +53,15 @@ index 29bd788ae8bc61c1e62a4f84b9e259931a7041ce..2f37873738ab542980d13f36356b04b4
|
||||
}
|
||||
final @Nullable Component history = this.getHistory();
|
||||
|
||||
@@ -60,7 +60,7 @@ public class PaperVersionFetcher implements VersionFetcher {
|
||||
int distance = DISTANCE_ERROR;
|
||||
|
||||
final OptionalInt buildNumber = build.buildNumber();
|
||||
- if (buildNumber.isPresent()) {
|
||||
+ if (buildNumber.isPresent() && false) { // Luminol
|
||||
distance = fetchDistanceFromSiteApi(build, buildNumber.getAsInt());
|
||||
} else {
|
||||
final Optional<String> gitBranch = build.gitBranch();
|
||||
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
|
||||
index e741201fdbea0dbbc0e42313ebd33368014c9dc4..673a81734a0903a0790f3007772642d3d9a044cc 100644
|
||||
--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 11:58:56 +0800
|
||||
Subject: [PATCH] Add config for server mod name
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
||||
index 6ed2114f577ce12d2d493985e798609c7d83f15e..7a5dcf3b7108794b9a224004730eb396a96cce8f 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
||||
@@ -14,7 +14,7 @@ class PaperServerListPingEventImpl extends PaperServerListPingEvent {
|
||||
|
||||
PaperServerListPingEventImpl(MinecraftServer server, StatusClient client, int protocolVersion, @Nullable CachedServerIcon icon) {
|
||||
super(client, server.motd(), server.getPlayerCount(), server.getMaxPlayers(),
|
||||
- server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);
|
||||
+ me.earthme.luminol.config.modules.misc.ServerModNameConfig.fakeVanilla ? server.getServerVersion() : server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);//Luminol - Fake vanilla mode
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 12:00:30 +0800
|
||||
Subject: [PATCH] Add config to disable async catchers
|
||||
|
||||
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
|
||||
index c95769a4e64fabd7acdff6c5f6f349107e1cf5c0..4efa1c057ae6cfdea7889c372bd62dc14637daa0 100644
|
||||
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
|
||||
@@ -48,14 +48,14 @@ public class TickThread extends Thread {
|
||||
*/
|
||||
@Deprecated
|
||||
public static void ensureTickThread(final String reason) {
|
||||
- if (!isTickThread()) {
|
||||
+ if (!isTickThread() && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable());
|
||||
throw new IllegalStateException(reason);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) {
|
||||
- if (!isTickThreadFor(world, pos)) {
|
||||
+ if (!isTickThreadFor(world, pos) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos;
|
||||
LOGGER.error(ex, new Throwable());
|
||||
@@ -64,7 +64,7 @@ public class TickThread extends Thread {
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) {
|
||||
- if (!isTickThreadFor(world, pos, blockRadius)) {
|
||||
+ if (!isTickThreadFor(world, pos, blockRadius) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius;
|
||||
LOGGER.error(ex, new Throwable());
|
||||
@@ -73,7 +73,7 @@ public class TickThread extends Thread {
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) {
|
||||
- if (!isTickThreadFor(world, pos)) {
|
||||
+ if (!isTickThreadFor(world, pos) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos;
|
||||
LOGGER.error(ex, new Throwable());
|
||||
@@ -82,7 +82,7 @@ public class TickThread extends Thread {
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) {
|
||||
- if (!isTickThreadFor(world, chunkX, chunkZ)) {
|
||||
+ if (!isTickThreadFor(world, chunkX, chunkZ) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ);
|
||||
LOGGER.error(ex, new Throwable());
|
||||
@@ -91,7 +91,7 @@ public class TickThread extends Thread {
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Entity entity, final String reason) {
|
||||
- if (!isTickThreadFor(entity)) {
|
||||
+ if (!isTickThreadFor(entity) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity);
|
||||
LOGGER.error(ex, new Throwable());
|
||||
@@ -100,7 +100,7 @@ public class TickThread extends Thread {
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Level world, final AABB aabb, final String reason) {
|
||||
- if (!isTickThreadFor(world, aabb)) {
|
||||
+ if (!isTickThreadFor(world, aabb) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb;
|
||||
LOGGER.error(ex, new Throwable());
|
||||
@@ -109,7 +109,7 @@ public class TickThread extends Thread {
|
||||
}
|
||||
|
||||
public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) {
|
||||
- if (!isTickThreadFor(world, blockX, blockZ)) {
|
||||
+ if (!isTickThreadFor(world, blockX, blockZ) && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Luminol
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
|
||||
LOGGER.error(ex, new Throwable());
|
||||
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
index 50f01faa88c8c658252fade3748f20e48e9c8432..36fa1f83c3286e10cc7c208a2a2f1a718d525ad8 100644
|
||||
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
@@ -7,7 +7,7 @@ public class AsyncCatcher {
|
||||
public static boolean enabled = true;
|
||||
|
||||
public static void catchOp(String reason) {
|
||||
- if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) { // Paper - chunk system
|
||||
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThread() && !me.earthme.luminol.config.modules.experiment.DisableAsyncCatcherConfig.enabled) { // Paper - chunk system // Luminol
|
||||
MinecraftServer.LOGGER.error("Thread {} failed main thread check: {}", Thread.currentThread().getName(), reason, new Throwable()); // Paper
|
||||
throw new IllegalStateException("Asynchronous " + reason + "!");
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <mrhua269@gmail.com>
|
||||
Date: Sat, 22 Mar 2025 09:24:55 +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 512ef437119041b33b62ef4675bdd1b27fd9a403..628211a282ef0553a0229b6cadacd2727d967873 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -2442,6 +2442,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2463,6 +2472,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());
|
||||
@@ -3672,4 +3690,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public void setSimplifyContainerDesyncCheck(final boolean simplifyContainerDesyncCheck) {
|
||||
this.simplifyContainerDesyncCheck = simplifyContainerDesyncCheck;
|
||||
}
|
||||
+
|
||||
+ // KioCG start - ChunkHot
|
||||
+ @Override
|
||||
+ public long getNearbyChunkHot() {
|
||||
+ return this.getHandle().getNearbyChunkHot();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:00:50 +0800
|
||||
Subject: [PATCH] Force disable builtin spark plugin
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java b/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java
|
||||
index a0b84535a9d3833d4df692b85b272f145559dd80..c2ba46408b5ad727d7a17f21d47b2898bb1ef8b4 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java
|
||||
@@ -87,7 +87,7 @@ public class FileProviderSource implements ProviderSource<Path, Path> {
|
||||
}
|
||||
|
||||
final PluginMeta config = type.getConfig(file);
|
||||
- if ((config.getName().equals("spark") && config.getMainClass().equals("me.lucko.spark.bukkit.BukkitSparkPlugin")) && !SparksFly.isPluginPreferred()) {
|
||||
+ if ((config.getName().equals("spark") && config.getMainClass().equals("me.lucko.spark.bukkit.BukkitSparkPlugin")) && !SparksFly.isPluginPreferred() && false) { // Luminol - Force disable builtin spark
|
||||
LOGGER.info("The spark plugin will not be loaded as this server bundles the spark profiler.");
|
||||
return;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 935ac76cec67ea661a392ff02396aa7aefd56268..58275b09c75b9913c2249c5c8190027143121070 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -314,7 +314,7 @@ public final class CraftServer implements Server {
|
||||
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.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes
|
||||
- public final io.papermc.paper.SparksFly spark; // Paper - spark
|
||||
+ public io.papermc.paper.SparksFly spark; // Paper - spark // Luminol - Force disable builtin spark
|
||||
|
||||
// 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
|
||||
@@ -492,7 +492,7 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
|
||||
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
||||
- this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark
|
||||
+ if (false) this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark // Luminol - Force disable builtin spark
|
||||
}
|
||||
|
||||
public boolean getCommandBlockOverride(String command) {
|
||||
@@ -1156,7 +1156,7 @@ public final class CraftServer implements Server {
|
||||
this.reloadData();
|
||||
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
|
||||
- this.spark.registerCommandBeforePlugins(this); // Paper - spark
|
||||
+ if (false) this.spark.registerCommandBeforePlugins(this); // Paper - spark // Luminol - Force disable builtin spark
|
||||
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
|
||||
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
|
||||
|
||||
@@ -1185,7 +1185,7 @@ public final class CraftServer implements Server {
|
||||
this.loadPlugins();
|
||||
this.enablePlugins(PluginLoadOrder.STARTUP);
|
||||
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
||||
- this.spark.registerCommandAfterPlugins(this); // Paper - spark
|
||||
+ if (false) this.spark.registerCommandAfterPlugins(this); // Paper - spark // Luminol - Force disable builtin spark
|
||||
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
|
||||
// Paper start - brigadier command API
|
||||
io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setValid(); // to clear invalid state for event fire below
|
||||
@@ -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
|
||||
}
|
||||
@@ -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) {
|
||||
@@ -1,27 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <novau233@163.com>
|
||||
Date: Sun, 28 Jan 2024 09:11:58 +0000
|
||||
Subject: [PATCH] Sparkly Paper Optimize canSee checks
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 11:46:26 +0800
|
||||
Subject: [PATCH] SparklyPaper Optimize canSee checks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 4a0c5afd03dba788c40a71f00bc1fd0d4f0fc7e4..04f5efdc0d5729af5009e51a3e36ed7c34991123 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1422,7 +1422,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Folia end - region threading
|
||||
|
||||
// CraftBukkit start - respect vanish API
|
||||
- if (flag && (!io.papermc.paper.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSee(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading
|
||||
+ if (flag && (!io.papermc.paper.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSeeChunkMapUpdatePlayer(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading // SparklyPaper - optimize canSee checks
|
||||
flag = false;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 28583ad8117167400faf3ca0dc4bc9f3f44dbedb..a3d4dc232d011c262d85028351191ac2b8547398 100644
|
||||
index 628211a282ef0553a0229b6cadacd2727d967873..583c2acc6d620b4411c65c2b285d323d7c9c1b98 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -198,7 +198,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
@@ -210,7 +210,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private boolean hasPlayedBefore = false;
|
||||
private final ConversationTracker conversationTracker = new ConversationTracker();
|
||||
private final Set<String> channels = new HashSet<String>();
|
||||
@@ -30,7 +17,7 @@ index 28583ad8117167400faf3ca0dc4bc9f3f44dbedb..a3d4dc232d011c262d85028351191ac2
|
||||
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
||||
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
||||
private int hash = 0;
|
||||
@@ -2234,9 +2234,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
@@ -2306,9 +2306,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public boolean canSee(org.bukkit.entity.Entity entity) {
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Mon, 29 Jul 2024 20:05:34 +0800
|
||||
Date: Sun, 12 Jan 2025 15:37:56 +0800
|
||||
Subject: [PATCH] Leaf Skip event if no listeners
|
||||
|
||||
|
||||
@@ -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 58275b09c75b9913c2249c5c8190027143121070..cb406334c316aaf7fc66060b90781eaace883c01 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));
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
+}
|
||||
@@ -0,0 +1,625 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/abomination/LinearRegionFile.java
|
||||
@@ -1,0 +_,622 @@
|
||||
+package abomination;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
||||
+import com.github.luben.zstd.ZstdInputStream;
|
||||
+import com.github.luben.zstd.ZstdOutputStream;
|
||||
+import com.mojang.logging.LogUtils;
|
||||
+import net.jpountz.lz4.LZ4Compressor;
|
||||
+import net.jpountz.lz4.LZ4Factory;
|
||||
+import net.jpountz.lz4.LZ4FastDecompressor;
|
||||
+import net.openhft.hashing.LongHashFunction;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
|
||||
+import net.minecraft.world.level.chunk.storage.RegionFileVersion;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import org.slf4j.Logger;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+import java.io.*;
|
||||
+import java.nio.ByteBuffer;
|
||||
+import java.nio.file.Files;
|
||||
+import java.nio.file.Path;
|
||||
+import java.nio.file.StandardCopyOption;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+import java.util.concurrent.locks.LockSupport;
|
||||
+import java.util.concurrent.locks.ReentrantLock;
|
||||
+
|
||||
+// LinearRegionFile_implementation_version_0_5byXymb
|
||||
+// Just gonna use this string to inform other forks about updates ;-)
|
||||
+public class LinearRegionFile implements IRegionFile{
|
||||
+ private static final long SUPERBLOCK = 0xc3ff13183cca9d9aL;
|
||||
+ private static final byte VERSION = 3;
|
||||
+ private static final int HEADER_SIZE = 27;
|
||||
+ private static final int FOOTER_SIZE = 8;
|
||||
+ private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+
|
||||
+ private byte[][] bucketBuffers;
|
||||
+ private final byte[][] buffer = new byte[1024][];
|
||||
+ private final int[] bufferUncompressedSize = new int[1024];
|
||||
+
|
||||
+ private final long[] chunkTimestamps = new long[1024];
|
||||
+ private final Object markedToSaveLock = new Object();
|
||||
+
|
||||
+ private final LZ4Compressor compressor;
|
||||
+ private final LZ4FastDecompressor decompressor;
|
||||
+
|
||||
+ private boolean markedToSave = false;
|
||||
+ private boolean close = false;
|
||||
+
|
||||
+ public final ReentrantLock fileLock = new ReentrantLock(true);
|
||||
+ public Path regionFile;
|
||||
+
|
||||
+ private final int compressionLevel;
|
||||
+ private int gridSize = 8;
|
||||
+ private int bucketSize = 4;
|
||||
+ private final Thread bindThread;
|
||||
+
|
||||
+ public Path getRegionFile() {
|
||||
+ return this.regionFile;
|
||||
+ }
|
||||
+
|
||||
+ public ReentrantLock getFileLock() {
|
||||
+ return this.fileLock;
|
||||
+ }
|
||||
+
|
||||
+ private int chunkToBucketIdx(int chunkX, int chunkZ) {
|
||||
+ int bx = chunkX / bucketSize, bz = chunkZ / bucketSize;
|
||||
+ return bx * gridSize + bz;
|
||||
+ }
|
||||
+
|
||||
+ private void openBucket(int chunkX, int chunkZ) {
|
||||
+ chunkX = Math.floorMod(chunkX, 32);
|
||||
+ chunkZ = Math.floorMod(chunkZ, 32);
|
||||
+ int idx = chunkToBucketIdx(chunkX, chunkZ);
|
||||
+
|
||||
+ if (bucketBuffers == null) return;
|
||||
+ if (bucketBuffers[idx] != null) {
|
||||
+ try {
|
||||
+ ByteArrayInputStream bucketByteStream = new ByteArrayInputStream(bucketBuffers[idx]);
|
||||
+ ZstdInputStream zstdStream = new ZstdInputStream(bucketByteStream);
|
||||
+ ByteBuffer bucketBuffer = ByteBuffer.wrap(zstdStream.readAllBytes());
|
||||
+
|
||||
+ int bx = chunkX / bucketSize, bz = chunkZ / bucketSize;
|
||||
+
|
||||
+ for (int cx = 0; cx < 32 / gridSize; cx++) {
|
||||
+ for (int cz = 0; cz < 32 / gridSize; cz++) {
|
||||
+ int chunkIndex = (bx * (32 / gridSize) + cx) + (bz * (32 / gridSize) + cz) * 32;
|
||||
+
|
||||
+ int chunkSize = bucketBuffer.getInt();
|
||||
+ long timestamp = bucketBuffer.getLong();
|
||||
+ this.chunkTimestamps[chunkIndex] = timestamp;
|
||||
+
|
||||
+ if (chunkSize > 0) {
|
||||
+ byte[] chunkData = new byte[chunkSize - 8];
|
||||
+ bucketBuffer.get(chunkData);
|
||||
+
|
||||
+ int maxCompressedLength = this.compressor.maxCompressedLength(chunkData.length);
|
||||
+ byte[] compressed = new byte[maxCompressedLength];
|
||||
+ int compressedLength = this.compressor.compress(chunkData, 0, chunkData.length, compressed, 0, maxCompressedLength);
|
||||
+ byte[] finalCompressed = new byte[compressedLength];
|
||||
+ System.arraycopy(compressed, 0, finalCompressed, 0, compressedLength);
|
||||
+
|
||||
+ // TODO: Optimization - return the requested chunk immediately to save on one LZ4 decompression
|
||||
+ this.buffer[chunkIndex] = finalCompressed;
|
||||
+ this.bufferUncompressedSize[chunkIndex] = chunkData.length;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (IOException ex) {
|
||||
+ throw new RuntimeException("Region file corrupted: " + regionFile + " bucket: " + idx);
|
||||
+ // TODO: Make sure the server crashes instead of corrupting the world
|
||||
+ }
|
||||
+ bucketBuffers[idx] = null;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean regionFileOpen = false;
|
||||
+
|
||||
+ private synchronized void openRegionFile() {
|
||||
+ if (regionFileOpen) return;
|
||||
+ regionFileOpen = true;
|
||||
+
|
||||
+ File regionFile = new File(this.regionFile.toString());
|
||||
+
|
||||
+ if(!regionFile.canRead()) {
|
||||
+ this.bindThread.start();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ byte[] fileContent = Files.readAllBytes(this.regionFile);
|
||||
+ ByteBuffer buffer = ByteBuffer.wrap(fileContent);
|
||||
+
|
||||
+ long superBlock = buffer.getLong();
|
||||
+ if (superBlock != SUPERBLOCK)
|
||||
+ throw new RuntimeException("Invalid superblock: " + superBlock + " file " + this.regionFile);
|
||||
+
|
||||
+ byte version = buffer.get();
|
||||
+ if (version == 1 || version == 2) {
|
||||
+ parseLinearV1(buffer);
|
||||
+ } else if (version == 3) {
|
||||
+ parseLinearV2(buffer);
|
||||
+ } else {
|
||||
+ throw new RuntimeException("Invalid version: " + version + " file " + this.regionFile);
|
||||
+ }
|
||||
+
|
||||
+ this.bindThread.start();
|
||||
+ } catch (IOException e) {
|
||||
+ throw new RuntimeException("Failed to open region file " + this.regionFile, e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void parseLinearV1(ByteBuffer buffer) throws IOException {
|
||||
+ final int HEADER_SIZE = 32;
|
||||
+ final int FOOTER_SIZE = 8;
|
||||
+
|
||||
+ // Skip newestTimestamp (Long) + Compression level (Byte) + Chunk count (Short): Unused.
|
||||
+ buffer.position(buffer.position() + 11);
|
||||
+
|
||||
+ int dataCount = buffer.getInt();
|
||||
+ long fileLength = this.regionFile.toFile().length();
|
||||
+ if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE) {
|
||||
+ throw new IOException("Invalid file length: " + this.regionFile + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE));
|
||||
+ }
|
||||
+
|
||||
+ buffer.position(buffer.position() + 8); // Skip data hash (Long): Unused.
|
||||
+
|
||||
+ byte[] rawCompressed = new byte[dataCount];
|
||||
+ buffer.get(rawCompressed);
|
||||
+
|
||||
+ ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(rawCompressed);
|
||||
+ ZstdInputStream zstdInputStream = new ZstdInputStream(byteArrayInputStream);
|
||||
+ ByteBuffer decompressedBuffer = ByteBuffer.wrap(zstdInputStream.readAllBytes());
|
||||
+
|
||||
+ int[] starts = new int[1024];
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ starts[i] = decompressedBuffer.getInt();
|
||||
+ decompressedBuffer.getInt(); // Skip timestamps (Int): Unused.
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ if (starts[i] > 0) {
|
||||
+ int size = starts[i];
|
||||
+ byte[] chunkData = new byte[size];
|
||||
+ decompressedBuffer.get(chunkData);
|
||||
+
|
||||
+ int maxCompressedLength = this.compressor.maxCompressedLength(size);
|
||||
+ byte[] compressed = new byte[maxCompressedLength];
|
||||
+ int compressedLength = this.compressor.compress(chunkData, 0, size, compressed, 0, maxCompressedLength);
|
||||
+ byte[] finalCompressed = new byte[compressedLength];
|
||||
+ System.arraycopy(compressed, 0, finalCompressed, 0, compressedLength);
|
||||
+
|
||||
+ this.buffer[i] = finalCompressed;
|
||||
+ this.bufferUncompressedSize[i] = size;
|
||||
+ this.chunkTimestamps[i] = getTimestamp(); // Use current timestamp as we don't have the original
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void parseLinearV2(ByteBuffer buffer) throws IOException {
|
||||
+ buffer.getLong(); // Skip newestTimestamp (Long)
|
||||
+ gridSize = buffer.get();
|
||||
+ if (gridSize != 1 && gridSize != 2 && gridSize != 4 && gridSize != 8 && gridSize != 16 && gridSize != 32)
|
||||
+ throw new RuntimeException("Invalid grid size: " + gridSize + " file " + this.regionFile);
|
||||
+ bucketSize = 32 / gridSize;
|
||||
+
|
||||
+ buffer.getInt(); // Skip region_x (Int)
|
||||
+ buffer.getInt(); // Skip region_z (Int)
|
||||
+
|
||||
+ boolean[] chunkExistenceBitmap = deserializeExistenceBitmap(buffer);
|
||||
+
|
||||
+ while (true) {
|
||||
+ byte featureNameLength = buffer.get();
|
||||
+ if (featureNameLength == 0) break;
|
||||
+ byte[] featureNameBytes = new byte[featureNameLength];
|
||||
+ buffer.get(featureNameBytes);
|
||||
+ String featureName = new String(featureNameBytes);
|
||||
+ int featureValue = buffer.getInt();
|
||||
+ // System.out.println("NBT Feature: " + featureName + " = " + featureValue);
|
||||
+ }
|
||||
+
|
||||
+ int[] bucketSizes = new int[gridSize * gridSize];
|
||||
+ byte[] bucketCompressionLevels = new byte[gridSize * gridSize];
|
||||
+ long[] bucketHashes = new long[gridSize * gridSize];
|
||||
+ for (int i = 0; i < gridSize * gridSize; i++) {
|
||||
+ bucketSizes[i] = buffer.getInt();
|
||||
+ bucketCompressionLevels[i] = buffer.get();
|
||||
+ bucketHashes[i] = buffer.getLong();
|
||||
+ }
|
||||
+
|
||||
+ bucketBuffers = new byte[gridSize * gridSize][];
|
||||
+ for (int i = 0; i < gridSize * gridSize; i++) {
|
||||
+ if (bucketSizes[i] > 0) {
|
||||
+ bucketBuffers[i] = new byte[bucketSizes[i]];
|
||||
+ buffer.get(bucketBuffers[i]);
|
||||
+ long rawHash = LongHashFunction.xx().hashBytes(bucketBuffers[i]);
|
||||
+ if (rawHash != bucketHashes[i]) throw new IOException("Region file hash incorrect " + this.regionFile);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ long footerSuperBlock = buffer.getLong();
|
||||
+ if (footerSuperBlock != SUPERBLOCK)
|
||||
+ throw new IOException("Footer superblock invalid " + this.regionFile);
|
||||
+ }
|
||||
+
|
||||
+ public LinearRegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync, int compressionLevel) throws IOException {
|
||||
+ this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync, compressionLevel);
|
||||
+ }
|
||||
+
|
||||
+ public LinearRegionFile(RegionStorageInfo storageKey, Path path, Path directory, RegionFileVersion compressionFormat, boolean dsync, int compressionLevel) throws IOException {
|
||||
+ Runnable flushCheck = () -> {
|
||||
+ while (!close) {
|
||||
+ synchronized (saveLock) {
|
||||
+ if (markedToSave && activeSaveThreads < SAVE_THREAD_MAX_COUNT) {
|
||||
+ activeSaveThreads++;
|
||||
+ Runnable flushOperation = () -> {
|
||||
+ try {
|
||||
+ flush();
|
||||
+ } catch (IOException ex) {
|
||||
+ LOGGER.error("Region file {} flush failed", this.regionFile.toAbsolutePath(), ex);
|
||||
+ } finally {
|
||||
+ synchronized (saveLock) {
|
||||
+ activeSaveThreads--;
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ Thread saveThread = USE_VIRTUAL_THREAD ?
|
||||
+ Thread.ofVirtual().name("Linear IO - " + LinearRegionFile.this.hashCode()).unstarted(flushOperation) :
|
||||
+ Thread.ofPlatform().name("Linear IO - " + LinearRegionFile.this.hashCode()).unstarted(flushOperation);
|
||||
+ saveThread.setPriority(Thread.NORM_PRIORITY - 3);
|
||||
+ saveThread.start();
|
||||
+ }
|
||||
+ }
|
||||
+ LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(SAVE_DELAY_MS));
|
||||
+ }
|
||||
+ };
|
||||
+ this.bindThread = USE_VIRTUAL_THREAD ? Thread.ofVirtual().unstarted(flushCheck) : Thread.ofPlatform().unstarted(flushCheck);
|
||||
+ this.bindThread.setName("Linear IO Schedule - " + this.hashCode());
|
||||
+ this.regionFile = path;
|
||||
+ this.compressionLevel = compressionLevel;
|
||||
+
|
||||
+ this.compressor = LZ4Factory.fastestInstance().fastCompressor();
|
||||
+ this.decompressor = LZ4Factory.fastestInstance().fastDecompressor();
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void markToSave() {
|
||||
+ synchronized(markedToSaveLock) {
|
||||
+ markedToSave = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private synchronized boolean isMarkedToSave() {
|
||||
+ synchronized(markedToSaveLock) {
|
||||
+ if(markedToSave) {
|
||||
+ markedToSave = false;
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static int SAVE_THREAD_MAX_COUNT = 6;
|
||||
+ public static int SAVE_DELAY_MS = 100;
|
||||
+ public static boolean USE_VIRTUAL_THREAD = true;
|
||||
+ private static final Object saveLock = new Object();
|
||||
+ private static int activeSaveThreads = 0;
|
||||
+
|
||||
+ /*public void run() {
|
||||
+ while (!close) {
|
||||
+ synchronized (saveLock) {
|
||||
+ if (markedToSave && activeSaveThreads < SAVE_THREAD_MAX_COUNT) {
|
||||
+ activeSaveThreads++;
|
||||
+ Thread saveThread = new Thread(() -> {
|
||||
+ try {
|
||||
+ flush();
|
||||
+ } catch (IOException ex) {
|
||||
+ LOGGER.error("Region file " + this.regionFile.toAbsolutePath() + " flush failed", ex);
|
||||
+ } finally {
|
||||
+ synchronized (saveLock) {
|
||||
+ activeSaveThreads--;
|
||||
+ }
|
||||
+ }
|
||||
+ }, "RegionFileFlush");
|
||||
+ saveThread.setPriority(Thread.NORM_PRIORITY - 3);
|
||||
+ saveThread.start();
|
||||
+ }
|
||||
+ }
|
||||
+ LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(SAVE_DELAY_MS));
|
||||
+ }
|
||||
+ }*/
|
||||
+
|
||||
+ public synchronized boolean doesChunkExist(ChunkPos pos) throws Exception {
|
||||
+ openRegionFile();
|
||||
+ throw new Exception("doesChunkExist is a stub");
|
||||
+ }
|
||||
+
|
||||
+ public synchronized void flush() throws IOException {
|
||||
+ if(!isMarkedToSave()) return;
|
||||
+
|
||||
+ openRegionFile();
|
||||
+
|
||||
+ long timestamp = getTimestamp();
|
||||
+
|
||||
+long writeStart = System.nanoTime();
|
||||
+ File tempFile = new File(regionFile.toString() + ".tmp");
|
||||
+ FileOutputStream fileStream = new FileOutputStream(tempFile);
|
||||
+ DataOutputStream dataStream = new DataOutputStream(fileStream);
|
||||
+
|
||||
+ dataStream.writeLong(SUPERBLOCK);
|
||||
+ dataStream.writeByte(VERSION);
|
||||
+ dataStream.writeLong(timestamp);
|
||||
+ dataStream.writeByte(gridSize);
|
||||
+
|
||||
+ String fileName = regionFile.getFileName().toString();
|
||||
+ String[] parts = fileName.split("\\.");
|
||||
+ int regionX = 0;
|
||||
+ int regionZ = 0;
|
||||
+ try {
|
||||
+ if (parts.length >= 4) {
|
||||
+ regionX = Integer.parseInt(parts[1]);
|
||||
+ regionZ = Integer.parseInt(parts[2]);
|
||||
+ } else {
|
||||
+ LOGGER.warn("Unexpected file name format: " + fileName);
|
||||
+ }
|
||||
+ } catch (NumberFormatException e) {
|
||||
+ LOGGER.error("Failed to parse region coordinates from file name: " + fileName, e);
|
||||
+ }
|
||||
+
|
||||
+ dataStream.writeInt(regionX);
|
||||
+ dataStream.writeInt(regionZ);
|
||||
+
|
||||
+ boolean[] chunkExistenceBitmap = new boolean[1024];
|
||||
+ for (int i = 0; i < 1024; i++) {
|
||||
+ chunkExistenceBitmap[i] = (this.bufferUncompressedSize[i] > 0);
|
||||
+ }
|
||||
+ writeSerializedExistenceBitmap(dataStream, chunkExistenceBitmap);
|
||||
+
|
||||
+ writeNBTFeatures(dataStream);
|
||||
+
|
||||
+ int bucketMisses = 0;
|
||||
+ byte[][] buckets = new byte[gridSize * gridSize][];
|
||||
+ for (int bx = 0; bx < gridSize; bx++) {
|
||||
+ for (int bz = 0; bz < gridSize; bz++) {
|
||||
+ if (bucketBuffers != null && bucketBuffers[bx * gridSize + bz] != null) {
|
||||
+ buckets[bx * gridSize + bz] = bucketBuffers[bx * gridSize + bz];
|
||||
+ continue;
|
||||
+ }
|
||||
+ bucketMisses++;
|
||||
+
|
||||
+ ByteArrayOutputStream bucketStream = new ByteArrayOutputStream();
|
||||
+ ZstdOutputStream zstdStream = new ZstdOutputStream(bucketStream, this.compressionLevel);
|
||||
+ DataOutputStream bucketDataStream = new DataOutputStream(zstdStream);
|
||||
+
|
||||
+ boolean hasData = false;
|
||||
+ for (int cx = 0; cx < 32 / gridSize; cx++) {
|
||||
+ for (int cz = 0; cz < 32 / gridSize; cz++) {
|
||||
+ int chunkIndex = (bx * 32 / gridSize + cx) + (bz * 32 / gridSize + cz) * 32;
|
||||
+ if (this.bufferUncompressedSize[chunkIndex] > 0) {
|
||||
+ hasData = true;
|
||||
+ byte[] chunkData = new byte[this.bufferUncompressedSize[chunkIndex]];
|
||||
+ this.decompressor.decompress(this.buffer[chunkIndex], 0, chunkData, 0, this.bufferUncompressedSize[chunkIndex]);
|
||||
+ bucketDataStream.writeInt(chunkData.length + 8);
|
||||
+ bucketDataStream.writeLong(this.chunkTimestamps[chunkIndex]);
|
||||
+ bucketDataStream.write(chunkData);
|
||||
+ } else {
|
||||
+ bucketDataStream.writeInt(0);
|
||||
+ bucketDataStream.writeLong(this.chunkTimestamps[chunkIndex]);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ bucketDataStream.close();
|
||||
+
|
||||
+ if (hasData) {
|
||||
+ buckets[bx * gridSize + bz] = bucketStream.toByteArray();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < gridSize * gridSize; i++) {
|
||||
+ dataStream.writeInt(buckets[i] != null ? buckets[i].length : 0);
|
||||
+ dataStream.writeByte(this.compressionLevel);
|
||||
+ long rawHash = 0;
|
||||
+ if (buckets[i] != null) {
|
||||
+ rawHash = LongHashFunction.xx().hashBytes(buckets[i]);
|
||||
+ }
|
||||
+ dataStream.writeLong(rawHash);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < gridSize * gridSize; i++) {
|
||||
+ if (buckets[i] != null) {
|
||||
+ dataStream.write(buckets[i]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dataStream.writeLong(SUPERBLOCK);
|
||||
+
|
||||
+ dataStream.flush();
|
||||
+ fileStream.getFD().sync();
|
||||
+ fileStream.getChannel().force(true); // Ensure atomicity on Btrfs
|
||||
+ dataStream.close();
|
||||
+
|
||||
+ fileStream.close();
|
||||
+ Files.move(tempFile.toPath(), this.regionFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
+//System.out.println("writeStart REGION FILE FLUSH " + (System.nanoTime() - writeStart) + " misses: " + bucketMisses);
|
||||
+ }
|
||||
+
|
||||
+ private void writeNBTFeatures(DataOutputStream dataStream) throws IOException {
|
||||
+ // writeNBTFeature(dataStream, "example", 1);
|
||||
+ dataStream.writeByte(0); // End of NBT features
|
||||
+ }
|
||||
+
|
||||
+ private void writeNBTFeature(DataOutputStream dataStream, String featureName, int featureValue) throws IOException {
|
||||
+ byte[] featureNameBytes = featureName.getBytes();
|
||||
+ dataStream.writeByte(featureNameBytes.length);
|
||||
+ dataStream.write(featureNameBytes);
|
||||
+ dataStream.writeInt(featureValue);
|
||||
+ }
|
||||
+
|
||||
+ public static final int MAX_CHUNK_SIZE = 500 * 1024 * 1024; // Abomination - prevent chunk dupe
|
||||
+
|
||||
+ public synchronized void write(ChunkPos pos, ByteBuffer buffer) {
|
||||
+ openRegionFile();
|
||||
+ openBucket(pos.x, pos.z);
|
||||
+ try {
|
||||
+ byte[] b = toByteArray(new ByteArrayInputStream(buffer.array()));
|
||||
+ int uncompressedSize = b.length;
|
||||
+
|
||||
+ if (uncompressedSize > MAX_CHUNK_SIZE) {
|
||||
+ LOGGER.error("Chunk dupe attempt " + this.regionFile);
|
||||
+ clear(pos);
|
||||
+ } else {
|
||||
+ int maxCompressedLength = this.compressor.maxCompressedLength(b.length);
|
||||
+ byte[] compressed = new byte[maxCompressedLength];
|
||||
+ int compressedLength = this.compressor.compress(b, 0, b.length, compressed, 0, maxCompressedLength);
|
||||
+ b = new byte[compressedLength];
|
||||
+ System.arraycopy(compressed, 0, b, 0, compressedLength);
|
||||
+
|
||||
+ int index = getChunkIndex(pos.x, pos.z);
|
||||
+ this.buffer[index] = b;
|
||||
+ this.chunkTimestamps[index] = getTimestamp();
|
||||
+ this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize;
|
||||
+ }
|
||||
+ } catch (IOException e) {
|
||||
+ LOGGER.error("Chunk write IOException " + e + " " + this.regionFile);
|
||||
+ }
|
||||
+ markToSave();
|
||||
+ }
|
||||
+
|
||||
+ public DataOutputStream getChunkDataOutputStream(ChunkPos pos) {
|
||||
+ openRegionFile();
|
||||
+ openBucket(pos.x, pos.z);
|
||||
+ return new DataOutputStream(new BufferedOutputStream(new LinearRegionFile.ChunkBuffer(pos)));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(CompoundTag data, ChunkPos pos) throws IOException {
|
||||
+ final DataOutputStream out = this.getChunkDataOutputStream(pos);
|
||||
+
|
||||
+ return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData(
|
||||
+ data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.WRITE,
|
||||
+ out, regionFile -> out.close()
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ private class ChunkBuffer extends ByteArrayOutputStream {
|
||||
+
|
||||
+ private final ChunkPos pos;
|
||||
+
|
||||
+ public ChunkBuffer(ChunkPos chunkcoordintpair) {
|
||||
+ super();
|
||||
+ this.pos = chunkcoordintpair;
|
||||
+ }
|
||||
+
|
||||
+ public void close() throws IOException {
|
||||
+ ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count);
|
||||
+ LinearRegionFile.this.write(this.pos, bytebuffer);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private byte[] toByteArray(InputStream in) throws IOException {
|
||||
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
+ byte[] tempBuffer = new byte[4096];
|
||||
+
|
||||
+ int length;
|
||||
+ while ((length = in.read(tempBuffer)) >= 0) {
|
||||
+ out.write(tempBuffer, 0, length);
|
||||
+ }
|
||||
+
|
||||
+ return out.toByteArray();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) {
|
||||
+ openRegionFile();
|
||||
+ openBucket(pos.x, pos.z);
|
||||
+
|
||||
+ if(this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) {
|
||||
+ byte[] content = new byte[bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]];
|
||||
+ this.decompressor.decompress(this.buffer[getChunkIndex(pos.x, pos.z)], 0, content, 0, bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]);
|
||||
+ return new DataInputStream(new ByteArrayInputStream(content));
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ public synchronized void clear(ChunkPos pos) {
|
||||
+ openRegionFile();
|
||||
+ openBucket(pos.x, pos.z);
|
||||
+ int i = getChunkIndex(pos.x, pos.z);
|
||||
+ this.buffer[i] = null;
|
||||
+ this.bufferUncompressedSize[i] = 0;
|
||||
+ this.chunkTimestamps[i] = 0;
|
||||
+ markToSave();
|
||||
+ }
|
||||
+
|
||||
+ public synchronized boolean hasChunk(ChunkPos pos) {
|
||||
+ openRegionFile();
|
||||
+ openBucket(pos.x, pos.z);
|
||||
+ return this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] > 0;
|
||||
+ }
|
||||
+
|
||||
+ public synchronized void close() throws IOException {
|
||||
+ openRegionFile();
|
||||
+ close = true;
|
||||
+ try {
|
||||
+ flush();
|
||||
+ } catch(IOException e) {
|
||||
+ throw new IOException("Region flush IOException " + e + " " + this.regionFile);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static int getChunkIndex(int x, int z) {
|
||||
+ return (x & 31) + ((z & 31) << 5);
|
||||
+ }
|
||||
+
|
||||
+ private static int getTimestamp() {
|
||||
+ return (int) (System.currentTimeMillis() / 1000L);
|
||||
+ }
|
||||
+
|
||||
+ public boolean recalculateHeader() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public void setOversized(int x, int z, boolean something) {}
|
||||
+
|
||||
+ public CompoundTag getOversizedData(int x, int z) throws IOException {
|
||||
+ throw new IOException("getOversizedData is a stub " + this.regionFile);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isOversized(int x, int z) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public Path getPath() {
|
||||
+ return this.regionFile;
|
||||
+ }
|
||||
+
|
||||
+ private boolean[] deserializeExistenceBitmap(ByteBuffer buffer) {
|
||||
+ boolean[] result = new boolean[1024];
|
||||
+ for (int i = 0; i < 128; i++) {
|
||||
+ byte b = buffer.get();
|
||||
+ for (int j = 0; j < 8; j++) {
|
||||
+ result[i * 8 + j] = ((b >> (7 - j)) & 1) == 1;
|
||||
+ }
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ private void writeSerializedExistenceBitmap(DataOutputStream out, boolean[] bitmap) throws IOException {
|
||||
+ for (int i = 0; i < 128; i++) {
|
||||
+ byte b = 0;
|
||||
+ for (int j = 0; j < 8; j++) {
|
||||
+ if (bitmap[i * 8 + j]) {
|
||||
+ b |= (1 << (7 - j));
|
||||
+ }
|
||||
+ }
|
||||
+ out.writeByte(b);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
@@ -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);
|
||||
+ }
|
||||
+}
|
||||
@@ -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) {
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,518 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java
|
||||
@@ -1,0 +_,515 @@
|
||||
+package com.logisticscraft.occlusionculling;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+import java.util.BitSet;
|
||||
+
|
||||
+import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache;
|
||||
+import com.logisticscraft.occlusionculling.cache.OcclusionCache;
|
||||
+import com.logisticscraft.occlusionculling.util.MathUtilities;
|
||||
+import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||
+
|
||||
+public class OcclusionCullingInstance {
|
||||
+
|
||||
+ private static final int ON_MIN_X = 0x01;
|
||||
+ private static final int ON_MAX_X = 0x02;
|
||||
+ private static final int ON_MIN_Y = 0x04;
|
||||
+ private static final int ON_MAX_Y = 0x08;
|
||||
+ private static final int ON_MIN_Z = 0x10;
|
||||
+ private static final int ON_MAX_Z = 0x20;
|
||||
+
|
||||
+ private final int reach;
|
||||
+ private final double aabbExpansion;
|
||||
+ private final DataProvider provider;
|
||||
+ private final OcclusionCache cache;
|
||||
+
|
||||
+ // Reused allocated data structures
|
||||
+ private final BitSet skipList = new BitSet(); // Grows bigger in case some mod introduces giant hitboxes
|
||||
+ private final Vec3d[] targetPoints = new Vec3d[15];
|
||||
+ private final Vec3d targetPos = new Vec3d(0, 0, 0);
|
||||
+ private final int[] cameraPos = new int[3];
|
||||
+ private final boolean[] dotselectors = new boolean[14];
|
||||
+ private boolean allowRayChecks = false;
|
||||
+ private final int[] lastHitBlock = new int[3];
|
||||
+ private boolean allowWallClipping = false;
|
||||
+
|
||||
+
|
||||
+ public OcclusionCullingInstance(int maxDistance, DataProvider provider) {
|
||||
+ this(maxDistance, provider, new ArrayOcclusionCache(maxDistance), 0.5);
|
||||
+ }
|
||||
+
|
||||
+ public OcclusionCullingInstance(int maxDistance, DataProvider provider, OcclusionCache cache, double aabbExpansion) {
|
||||
+ this.reach = maxDistance;
|
||||
+ this.provider = provider;
|
||||
+ this.cache = cache;
|
||||
+ this.aabbExpansion = aabbExpansion;
|
||||
+ for(int i = 0; i < targetPoints.length; i++) {
|
||||
+ targetPoints[i] = new Vec3d(0, 0, 0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean isAABBVisible(Vec3d aabbMin, Vec3d aabbMax, Vec3d viewerPosition) {
|
||||
+ try {
|
||||
+ int maxX = MathUtilities.floor(aabbMax.x
|
||||
+ + aabbExpansion);
|
||||
+ int maxY = MathUtilities.floor(aabbMax.y
|
||||
+ + aabbExpansion);
|
||||
+ int maxZ = MathUtilities.floor(aabbMax.z
|
||||
+ + aabbExpansion);
|
||||
+ int minX = MathUtilities.floor(aabbMin.x
|
||||
+ - aabbExpansion);
|
||||
+ int minY = MathUtilities.floor(aabbMin.y
|
||||
+ - aabbExpansion);
|
||||
+ int minZ = MathUtilities.floor(aabbMin.z
|
||||
+ - aabbExpansion);
|
||||
+
|
||||
+ cameraPos[0] = MathUtilities.floor(viewerPosition.x);
|
||||
+ cameraPos[1] = MathUtilities.floor(viewerPosition.y);
|
||||
+ cameraPos[2] = MathUtilities.floor(viewerPosition.z);
|
||||
+
|
||||
+ Relative relX = Relative.from(minX, maxX, cameraPos[0]);
|
||||
+ Relative relY = Relative.from(minY, maxY, cameraPos[1]);
|
||||
+ Relative relZ = Relative.from(minZ, maxZ, cameraPos[2]);
|
||||
+
|
||||
+ if(relX == Relative.INSIDE && relY == Relative.INSIDE && relZ == Relative.INSIDE) {
|
||||
+ return true; // We are inside of the AABB, don't cull
|
||||
+ }
|
||||
+
|
||||
+ skipList.clear();
|
||||
+
|
||||
+ // Just check the cache first
|
||||
+ int id = 0;
|
||||
+ for (int x = minX; x <= maxX; x++) {
|
||||
+ for (int y = minY; y <= maxY; y++) {
|
||||
+ for (int z = minZ; z <= maxZ; z++) {
|
||||
+ int cachedValue = getCacheValue(x, y, z);
|
||||
+
|
||||
+ if (cachedValue == 1) {
|
||||
+ // non-occluding
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (cachedValue != 0) {
|
||||
+ // was checked and it wasn't visible
|
||||
+ skipList.set(id);
|
||||
+ }
|
||||
+ id++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // only after the first hit wall the cache becomes valid.
|
||||
+ allowRayChecks = false;
|
||||
+
|
||||
+ // since the cache wasn't helpfull
|
||||
+ id = 0;
|
||||
+ for (int x = minX; x <= maxX; x++) {
|
||||
+ byte visibleOnFaceX = 0;
|
||||
+ byte faceEdgeDataX = 0;
|
||||
+ faceEdgeDataX |= (x == minX) ? ON_MIN_X : 0;
|
||||
+ faceEdgeDataX |= (x == maxX) ? ON_MAX_X : 0;
|
||||
+ visibleOnFaceX |= (x == minX && relX == Relative.POSITIVE) ? ON_MIN_X : 0;
|
||||
+ visibleOnFaceX |= (x == maxX && relX == Relative.NEGATIVE) ? ON_MAX_X : 0;
|
||||
+ for (int y = minY; y <= maxY; y++) {
|
||||
+ byte faceEdgeDataY = faceEdgeDataX;
|
||||
+ byte visibleOnFaceY = visibleOnFaceX;
|
||||
+ faceEdgeDataY |= (y == minY) ? ON_MIN_Y : 0;
|
||||
+ faceEdgeDataY |= (y == maxY) ? ON_MAX_Y : 0;
|
||||
+ visibleOnFaceY |= (y == minY && relY == Relative.POSITIVE) ? ON_MIN_Y : 0;
|
||||
+ visibleOnFaceY |= (y == maxY && relY == Relative.NEGATIVE) ? ON_MAX_Y : 0;
|
||||
+ for (int z = minZ; z <= maxZ; z++) {
|
||||
+ byte faceEdgeData = faceEdgeDataY;
|
||||
+ byte visibleOnFace = visibleOnFaceY;
|
||||
+ faceEdgeData |= (z == minZ) ? ON_MIN_Z : 0;
|
||||
+ faceEdgeData |= (z == maxZ) ? ON_MAX_Z : 0;
|
||||
+ visibleOnFace |= (z == minZ && relZ == Relative.POSITIVE) ? ON_MIN_Z : 0;
|
||||
+ visibleOnFace |= (z == maxZ && relZ == Relative.NEGATIVE) ? ON_MAX_Z : 0;
|
||||
+ if(skipList.get(id)) { // was checked and it wasn't visible
|
||||
+ id++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (visibleOnFace != 0) {
|
||||
+ targetPos.set(x, y, z);
|
||||
+ if (isVoxelVisible(viewerPosition, targetPos, faceEdgeData, visibleOnFace)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ id++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ } catch (Throwable t) {
|
||||
+ // Failsafe
|
||||
+ t.printStackTrace();
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param viewerPosition
|
||||
+ * @param position
|
||||
+ * @param faceData contains rather this Block is on the outside for a given face
|
||||
+ * @param visibleOnFace contains rather a face should be concidered
|
||||
+ * @return
|
||||
+ */
|
||||
+ private boolean isVoxelVisible(Vec3d viewerPosition, Vec3d position, byte faceData, byte visibleOnFace) {
|
||||
+ int targetSize = 0;
|
||||
+ Arrays.fill(dotselectors, false);
|
||||
+ if((visibleOnFace & ON_MIN_X) == ON_MIN_X){
|
||||
+ dotselectors[0] = true;
|
||||
+ if((faceData & ~ON_MIN_X) != 0) {
|
||||
+ dotselectors[1] = true;
|
||||
+ dotselectors[4] = true;
|
||||
+ dotselectors[5] = true;
|
||||
+ }
|
||||
+ dotselectors[8] = true;
|
||||
+ }
|
||||
+ if((visibleOnFace & ON_MIN_Y) == ON_MIN_Y){
|
||||
+ dotselectors[0] = true;
|
||||
+ if((faceData & ~ON_MIN_Y) != 0) {
|
||||
+ dotselectors[3] = true;
|
||||
+ dotselectors[4] = true;
|
||||
+ dotselectors[7] = true;
|
||||
+ }
|
||||
+ dotselectors[9] = true;
|
||||
+ }
|
||||
+ if((visibleOnFace & ON_MIN_Z) == ON_MIN_Z){
|
||||
+ dotselectors[0] = true;
|
||||
+ if((faceData & ~ON_MIN_Z) != 0) {
|
||||
+ dotselectors[1] = true;
|
||||
+ dotselectors[4] = true;
|
||||
+ dotselectors[5] = true;
|
||||
+ }
|
||||
+ dotselectors[10] = true;
|
||||
+ }
|
||||
+ if((visibleOnFace & ON_MAX_X) == ON_MAX_X){
|
||||
+ dotselectors[4] = true;
|
||||
+ if((faceData & ~ON_MAX_X) != 0) {
|
||||
+ dotselectors[5] = true;
|
||||
+ dotselectors[6] = true;
|
||||
+ dotselectors[7] = true;
|
||||
+ }
|
||||
+ dotselectors[11] = true;
|
||||
+ }
|
||||
+ if((visibleOnFace & ON_MAX_Y) == ON_MAX_Y){
|
||||
+ dotselectors[1] = true;
|
||||
+ if((faceData & ~ON_MAX_Y) != 0) {
|
||||
+ dotselectors[2] = true;
|
||||
+ dotselectors[5] = true;
|
||||
+ dotselectors[6] = true;
|
||||
+ }
|
||||
+ dotselectors[12] = true;
|
||||
+ }
|
||||
+ if((visibleOnFace & ON_MAX_Z) == ON_MAX_Z){
|
||||
+ dotselectors[2] = true;
|
||||
+ if((faceData & ~ON_MAX_Z) != 0) {
|
||||
+ dotselectors[3] = true;
|
||||
+ dotselectors[6] = true;
|
||||
+ dotselectors[7] = true;
|
||||
+ }
|
||||
+ dotselectors[13] = true;
|
||||
+ }
|
||||
+
|
||||
+ if (dotselectors[0])targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.05);
|
||||
+ if (dotselectors[1])targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.05);
|
||||
+ if (dotselectors[2])targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.95);
|
||||
+ if (dotselectors[3])targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.95);
|
||||
+ if (dotselectors[4])targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.05);
|
||||
+ if (dotselectors[5])targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.05);
|
||||
+ if (dotselectors[6])targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.95);
|
||||
+ if (dotselectors[7])targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.95);
|
||||
+ // middle points
|
||||
+ if (dotselectors[8])targetPoints[targetSize++].setAdd(position, 0.05, 0.5, 0.5);
|
||||
+ if (dotselectors[9])targetPoints[targetSize++].setAdd(position, 0.5, 0.05, 0.5);
|
||||
+ if (dotselectors[10])targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.05);
|
||||
+ if (dotselectors[11])targetPoints[targetSize++].setAdd(position, 0.95, 0.5, 0.5);
|
||||
+ if (dotselectors[12])targetPoints[targetSize++].setAdd(position, 0.5, 0.95, 0.5);
|
||||
+ if (dotselectors[13])targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.95);
|
||||
+
|
||||
+ return isVisible(viewerPosition, targetPoints, targetSize);
|
||||
+ }
|
||||
+
|
||||
+ private boolean rayIntersection(int[] b, Vec3d rayOrigin, Vec3d rayDir) {
|
||||
+ Vec3d rInv = new Vec3d(1, 1, 1).div(rayDir);
|
||||
+
|
||||
+ double t1 = (b[0] - rayOrigin.x) * rInv.x;
|
||||
+ double t2 = (b[0] + 1 - rayOrigin.x) * rInv.x;
|
||||
+ double t3 = (b[1] - rayOrigin.y) * rInv.y;
|
||||
+ double t4 = (b[1] + 1 - rayOrigin.y) * rInv.y;
|
||||
+ double t5 = (b[2] - rayOrigin.z) * rInv.z;
|
||||
+ double t6 = (b[2] + 1 - rayOrigin.z) * rInv.z;
|
||||
+
|
||||
+ double tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6));
|
||||
+ double tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6));
|
||||
+
|
||||
+ // if tmax > 0, ray (line) is intersecting AABB, but the whole AABB is behind us
|
||||
+ if (tmax > 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // if tmin > tmax, ray doesn't intersect AABB
|
||||
+ if (tmin > tmax) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * returns the grid cells that intersect with this Vec3d<br>
|
||||
+ * <a href=
|
||||
+ * "http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html">http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html</a>
|
||||
+ * <p>
|
||||
+ * Caching assumes that all Vec3d's are inside the same block
|
||||
+ */
|
||||
+ private boolean isVisible(Vec3d start, Vec3d[] targets, int size) {
|
||||
+ // start cell coordinate
|
||||
+ int x = cameraPos[0];
|
||||
+ int y = cameraPos[1];
|
||||
+ int z = cameraPos[2];
|
||||
+
|
||||
+ for (int v = 0; v < size; v++) {
|
||||
+ // ray-casting target
|
||||
+ Vec3d target = targets[v];
|
||||
+
|
||||
+ double relativeX = start.x - target.getX();
|
||||
+ double relativeY = start.y - target.getY();
|
||||
+ double relativeZ = start.z - target.getZ();
|
||||
+
|
||||
+ if(allowRayChecks && rayIntersection(lastHitBlock, start, new Vec3d(relativeX, relativeY, relativeZ).normalize())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // horizontal and vertical cell amount spanned
|
||||
+ double dimensionX = Math.abs(relativeX);
|
||||
+ double dimensionY = Math.abs(relativeY);
|
||||
+ double dimensionZ = Math.abs(relativeZ);
|
||||
+
|
||||
+ // distance between horizontal intersection points with cell border as a
|
||||
+ // fraction of the total Vec3d length
|
||||
+ double dimFracX = 1f / dimensionX;
|
||||
+ // distance between vertical intersection points with cell border as a fraction
|
||||
+ // of the total Vec3d length
|
||||
+ double dimFracY = 1f / dimensionY;
|
||||
+ double dimFracZ = 1f / dimensionZ;
|
||||
+
|
||||
+ // total amount of intersected cells
|
||||
+ int intersectCount = 1;
|
||||
+
|
||||
+ // 1, 0 or -1
|
||||
+ // determines the direction of the next cell (horizontally / vertically)
|
||||
+ int x_inc, y_inc, z_inc;
|
||||
+
|
||||
+ // the distance to the next horizontal / vertical intersection point with a cell
|
||||
+ // border as a fraction of the total Vec3d length
|
||||
+ double t_next_y, t_next_x, t_next_z;
|
||||
+
|
||||
+ if (dimensionX == 0f) {
|
||||
+ x_inc = 0;
|
||||
+ t_next_x = dimFracX; // don't increment horizontally because the Vec3d is perfectly vertical
|
||||
+ } else if (target.x > start.x) {
|
||||
+ x_inc = 1; // target point is horizontally greater than starting point so increment every
|
||||
+ // step by 1
|
||||
+ intersectCount += MathUtilities.floor(target.x) - x; // increment total amount of intersecting cells
|
||||
+ t_next_x = (float) ((x + 1 - start.x) * dimFracX); // calculate the next horizontal
|
||||
+ // intersection
|
||||
+ // point based on the position inside
|
||||
+ // the first cell
|
||||
+ } else {
|
||||
+ x_inc = -1; // target point is horizontally smaller than starting point so reduce every step
|
||||
+ // by 1
|
||||
+ intersectCount += x - MathUtilities.floor(target.x); // increment total amount of intersecting cells
|
||||
+ t_next_x = (float) ((start.x - x)
|
||||
+ * dimFracX); // calculate the next horizontal
|
||||
+ // intersection point
|
||||
+ // based on the position inside
|
||||
+ // the first cell
|
||||
+ }
|
||||
+
|
||||
+ if (dimensionY == 0f) {
|
||||
+ y_inc = 0;
|
||||
+ t_next_y = dimFracY; // don't increment vertically because the Vec3d is perfectly horizontal
|
||||
+ } else if (target.y > start.y) {
|
||||
+ y_inc = 1; // target point is vertically greater than starting point so increment every
|
||||
+ // step by 1
|
||||
+ intersectCount += MathUtilities.floor(target.y) - y; // increment total amount of intersecting cells
|
||||
+ t_next_y = (float) ((y + 1 - start.y)
|
||||
+ * dimFracY); // calculate the next vertical
|
||||
+ // intersection
|
||||
+ // point based on the position inside
|
||||
+ // the first cell
|
||||
+ } else {
|
||||
+ y_inc = -1; // target point is vertically smaller than starting point so reduce every step
|
||||
+ // by 1
|
||||
+ intersectCount += y - MathUtilities.floor(target.y); // increment total amount of intersecting cells
|
||||
+ t_next_y = (float) ((start.y - y)
|
||||
+ * dimFracY); // calculate the next vertical intersection
|
||||
+ // point
|
||||
+ // based on the position inside
|
||||
+ // the first cell
|
||||
+ }
|
||||
+
|
||||
+ if (dimensionZ == 0f) {
|
||||
+ z_inc = 0;
|
||||
+ t_next_z = dimFracZ; // don't increment vertically because the Vec3d is perfectly horizontal
|
||||
+ } else if (target.z > start.z) {
|
||||
+ z_inc = 1; // target point is vertically greater than starting point so increment every
|
||||
+ // step by 1
|
||||
+ intersectCount += MathUtilities.floor(target.z) - z; // increment total amount of intersecting cells
|
||||
+ t_next_z = (float) ((z + 1 - start.z)
|
||||
+ * dimFracZ); // calculate the next vertical
|
||||
+ // intersection
|
||||
+ // point based on the position inside
|
||||
+ // the first cell
|
||||
+ } else {
|
||||
+ z_inc = -1; // target point is vertically smaller than starting point so reduce every step
|
||||
+ // by 1
|
||||
+ intersectCount += z - MathUtilities.floor(target.z); // increment total amount of intersecting cells
|
||||
+ t_next_z = (float) ((start.z - z)
|
||||
+ * dimFracZ); // calculate the next vertical intersection
|
||||
+ // point
|
||||
+ // based on the position inside
|
||||
+ // the first cell
|
||||
+ }
|
||||
+
|
||||
+ boolean finished = stepRay(start, x, y, z,
|
||||
+ dimFracX, dimFracY, dimFracZ, intersectCount, x_inc, y_inc,
|
||||
+ z_inc, t_next_y, t_next_x, t_next_z);
|
||||
+ provider.cleanup();
|
||||
+ if (finished) {
|
||||
+ cacheResult(targets[0], true);
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ allowRayChecks = true;
|
||||
+ }
|
||||
+ }
|
||||
+ cacheResult(targets[0], false);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private boolean stepRay(Vec3d start, int currentX, int currentY,
|
||||
+ int currentZ, double distInX, double distInY,
|
||||
+ double distInZ, int n, int x_inc, int y_inc,
|
||||
+ int z_inc, double t_next_y, double t_next_x,
|
||||
+ double t_next_z) {
|
||||
+ allowWallClipping = true; // initially allow rays to go through walls till they are on the outside
|
||||
+ // iterate through all intersecting cells (n times)
|
||||
+ for (; n > 1; n--) { // n-1 times because we don't want to check the last block
|
||||
+ // towards - where from
|
||||
+
|
||||
+
|
||||
+ // get cached value, 0 means uncached (default)
|
||||
+ int cVal = getCacheValue(currentX, currentY, currentZ);
|
||||
+
|
||||
+ if (cVal == 2 && !allowWallClipping) {
|
||||
+ // block cached as occluding, stop ray
|
||||
+ lastHitBlock[0] = currentX;
|
||||
+ lastHitBlock[1] = currentY;
|
||||
+ lastHitBlock[2] = currentZ;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (cVal == 0) {
|
||||
+ // save current cell
|
||||
+ int chunkX = currentX >> 4;
|
||||
+ int chunkZ = currentZ >> 4;
|
||||
+
|
||||
+ if (!provider.prepareChunk(chunkX, chunkZ)) { // Chunk not ready
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (provider.isOpaqueFullCube(currentX, currentY, currentZ)) {
|
||||
+ if (!allowWallClipping) {
|
||||
+ cache.setLastHidden();
|
||||
+ lastHitBlock[0] = currentX;
|
||||
+ lastHitBlock[1] = currentY;
|
||||
+ lastHitBlock[2] = currentZ;
|
||||
+ return false;
|
||||
+ }
|
||||
+ } else {
|
||||
+ // outside of wall, now clipping is not allowed
|
||||
+ allowWallClipping = false;
|
||||
+ cache.setLastVisible();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(cVal == 1) {
|
||||
+ // outside of wall, now clipping is not allowed
|
||||
+ allowWallClipping = false;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (t_next_y < t_next_x && t_next_y < t_next_z) { // next cell is upwards/downwards because the distance to
|
||||
+ // the next vertical
|
||||
+ // intersection point is smaller than to the next horizontal intersection point
|
||||
+ currentY += y_inc; // move up/down
|
||||
+ t_next_y += distInY; // update next vertical intersection point
|
||||
+ } else if (t_next_x < t_next_y && t_next_x < t_next_z) { // next cell is right/left
|
||||
+ currentX += x_inc; // move right/left
|
||||
+ t_next_x += distInX; // update next horizontal intersection point
|
||||
+ } else {
|
||||
+ currentZ += z_inc; // move right/left
|
||||
+ t_next_z += distInZ; // update next horizontal intersection point
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ // -1 = invalid location, 0 = not checked yet, 1 = visible, 2 = occluding
|
||||
+ private int getCacheValue(int x, int y, int z) {
|
||||
+ x -= cameraPos[0];
|
||||
+ y -= cameraPos[1];
|
||||
+ z -= cameraPos[2];
|
||||
+ if (Math.abs(x) > reach - 2 || Math.abs(y) > reach - 2
|
||||
+ || Math.abs(z) > reach - 2) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ // check if target is already known
|
||||
+ return cache.getState(x + reach, y + reach, z + reach);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ private void cacheResult(int x, int y, int z, boolean result) {
|
||||
+ int cx = x - cameraPos[0] + reach;
|
||||
+ int cy = y - cameraPos[1] + reach;
|
||||
+ int cz = z - cameraPos[2] + reach;
|
||||
+ if (result) {
|
||||
+ cache.setVisible(cx, cy, cz);
|
||||
+ } else {
|
||||
+ cache.setHidden(cx, cy, cz);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void cacheResult(Vec3d vector, boolean result) {
|
||||
+ int cx = MathUtilities.floor(vector.x) - cameraPos[0] + reach;
|
||||
+ int cy = MathUtilities.floor(vector.y) - cameraPos[1] + reach;
|
||||
+ int cz = MathUtilities.floor(vector.z) - cameraPos[2] + reach;
|
||||
+ if (result) {
|
||||
+ cache.setVisible(cx, cy, cz);
|
||||
+ } else {
|
||||
+ cache.setHidden(cx, cy, cz);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void resetCache() {
|
||||
+ this.cache.resetCache();
|
||||
+ }
|
||||
+
|
||||
+ private enum Relative {
|
||||
+ INSIDE, POSITIVE, NEGATIVE;
|
||||
+
|
||||
+ public static Relative from(int min, int max, int pos) {
|
||||
+ if (max > pos && min > pos) {
|
||||
+ return POSITIVE;
|
||||
+ } else if (min < pos && max < pos) {
|
||||
+ return NEGATIVE;
|
||||
+ }
|
||||
+ return INSIDE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -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;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -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();
|
||||
+
|
||||
+}
|
||||
@@ -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;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -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 + ")";
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,144 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java
|
||||
@@ -1,0 +_,141 @@
|
||||
+package dev.kaiijumc.kaiiju;
|
||||
+
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.util.Map;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.logging.Level;
|
||||
+
|
||||
+import com.google.common.base.Throwables;
|
||||
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
+import io.github.classgraph.ClassGraph;
|
||||
+import io.github.classgraph.ClassInfo;
|
||||
+import io.github.classgraph.ScanResult;
|
||||
+import org.slf4j.Logger;
|
||||
+
|
||||
+import com.mojang.logging.LogUtils;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.configuration.InvalidConfigurationException;
|
||||
+import org.bukkit.configuration.file.YamlConfiguration;
|
||||
+
|
||||
+@SuppressWarnings("unused")
|
||||
+public class KaiijuEntityLimits {
|
||||
+ private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ private static final File CONFIG_FOLDER = new File("luminol_config");
|
||||
+
|
||||
+ protected static final String HEADER =
|
||||
+ "Per region entity limits for Kaiiju.\n"
|
||||
+ + "If there are more of particular entity type in a region than limit, entity ticking will be throttled.\n"
|
||||
+ + "Example: for Wither limit 100 & 300 Withers in a region -> 100 Withers tick every tick & every Wither ticks every 3 ticks.\n"
|
||||
+ + "Available entities: GlowSquid, Ambient, Bat, Animal, Bee, Cat, Chicken, Cod, Cow, Dolphin, Fish, FishSchool, Fox, Golem, IronGolem, "
|
||||
+ + "MushroomCow, Ocelot, Panda, Parrot, Perchable, Pig, PolarBear, PufferFish, Rabbit, Salmon, Sheep, Snowman, Squid, TropicalFish, Turtle, "
|
||||
+ + "WaterAnimal, Wolf, Allay, Axolotl, Camel, Frog, Tadpole, Goat, Horse, HorseAbstract, HorseChestedAbstract, HorseDonkey, HorseMule, "
|
||||
+ + "HorseSkeleton, HorseZombie, Llama, LlamaTrader, Sniffer, EnderCrystal, EnderDragon, Wither, ArmorStand, Hanging, ItemFrame, Leash, "
|
||||
+ + "Painting, GlowItemFrame, FallingBlock, Item, TNTPrimed, Blaze, CaveSpider, Creeper, Drowned, Enderman, Endermite, Evoker, Ghast, "
|
||||
+ + "GiantZombie, Guardian, GuardianElder, IllagerAbstract, IllagerIllusioner, IllagerWizard, MagmaCube, Monster, MonsterPatrolling, Phantom, "
|
||||
+ + "PigZombie, Pillager, Ravager, Shulker, Silverfish, Skeleton, SkeletonAbstract, SkeletonStray, SkeletonWither, Slime, Spider, Strider, Vex, "
|
||||
+ + "Vindicator, Witch, Zoglin, Zombie, ZombieHusk, ZombieVillager, Hoglin, Piglin, PiglinAbstract, PiglinBrute, Warden, Villager, "
|
||||
+ + "VillagerTrader, Arrow, DragonFireball, Egg, EnderPearl, EnderSignal, EvokerFangs, Fireball, FireballFireball, Fireworks, FishingHook, "
|
||||
+ + "LargeFireball, LlamaSpit, Potion, Projectile, ProjectileThrowable, ShulkerBullet, SmallFireball, Snowball, SpectralArrow, ThrownExpBottle, "
|
||||
+ + "ThrownTrident, TippedArrow, WitherSkull, Raider, ChestBoat, Boat, MinecartAbstract, MinecartChest, MinecartCommandBlock, MinecartContainer, "
|
||||
+ + "MinecartFurnace, MinecartHopper, MinecartMobSpawner, MinecartRideable, MinecartTNT\n";
|
||||
+ protected static final File ENTITY_LIMITS_FILE = new File(CONFIG_FOLDER, "kaiiju_entity_limits.yml");
|
||||
+ public static YamlConfiguration entityLimitsConfig;
|
||||
+ public static boolean enabled = false;
|
||||
+
|
||||
+ protected static Map<Class<? extends Entity>, EntityLimit> entityLimits;
|
||||
+
|
||||
+ static final String ENTITY_PREFIX = "Entity";
|
||||
+
|
||||
+ public static void init() {
|
||||
+ init(true);
|
||||
+ }
|
||||
+
|
||||
+ private static void init(boolean setup) {
|
||||
+ entityLimitsConfig = new YamlConfiguration();
|
||||
+
|
||||
+ if (ENTITY_LIMITS_FILE.exists()) {
|
||||
+ try {
|
||||
+ entityLimitsConfig.load(ENTITY_LIMITS_FILE);
|
||||
+ } catch (InvalidConfigurationException ex) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Could not load kaiiju_entity_limits.yml, please correct your syntax errors", ex);
|
||||
+ throw Throwables.propagate(ex);
|
||||
+ } catch (IOException ignore) {}
|
||||
+ } else {
|
||||
+ if (setup) {
|
||||
+ entityLimitsConfig.options().header(HEADER);
|
||||
+ entityLimitsConfig.options().copyDefaults(true);
|
||||
+ entityLimitsConfig.set("enabled", enabled);
|
||||
+ entityLimitsConfig.set("Axolotl.limit", 1000);
|
||||
+ entityLimitsConfig.set("Axolotl.removal", 2000);
|
||||
+ try {
|
||||
+ entityLimitsConfig.save(ENTITY_LIMITS_FILE);
|
||||
+ } catch (IOException ex) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Could not save " + ENTITY_LIMITS_FILE, ex);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ enabled = entityLimitsConfig.getBoolean("enabled");
|
||||
+
|
||||
+ entityLimits = new Object2ObjectOpenHashMap<>();
|
||||
+ try (ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages("net.minecraft.world.entity").scan()) {
|
||||
+ Map<String, ClassInfo> entityClasses = new HashMap<>();
|
||||
+ for (ClassInfo classInfo : scanResult.getAllClasses()) {
|
||||
+ Class<?> entityClass = Class.forName(classInfo.getName());
|
||||
+ if (Entity.class.isAssignableFrom(entityClass)) {
|
||||
+ String entityName = extractEntityName(entityClass.getSimpleName());
|
||||
+ entityClasses.put(entityName, classInfo);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (String key : entityLimitsConfig.getKeys(false)) {
|
||||
+ if (key.equals("enabled")) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!entityClasses.containsKey(key)) {
|
||||
+ LOGGER.error("Unknown entity '" + key + "' in kaiiju-entity-limits.yml, skipping");
|
||||
+ continue;
|
||||
+ }
|
||||
+ int limit = entityLimitsConfig.getInt(key + ".limit");
|
||||
+ int removal = entityLimitsConfig.getInt(key + ".removal");
|
||||
+
|
||||
+ if (limit < 1) {
|
||||
+ LOGGER.error(key + " has a limit less than the minimum of 1, ignoring");
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (removal <= limit && removal != -1) {
|
||||
+ LOGGER.error(key + " has a removal limit that is less than or equal to its limit, setting removal to limit * 10");
|
||||
+ removal = limit * 10;
|
||||
+ }
|
||||
+
|
||||
+ entityLimits.put((Class<? extends Entity>) Class.forName(entityClasses.get(key).getName()), new EntityLimit(limit, removal));
|
||||
+ }
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static EntityLimit getEntityLimit(Entity entity) {
|
||||
+ return entityLimits.get(entity.getClass());
|
||||
+ }
|
||||
+
|
||||
+ private static String extractEntityName(String input) {
|
||||
+ int prefixLength = ENTITY_PREFIX.length();
|
||||
+
|
||||
+ if (input.length() <= prefixLength || !input.startsWith(ENTITY_PREFIX)) {
|
||||
+ return input;
|
||||
+ } else {
|
||||
+ return input.substring(prefixLength);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record EntityLimit(int limit, int removal) {
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "EntityLimit{limit=" + limit + ", removal=" + removal + "}";
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user