mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-26 10:39:07 +00:00
Compare commits
453 Commits
2.3.12-1.1
...
3.2.3-1.19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ac4024e4e | ||
|
|
16affd11cc | ||
|
|
33b0dec9da | ||
|
|
121a463788 | ||
|
|
3625e70948 | ||
|
|
3d90207172 | ||
|
|
ca7dc19c81 | ||
|
|
d0f16dbbc4 | ||
|
|
fd91c223b7 | ||
|
|
93690b766c | ||
|
|
cc4af9950b | ||
|
|
a6281483dd | ||
|
|
f587816b30 | ||
|
|
eea3c3ab0b | ||
|
|
ba68ab9e06 | ||
|
|
eb94d97ea4 | ||
|
|
04ad02719c | ||
|
|
f68f25b92f | ||
|
|
767cca36c8 | ||
|
|
b30172fe89 | ||
|
|
b2934b0cc2 | ||
|
|
50686795d0 | ||
|
|
5561a4dc2f | ||
|
|
15b8780e17 | ||
|
|
15c4d312cb | ||
|
|
ccbea89253 | ||
|
|
7b1e666b3b | ||
|
|
8af212fca8 | ||
|
|
352ee7a622 | ||
|
|
f26d0fac0b | ||
|
|
9612fef2a4 | ||
|
|
a691d49abc | ||
|
|
289eca35ec | ||
|
|
e9ca30257c | ||
|
|
6b21997baa | ||
|
|
6d3dbf84ef | ||
|
|
eb45339c81 | ||
|
|
65e3fdd26c | ||
|
|
34cad85942 | ||
|
|
e407679d2b | ||
|
|
8a08a3e148 | ||
|
|
a01d27d273 | ||
|
|
43f642ae8b | ||
|
|
93c1265de9 | ||
|
|
d08600fbaa | ||
|
|
fb9f8d28f4 | ||
|
|
cd3e9f772d | ||
|
|
7a95441799 | ||
|
|
9345828c97 | ||
|
|
58d88dd079 | ||
|
|
6cbc2374b3 | ||
|
|
12bd11386d | ||
|
|
0497045388 | ||
|
|
d3f1640855 | ||
|
|
960e2fcc61 | ||
|
|
6a012cf400 | ||
|
|
d658ec2099 | ||
|
|
c9a07bd9d7 | ||
|
|
dc4cfc49ad | ||
|
|
9fc72868d7 | ||
|
|
7d4c9d6c1e | ||
|
|
e68b1a52ee | ||
|
|
955e8622b5 | ||
|
|
82640de06b | ||
|
|
c93cb19563 | ||
|
|
ccb7855d7d | ||
|
|
20f05bf317 | ||
|
|
ab658f58f9 | ||
|
|
1b3916749a | ||
|
|
e29ec657d3 | ||
|
|
04f3a226a1 | ||
|
|
099d1cc362 | ||
|
|
c11e9bf704 | ||
|
|
ffa0b984a0 | ||
|
|
f0f9261ed3 | ||
|
|
ba433bc244 | ||
|
|
27f8ad982a | ||
|
|
9b89ae7846 | ||
|
|
c11b5342e3 | ||
|
|
b9c88f5b12 | ||
|
|
02c7ab71d4 | ||
|
|
8ec1ac9875 | ||
|
|
e03027a386 | ||
|
|
387cf566c9 | ||
|
|
dff7665934 | ||
|
|
9421d788f3 | ||
|
|
d960574b24 | ||
|
|
e8671cbbf0 | ||
|
|
cbf8039eea | ||
|
|
d7415e3711 | ||
|
|
26e71ee6b5 | ||
|
|
f8c42b3e48 | ||
|
|
886bed9634 | ||
|
|
7b7023fc99 | ||
|
|
701bfe4a54 | ||
|
|
290d7a93ab | ||
|
|
729bcc7ba0 | ||
|
|
e46b68e2f3 | ||
|
|
cdf73c4629 | ||
|
|
2f0dd2d172 | ||
|
|
7e5704bf80 | ||
|
|
ef96fb9a0e | ||
|
|
f2370ad814 | ||
|
|
0783620104 | ||
|
|
2193b02c0a | ||
|
|
aef05bad20 | ||
|
|
e002ab6378 | ||
|
|
a2c2b4a2d4 | ||
|
|
3ae896457b | ||
|
|
683a90ed09 | ||
|
|
5685e25234 | ||
|
|
6edf083e7b | ||
|
|
995d1495eb | ||
|
|
d5f74631cd | ||
|
|
dd5b9b2e81 | ||
|
|
ca78200c1c | ||
|
|
d73c2a65ae | ||
|
|
0ee2cb8e3c | ||
|
|
5ba429ec73 | ||
|
|
709825d073 | ||
|
|
3fe73af5e8 | ||
|
|
ccc0b0dd7d | ||
|
|
1114ede267 | ||
|
|
5546f12499 | ||
|
|
4f38acb592 | ||
|
|
39f59e023c | ||
|
|
5ed5322fce | ||
|
|
33b926d547 | ||
|
|
af8778c6cd | ||
|
|
bb4ad08cc5 | ||
|
|
ee4eb7b3f0 | ||
|
|
5bc024a6ee | ||
|
|
0546caeb05 | ||
|
|
a75348d3ee | ||
|
|
3f3f947f43 | ||
|
|
5127b7c959 | ||
|
|
a28df78792 | ||
|
|
4f888f16bc | ||
|
|
55ed9d7132 | ||
|
|
779a56c3a1 | ||
|
|
f6440bde07 | ||
|
|
930dc2fd1c | ||
|
|
1e96fd529b | ||
|
|
167c865bb2 | ||
|
|
4e6b6c11a3 | ||
|
|
bfdb71ca91 | ||
|
|
f590f9824e | ||
|
|
b3a087702d | ||
|
|
1a786fb418 | ||
|
|
650d38e212 | ||
|
|
130cb7ad93 | ||
|
|
85e8ffeaa3 | ||
|
|
db40f608fa | ||
|
|
a7b471682a | ||
|
|
4595fea7d7 | ||
|
|
4580f8d9a4 | ||
|
|
37f76fa133 | ||
|
|
5507c35547 | ||
|
|
350328f99c | ||
|
|
91ec6b773d | ||
|
|
c0fdf23133 | ||
|
|
28523a9593 | ||
|
|
07e0b52ea3 | ||
|
|
008e758da8 | ||
|
|
7ce219a6a8 | ||
|
|
1809d4a53f | ||
|
|
54ae026c2b | ||
|
|
57c647fa0e | ||
|
|
9745f23fb2 | ||
|
|
7d2062f298 | ||
|
|
306a1948cf | ||
|
|
ac4c00d3f2 | ||
|
|
db43bc300e | ||
|
|
6494cded62 | ||
|
|
b5c1e7e2da | ||
|
|
83e311870f | ||
|
|
8fc6e3b335 | ||
|
|
18a69e97b3 | ||
|
|
80d8449f02 | ||
|
|
d830aa1d1a | ||
|
|
d473126d4c | ||
|
|
17f8fe69fb | ||
|
|
7263d102c7 | ||
|
|
815b2235a2 | ||
|
|
f61247f8bb | ||
|
|
205d9d528e | ||
|
|
1044f901bd | ||
|
|
de261a38fd | ||
|
|
81776e60fb | ||
|
|
0c179eae86 | ||
|
|
c30de98449 | ||
|
|
47990cde46 | ||
|
|
b098c210ce | ||
|
|
6edd8bf119 | ||
|
|
de0e124ebb | ||
|
|
5fc012a557 | ||
|
|
32afcc3478 | ||
|
|
a27f37945d | ||
|
|
0adfe6911f | ||
|
|
8bb1964b30 | ||
|
|
cc95e1ae63 | ||
|
|
9843f18c96 | ||
|
|
18ea61fcc0 | ||
|
|
5b3fdb6e62 | ||
|
|
c5220c8d06 | ||
|
|
74e87a7fae | ||
|
|
c809f50c3b | ||
|
|
e7e46f78c7 | ||
|
|
2b449a1f3d | ||
|
|
f257f2c551 | ||
|
|
7f91d73d27 | ||
|
|
15a90edb03 | ||
|
|
b2f1e16d9a | ||
|
|
f544455708 | ||
|
|
5118997188 | ||
|
|
b6ae649cd1 | ||
|
|
a6d0d85b84 | ||
|
|
c71c2494af | ||
|
|
4a3a7bc98d | ||
|
|
4e4f7f693d | ||
|
|
7a729c39a6 | ||
|
|
48b757f693 | ||
|
|
b449938730 | ||
|
|
ba55ff6a4b | ||
|
|
2b4bc621ac | ||
|
|
acac2d0fc5 | ||
|
|
6ff5975918 | ||
|
|
8912cfe37b | ||
|
|
9e02c318a1 | ||
|
|
f6b51c21d5 | ||
|
|
df3e4b055f | ||
|
|
ffcd2b4179 | ||
|
|
7afdbc2a53 | ||
|
|
5004481685 | ||
|
|
1905741a7c | ||
|
|
8bf7451107 | ||
|
|
fdfb708ce0 | ||
|
|
68a4eee8bb | ||
|
|
746ebfffbd | ||
|
|
213f8645bc | ||
|
|
1b2541bd84 | ||
|
|
522de89792 | ||
|
|
5feaa45edf | ||
|
|
9333775e0e | ||
|
|
afd15ad450 | ||
|
|
e7fc9e6fe5 | ||
|
|
021f9b1d0e | ||
|
|
dc21f05482 | ||
|
|
c22ccf71a7 | ||
|
|
d5b9a074e6 | ||
|
|
63e6104736 | ||
|
|
de475c9561 | ||
|
|
3f4fa0c67c | ||
|
|
ca3f228b89 | ||
|
|
2b159041ac | ||
|
|
5fa564969e | ||
|
|
8ba8627281 | ||
|
|
a12cb59a51 | ||
|
|
dd124fab33 | ||
|
|
9f8ef4c1f3 | ||
|
|
563c6d0403 | ||
|
|
1bad0fe048 | ||
|
|
b40dcd3164 | ||
|
|
8a0b443d28 | ||
|
|
5f38503ac5 | ||
|
|
231d1209c9 | ||
|
|
06bc180127 | ||
|
|
fb2221fa8d | ||
|
|
e1c7f38bb8 | ||
|
|
a82fa578eb | ||
|
|
0ecefdcc1c | ||
|
|
8bacc8128b | ||
|
|
3dff96152c | ||
|
|
79e198d441 | ||
|
|
e6cf33e262 | ||
|
|
f839ca674b | ||
|
|
f9427d1258 | ||
|
|
bd2cdc9bd0 | ||
|
|
67352311de | ||
|
|
555a7682e1 | ||
|
|
19d94489d7 | ||
|
|
0175cfa986 | ||
|
|
1b0ff36d51 | ||
|
|
f5c499ab60 | ||
|
|
81e3fd346a | ||
|
|
3bca1f5304 | ||
|
|
593e96a31a | ||
|
|
169b783e4f | ||
|
|
f129742a41 | ||
|
|
01016d1b14 | ||
|
|
a883e43acb | ||
|
|
e0d0657e7b | ||
|
|
e4c27bd49c | ||
|
|
7a31fd31eb | ||
|
|
4f0f2c3213 | ||
|
|
d9889b06ad | ||
|
|
9f5cff4ab8 | ||
|
|
958543a171 | ||
|
|
b8e03f5e13 | ||
|
|
e76218b39f | ||
|
|
7d1a375bda | ||
|
|
dfaa80f1e4 | ||
|
|
8939a903be | ||
|
|
d6f1ea78fa | ||
|
|
f25c4c74be | ||
|
|
1619df1ba3 | ||
|
|
566169cdbf | ||
|
|
ee3e631789 | ||
|
|
8202754988 | ||
|
|
447d7596dc | ||
|
|
7c4568066f | ||
|
|
46ee7a5983 | ||
|
|
5a8ef99afa | ||
|
|
571729cfe4 | ||
|
|
c1de316ed6 | ||
|
|
1e316acd64 | ||
|
|
f89460538d | ||
|
|
0bf0062c2c | ||
|
|
540d1b5801 | ||
|
|
8f0d1b7b7b | ||
|
|
5061791dcf | ||
|
|
ce98264552 | ||
|
|
15e6750e11 | ||
|
|
7a20421580 | ||
|
|
f42f06226c | ||
|
|
cce3d74c52 | ||
|
|
7b9fb880f4 | ||
|
|
2a9b0a54d9 | ||
|
|
373e9e9755 | ||
|
|
4115dd5797 | ||
|
|
57bfd251dc | ||
|
|
d324790f66 | ||
|
|
99d3dba440 | ||
|
|
5a44e79ad1 | ||
|
|
86808017db | ||
|
|
f735db9843 | ||
|
|
5a333c23ac | ||
|
|
4d2d51edfa | ||
|
|
dcfd5a0cd8 | ||
|
|
a821c0da50 | ||
|
|
804147e2c4 | ||
|
|
ed346291f9 | ||
|
|
2190f6eff8 | ||
|
|
ce30e24e42 | ||
|
|
d5e13541c8 | ||
|
|
2e707adaa0 | ||
|
|
4d8e36cb05 | ||
|
|
73b710cdde | ||
|
|
09182bf3f3 | ||
|
|
9a945837cd | ||
|
|
b64c821ef4 | ||
|
|
a9ab3bc519 | ||
|
|
94292cea6e | ||
|
|
b5fdeb2a02 | ||
|
|
fa3ac36e8c | ||
|
|
6632d1b65f | ||
|
|
8805693800 | ||
|
|
93db7ee0ee | ||
|
|
9ba4dd4099 | ||
|
|
36efacf43c | ||
|
|
d9bf91afa5 | ||
|
|
b0c96be841 | ||
|
|
673b08f174 | ||
|
|
989778af26 | ||
|
|
f5a3a7eb1a | ||
|
|
7a97928c21 | ||
|
|
12a6d022cf | ||
|
|
e3d2dfa99e | ||
|
|
35cc39e9e2 | ||
|
|
006b0b4a03 | ||
|
|
ec939b9f78 | ||
|
|
7a94f53735 | ||
|
|
a9efe146ba | ||
|
|
956e2f6b06 | ||
|
|
72623e0acf | ||
|
|
e0f673bc3c | ||
|
|
fe40f12d2e | ||
|
|
0fda7a8506 | ||
|
|
22887da769 | ||
|
|
a1e0a8ffc1 | ||
|
|
62010116d7 | ||
|
|
6ebcd02ae6 | ||
|
|
051015656a | ||
|
|
ee082762c6 | ||
|
|
e967b5e052 | ||
|
|
36505e2fa1 | ||
|
|
502aa054f6 | ||
|
|
cc5a880fd7 | ||
|
|
6f9ad8b0eb | ||
|
|
ac6ab74d48 | ||
|
|
807ed2b247 | ||
|
|
367de5a8fd | ||
|
|
5bf2da714a | ||
|
|
cc90f42deb | ||
|
|
20ceaead09 | ||
|
|
3ec2f8fb7b | ||
|
|
6c5fac154e | ||
|
|
540ab8f0d2 | ||
|
|
17d2ac8d70 | ||
|
|
a6ebdead19 | ||
|
|
aa7631ecd0 | ||
|
|
4e138cad9f | ||
|
|
7e55b5fcee | ||
|
|
e19e5278b4 | ||
|
|
dfcd2dc83e | ||
|
|
8775f842e6 | ||
|
|
7b07a4ba6c | ||
|
|
d78e5973e9 | ||
|
|
110d296184 | ||
|
|
23cd5c117b | ||
|
|
131c4692bc | ||
|
|
f6571367db | ||
|
|
f5c64c7480 | ||
|
|
085f63a915 | ||
|
|
3e022e1931 | ||
|
|
0dba3725ae | ||
|
|
8bb409df4e | ||
|
|
603168a147 | ||
|
|
2a95edd860 | ||
|
|
e94406fb45 | ||
|
|
e5a7b5d0c6 | ||
|
|
d6f816fe2f | ||
|
|
c15d4a349f | ||
|
|
3ce832583c | ||
|
|
5514fd2645 | ||
|
|
66d07dcaca | ||
|
|
c1cf8e88ee | ||
|
|
684bd739b9 | ||
|
|
d4c0e07b1d | ||
|
|
a6ea6fcfb2 | ||
|
|
c366ec0c40 | ||
|
|
8d715e2e4e | ||
|
|
dea3ec80ac | ||
|
|
4053f05ba9 | ||
|
|
ef07ec2c62 | ||
|
|
0ffc64231b | ||
|
|
fe112c3ba5 | ||
|
|
2fa03aac3b | ||
|
|
6ac5ad880d | ||
|
|
54f14392d9 | ||
|
|
c7ecdaf8a8 | ||
|
|
497c24a3b6 | ||
|
|
00aa26e602 | ||
|
|
3796381156 | ||
|
|
b0c5700cf5 | ||
|
|
78a4b1d2ce | ||
|
|
e5e6b9848f | ||
|
|
3e36f57f14 | ||
|
|
d794ede4d8 | ||
|
|
7a4d97d76a | ||
|
|
e76ab1d367 | ||
|
|
9731feff7f | ||
|
|
4ce790082d |
3
.github/ISSUE_TEMPLATE/bug.yml
vendored
3
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -40,6 +40,9 @@ body:
|
||||
- 1.17.1
|
||||
- 1.18
|
||||
- 1.19
|
||||
- 1.20
|
||||
- 1.21
|
||||
- 1.22
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
|
||||
build/
|
||||
libs/
|
||||
|
||||
.gradle/
|
||||
|
||||
@@ -9,4 +10,4 @@ build/
|
||||
|
||||
collection/
|
||||
|
||||
src/main/java/com/volmit/iris/util/uniques/
|
||||
/core/src/main/java/com/volmit/iris/util/uniques/
|
||||
|
||||
@@ -11,6 +11,8 @@ development.
|
||||
|
||||
Consider supporting our development by buying Iris on spigot! We work hard to make Iris the best it can be for everyone.
|
||||
|
||||
## Preface: if you need help compiling and you are a developer / intend to help out in the community or with development we would love to help you regardless in the discord! however do not come to the discord asking for free copies, or a tutorial on how to compile.
|
||||
|
||||
### Command Line Builds
|
||||
|
||||
1. Install [Java JDK 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
||||
|
||||
668
build.gradle
668
build.gradle
@@ -1,321 +1,347 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'java-library'
|
||||
id "io.freefair.lombok" version "6.3.0"
|
||||
id "com.github.johnrengelman.shadow" version "7.1.2"
|
||||
id "de.undercouch.download" version "5.0.1"
|
||||
}
|
||||
|
||||
version '2.3.10-1.19.3' // Needs to be version specific
|
||||
def nmsVersion = "1.19.3" //[NMS]
|
||||
def apiVersion = '1.19'
|
||||
def specialSourceVersion = '1.11.0' //[NMS]
|
||||
def spigotJarVersion = '1.19.3-R0.1-SNAPSHOT' //[NMS]
|
||||
def name = getRootProject().getName() // Defined in settings.gradle
|
||||
def main = 'com.volmit.iris.Iris'
|
||||
|
||||
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
||||
// ======================== WINDOWS =============================
|
||||
registerCustomOutputTask('Cyberpwn', 'C://Users/cyberpwn/Documents/development/server/plugins')
|
||||
registerCustomOutputTask('Psycho', 'C://Dan/MinecraftDevelopment/Server/plugins')
|
||||
registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/server/plugins')
|
||||
registerCustomOutputTask('Coco', 'D://Documents/MC/plugins')
|
||||
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
||||
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.3/plugins')
|
||||
// ========================== UNIX ==============================
|
||||
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
||||
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Desktop/REMOTES/RemoteMinecraft/plugins')
|
||||
// ==============================================================
|
||||
|
||||
/**
|
||||
* Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
|
||||
*/
|
||||
file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete()
|
||||
|
||||
/**
|
||||
* Expand properties into plugin yml
|
||||
*/
|
||||
processResources {
|
||||
filesMatching('**/plugin.yml') {
|
||||
expand(
|
||||
'name': name.toString(),
|
||||
'version': version.toString(),
|
||||
'main': main.toString(),
|
||||
'apiversion': apiVersion.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified repo
|
||||
*/
|
||||
repositories {
|
||||
mavenLocal {
|
||||
content {
|
||||
includeGroup("org.bukkit")
|
||||
includeGroup("org.spigotmc")
|
||||
}
|
||||
}
|
||||
maven { url "https://arcanearts.jfrog.io/artifactory/archives" }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* We need parameter meta for the decree command system
|
||||
*/
|
||||
compileJava {
|
||||
options.compilerArgs << '-parameters'
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure Iris for shading
|
||||
*/
|
||||
shadowJar {
|
||||
//minimize()
|
||||
append("plugin.yml")
|
||||
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
|
||||
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
||||
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
||||
dependencies {
|
||||
include(dependency('io.papermc:paperlib'))
|
||||
include(dependency('com.dfsek:Paralithic'))
|
||||
include(dependency('net.kyori:'))
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
|
||||
resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes'
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependencies.
|
||||
*
|
||||
* Provided or classpath dependencies are not shaded and are available on the runtime classpath
|
||||
*
|
||||
* Shaded dependencies are not available at runtime, nor are they available on mvn central so they
|
||||
* need to be shaded into the jar (increasing binary size)
|
||||
*
|
||||
* Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
|
||||
* plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
|
||||
* these dependencies if they are available on mvn central.
|
||||
*/
|
||||
dependencies {
|
||||
// Provided or Classpath
|
||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||
implementation 'org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT'
|
||||
implementation 'me.clip:placeholderapi:2.11.1'
|
||||
implementation 'io.th0rgal:oraxen:1.94.0'
|
||||
implementation 'org.bukkit:craftbukkit:1.19.3-R0.1-SNAPSHOT:remapped-mojang' //[NMS]
|
||||
implementation 'com.github.LoneDev6:api-itemsadder:3.1.0b'
|
||||
|
||||
// Shaded
|
||||
implementation 'com.dfsek:Paralithic:0.4.0'
|
||||
implementation 'io.papermc:paperlib:1.0.5'
|
||||
implementation "net.kyori:adventure-text-minimessage:4.11.0"
|
||||
implementation 'net.kyori:adventure-platform-bukkit:4.1.0'
|
||||
implementation 'net.kyori:adventure-api:4.11.0'
|
||||
|
||||
// Dynamically Loaded
|
||||
implementation 'io.timeandspace:smoothie-map:2.0.2'
|
||||
implementation 'it.unimi.dsi:fastutil:8.5.8'
|
||||
implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
|
||||
implementation 'org.zeroturnaround:zt-zip:1.14'
|
||||
implementation 'com.google.code.gson:gson:2.9.0'
|
||||
implementation 'org.ow2.asm:asm:9.2'
|
||||
implementation 'com.google.guava:guava:31.1-jre'
|
||||
implementation 'bsf:bsf:2.4.0'
|
||||
implementation 'rhino:js:1.7R2'
|
||||
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6'
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
}
|
||||
|
||||
if (JavaVersion.current().toString() != "17") {
|
||||
System.err.println()
|
||||
System.err.println("=========================================================================================================")
|
||||
System.err.println("You must run gradle on Java 17. You are using " + JavaVersion.current())
|
||||
System.err.println()
|
||||
System.err.println("=== For IDEs ===")
|
||||
System.err.println("1. Configure the project for Java 17")
|
||||
System.err.println("2. Configure the bundled gradle to use Java 17 in settings")
|
||||
System.err.println()
|
||||
System.err.println("=== For Command Line (gradlew) ===")
|
||||
System.err.println("1. Install JDK 17 from https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html")
|
||||
System.err.println("2. Set JAVA_HOME environment variable to the new jdk installation folder such as C:\\Program Files\\Java\\jdk-17.0.1")
|
||||
System.err.println("3. Open a new command prompt window to get the new environment variables if need be.")
|
||||
System.err.println("=========================================================================================================")
|
||||
System.err.println()
|
||||
System.exit(69);
|
||||
}
|
||||
|
||||
def buildToolsJar = new File(buildDir, "buildtools/BuildTools.jar");
|
||||
def specialSourceJar = new File(buildDir, "specialsource/SpecialSource.jar");
|
||||
def buildToolsFolder = new File(buildDir, "buildtools");
|
||||
def specialSourceFolder = new File(buildDir, "specialsource");
|
||||
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nmsVersion + ".jar");
|
||||
def outputShadeJar = new File(buildDir, "libs/Iris-" + version + "-all.jar");
|
||||
def ssiJar = new File(buildDir, "specialsource/Iris-" + version + "-all.jar");
|
||||
def ssobfJar = new File(buildDir, "specialsource/Iris-" + version + "-rmo.jar");
|
||||
def ssJar = new File(buildDir, "specialsource/Iris-" + version + "-rma.jar");
|
||||
def homePath = System.properties['user.home']
|
||||
def m2 = new File(homePath + "/.m2/repository")
|
||||
def m2s = m2.getAbsolutePath();
|
||||
|
||||
// ======================== Building Mapped Jars =============================
|
||||
task downloadBuildtools(type: Download) {
|
||||
group "remapping"
|
||||
src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar'
|
||||
dest buildToolsJar
|
||||
onlyIf {
|
||||
!buildToolsJar.exists()
|
||||
}
|
||||
}
|
||||
|
||||
task downloadSpecialSource(type: Download) {
|
||||
group "remapping"
|
||||
src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/' + specialSourceVersion + '/SpecialSource-'+specialSourceVersion+'-shaded.jar'
|
||||
dest specialSourceJar
|
||||
onlyIf {
|
||||
!specialSourceJar.exists()
|
||||
}
|
||||
}
|
||||
|
||||
task executeBuildTools(dependsOn: downloadBuildtools, type: JavaExec)
|
||||
{
|
||||
group "remapping"
|
||||
classpath = files(buildToolsJar)
|
||||
workingDir = buildToolsFolder
|
||||
args = [
|
||||
"--rev",
|
||||
nmsVersion,
|
||||
"--compile",
|
||||
"craftbukkit",
|
||||
"--remap"
|
||||
]
|
||||
onlyIf {
|
||||
!buildToolsHint.exists()
|
||||
}
|
||||
}
|
||||
|
||||
task copyBuildToSpecialSource(type: Copy)
|
||||
{
|
||||
group "remapping"
|
||||
from outputShadeJar
|
||||
into specialSourceFolder
|
||||
dependsOn(downloadSpecialSource, shadowJar)
|
||||
}
|
||||
|
||||
task specialSourceRemapObfuscate(type: JavaExec)
|
||||
{
|
||||
group "remapping"
|
||||
dependsOn(copyBuildToSpecialSource, downloadSpecialSource, shadowJar)
|
||||
workingDir = specialSourceFolder
|
||||
classpath = files(specialSourceJar,
|
||||
new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-mojang.jar"))
|
||||
mainClass = "net.md_5.specialsource.SpecialSource"
|
||||
args = [
|
||||
"--live",
|
||||
"-i",
|
||||
ssiJar.getName(),
|
||||
"-o",
|
||||
ssobfJar.getName(),
|
||||
"-m",
|
||||
m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-mojang.txt",
|
||||
"--reverse",
|
||||
]
|
||||
}
|
||||
|
||||
task specialSourceRemap(type: JavaExec)
|
||||
{
|
||||
group "remapping"
|
||||
dependsOn(specialSourceRemapObfuscate)
|
||||
workingDir = specialSourceFolder
|
||||
classpath = files(specialSourceJar,
|
||||
new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-obf.jar"))
|
||||
mainClass = "net.md_5.specialsource.SpecialSource"
|
||||
args = [
|
||||
"--live",
|
||||
"-i",
|
||||
ssobfJar.getName(),
|
||||
"-o",
|
||||
ssJar.getName(),
|
||||
"-m",
|
||||
m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-spigot.csrg"
|
||||
]
|
||||
}
|
||||
|
||||
tasks.compileJava.dependsOn(executeBuildTools)
|
||||
|
||||
compileJava {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
task setup()
|
||||
{
|
||||
group("iris")
|
||||
dependsOn(clean, executeBuildTools)
|
||||
}
|
||||
|
||||
task iris(type: Copy)
|
||||
{
|
||||
group "iris"
|
||||
from ssJar
|
||||
into buildDir
|
||||
rename { String fileName ->
|
||||
fileName.replace('Iris-' + version + '-rma.jar', "Iris-" + version + ".jar")
|
||||
}
|
||||
dependsOn(specialSourceRemap)
|
||||
}
|
||||
|
||||
def registerCustomOutputTask(name, path) {
|
||||
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||
return;
|
||||
}
|
||||
|
||||
tasks.register('build' + name, Copy) {
|
||||
group('development')
|
||||
outputs.upToDateWhen { false }
|
||||
dependsOn(iris)
|
||||
from(new File(buildDir, "Iris-" + version + ".jar"))
|
||||
into(file(path))
|
||||
rename { String fileName ->
|
||||
fileName.replace("Iris-" + version + ".jar", "Iris.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def registerCustomOutputTaskUnix(name, path) {
|
||||
if (System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||
return;
|
||||
}
|
||||
|
||||
tasks.register('build' + name, Copy) {
|
||||
group('development')
|
||||
outputs.upToDateWhen { false }
|
||||
dependsOn(iris)
|
||||
from(new File(buildDir, "Iris-" + version + ".jar"))
|
||||
into(file(path))
|
||||
rename { String fileName ->
|
||||
fileName.replace("Iris-" + version + ".jar", "Iris.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
import java.util.function.Consumer
|
||||
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'java-library'
|
||||
id "com.github.johnrengelman.shadow" version "7.1.2"
|
||||
id "de.undercouch.download" version "5.0.1"
|
||||
}
|
||||
|
||||
version '3.2.3-1.19.2-1.20.4'
|
||||
def specialSourceVersion = '1.11.0' //[NMS]
|
||||
|
||||
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
||||
// ======================== WINDOWS =============================
|
||||
registerCustomOutputTask('Cyberpwn', 'C://Users/cyberpwn/Documents/development/server/plugins')
|
||||
registerCustomOutputTask('Psycho', 'C://Dan/MinecraftDevelopment/Server/plugins')
|
||||
registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/server/plugins')
|
||||
registerCustomOutputTask('Coco', 'D://mcsm/plugins')
|
||||
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
||||
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
||||
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
||||
registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.4 - Iris Development/plugins')
|
||||
// ========================== UNIX ==============================
|
||||
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
||||
registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins')
|
||||
// ==============================================================
|
||||
|
||||
def NMS_BINDINGS = Map.of(
|
||||
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
||||
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
||||
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
||||
"v1_19_R3", "1.19.4-R0.1-SNAPSHOT",
|
||||
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
|
||||
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
|
||||
)
|
||||
NMS_BINDINGS.each {
|
||||
def key = it.key
|
||||
def value = it.value
|
||||
def nms = value.split("-")[0];
|
||||
project(":nms:${key}") {
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'de.undercouch.download'
|
||||
|
||||
dependencies {
|
||||
implementation project(":core")
|
||||
compileOnly "org.spigotmc:spigot-api:${value}"
|
||||
compileOnly "org.bukkit:craftbukkit:${value}:remapped-mojang" //[NMS]
|
||||
}
|
||||
def buildToolsJar = new File(rootProject.buildDir, "tools/BuildTools.jar")
|
||||
def specialSourceJar = new File(rootProject.buildDir, "tools/SpecialSource.jar")
|
||||
|
||||
def buildToolsFolder = new File(buildDir, "buildtools")
|
||||
def specialSourceFolder = new File(buildDir, "specialsource")
|
||||
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nms + ".jar")
|
||||
|
||||
def outputJar = new File(buildDir, "libs/${key}.jar")
|
||||
def ssiJar = new File(buildDir, "specialsource/${key}.jar")
|
||||
def ssobfJar = new File(buildDir, "specialsource/${key}-rmo.jar")
|
||||
def ssJar = new File(buildDir, "specialsource/${key}-rma.jar")
|
||||
|
||||
def homePath = System.properties['user.home']
|
||||
def m2 = new File(homePath + "/.m2/repository")
|
||||
def m2s = m2.getAbsolutePath();
|
||||
|
||||
// ======================== Building Mapped Jars =============================
|
||||
|
||||
ext {
|
||||
executeBuildTools = new Runnable() {
|
||||
@Override
|
||||
void run() {
|
||||
//Download
|
||||
if (!buildToolsJar.exists()) {
|
||||
download.run {
|
||||
src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar'
|
||||
dest buildToolsJar
|
||||
}
|
||||
}
|
||||
|
||||
//Execute
|
||||
if (!buildToolsHint.exists()) {
|
||||
buildToolsFolder.mkdirs()
|
||||
project.javaexec {
|
||||
classpath = files(buildToolsJar)
|
||||
workingDir = buildToolsFolder
|
||||
args = [
|
||||
"--rev",
|
||||
nms,
|
||||
"--compile",
|
||||
"craftbukkit",
|
||||
"--remap"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.register("executeBuildTools") {
|
||||
doLast {
|
||||
property("executeBuildTools").run();
|
||||
}
|
||||
}
|
||||
|
||||
tasks.build.doLast {
|
||||
//Download
|
||||
if (!specialSourceJar.exists()) {
|
||||
download.run {
|
||||
src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/' + specialSourceVersion + '/SpecialSource-'+specialSourceVersion+'-shaded.jar'
|
||||
dest specialSourceJar
|
||||
}
|
||||
}
|
||||
specialSourceFolder.mkdirs();
|
||||
|
||||
//Copy
|
||||
copy {
|
||||
from outputJar
|
||||
into specialSourceFolder
|
||||
}
|
||||
|
||||
//obfuscate
|
||||
javaexec {
|
||||
workingDir = specialSourceFolder
|
||||
classpath = files(specialSourceJar,
|
||||
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-mojang.jar"))
|
||||
mainClass = "net.md_5.specialsource.SpecialSource"
|
||||
args = [
|
||||
"--live",
|
||||
"-i",
|
||||
ssiJar.getName(),
|
||||
"-o",
|
||||
ssobfJar.getName(),
|
||||
"-m",
|
||||
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-mojang.txt",
|
||||
"--reverse",
|
||||
]
|
||||
}
|
||||
|
||||
//remap
|
||||
javaexec {
|
||||
workingDir = specialSourceFolder
|
||||
classpath = files(specialSourceJar,
|
||||
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-obf.jar"))
|
||||
mainClass = "net.md_5.specialsource.SpecialSource"
|
||||
args = [
|
||||
"--live",
|
||||
"-i",
|
||||
ssobfJar.getName(),
|
||||
"-o",
|
||||
ssJar.getName(),
|
||||
"-m",
|
||||
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-spigot.csrg"
|
||||
]
|
||||
}
|
||||
//copy
|
||||
copy {
|
||||
from ssJar
|
||||
into outputJar.getParentFile()
|
||||
rename {
|
||||
outputJar.getName()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
NMS_BINDINGS.each {dependsOn(":nms:${it.key}:build")}
|
||||
|
||||
//minimize()
|
||||
append("plugin.yml")
|
||||
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
|
||||
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
||||
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
||||
archiveFileName.set("Iris-${project.version}.jar")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':core')
|
||||
NMS_BINDINGS.each {
|
||||
implementation project(":nms:${it.key}")
|
||||
}
|
||||
}
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
|
||||
resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes'
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'java'
|
||||
|
||||
repositories {
|
||||
mavenLocal {
|
||||
content {
|
||||
includeGroup("org.bukkit")
|
||||
includeGroup("org.spigotmc")
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
maven { url "https://repo.papermc.io/repository/maven-public/"}
|
||||
maven { url "https://repo.codemc.org/repository/maven-public" }
|
||||
maven { url "https://mvn.lumine.io/repository/maven-public/" }
|
||||
maven { url "https://jitpack.io"}
|
||||
|
||||
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
|
||||
maven { url "https://mvn.lumine.io/repository/maven/" }
|
||||
maven { url "https://repo.triumphteam.dev/snapshots" }
|
||||
maven { url "https://repo.mineinabyss.com/releases" }
|
||||
maven { url 'https://hub.jeff-media.com/nexus/repository/jeff-media-public/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Provided or Classpath
|
||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||
|
||||
// Shaded
|
||||
implementation 'com.dfsek:Paralithic:0.4.0'
|
||||
implementation 'io.papermc:paperlib:1.0.5'
|
||||
implementation "net.kyori:adventure-text-minimessage:4.13.1"
|
||||
implementation 'net.kyori:adventure-platform-bukkit:4.3.2'
|
||||
implementation 'net.kyori:adventure-api:4.13.1'
|
||||
compileOnly 'io.lumine:Mythic-Dist:5.2.1'
|
||||
|
||||
// Dynamically Loaded
|
||||
compileOnly 'io.timeandspace:smoothie-map:2.0.2'
|
||||
compileOnly 'it.unimi.dsi:fastutil:8.5.8'
|
||||
compileOnly 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
|
||||
compileOnly 'org.zeroturnaround:zt-zip:1.14'
|
||||
compileOnly 'com.google.code.gson:gson:2.9.0'
|
||||
compileOnly 'org.ow2.asm:asm:9.2'
|
||||
compileOnly 'com.google.guava:guava:33.0.0-jre'
|
||||
compileOnly 'bsf:bsf:2.4.0'
|
||||
compileOnly 'rhino:js:1.7R2'
|
||||
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
|
||||
compileOnly 'org.apache.commons:commons-lang3:3.12.0'
|
||||
}
|
||||
|
||||
/**
|
||||
* We need parameter meta for the decree command system
|
||||
*/
|
||||
compileJava {
|
||||
options.compilerArgs << '-parameters'
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaVersion.current().toString() != "17") {
|
||||
System.err.println()
|
||||
System.err.println("=========================================================================================================")
|
||||
System.err.println("You must run gradle on Java 17. You are using " + JavaVersion.current())
|
||||
System.err.println()
|
||||
System.err.println("=== For IDEs ===")
|
||||
System.err.println("1. Configure the project for Java 17")
|
||||
System.err.println("2. Configure the bundled gradle to use Java 17 in settings")
|
||||
System.err.println()
|
||||
System.err.println("=== For Command Line (gradlew) ===")
|
||||
System.err.println("1. Install JDK 17 from https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html")
|
||||
System.err.println("2. Set JAVA_HOME environment variable to the new jdk installation folder such as C:\\Program Files\\Java\\jdk-17.0.1")
|
||||
System.err.println("3. Open a new command prompt window to get the new environment variables if need be.")
|
||||
System.err.println("=========================================================================================================")
|
||||
System.err.println()
|
||||
System.exit(69);
|
||||
}
|
||||
|
||||
task iris(type: Copy) {
|
||||
group "iris"
|
||||
from new File(buildDir, "libs/Iris-${version}.jar")
|
||||
into buildDir
|
||||
dependsOn(build)
|
||||
}
|
||||
|
||||
task setup() {
|
||||
group "iris"
|
||||
dependsOn(clean)
|
||||
NMS_BINDINGS.each {
|
||||
dependsOn(":nms:${it.key}:clean");
|
||||
}
|
||||
|
||||
doLast {
|
||||
NMS_BINDINGS.each {
|
||||
project(":nms:${it.key}").property("executeBuildTools").run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NMS_BINDINGS.keySet().forEach {
|
||||
def nms = it
|
||||
tasks.register("setup-${nms}") {
|
||||
group "iris"
|
||||
dependsOn(":nms:${nms}:clean")
|
||||
dependsOn(":nms:${nms}:executeBuildTools")
|
||||
}
|
||||
}
|
||||
|
||||
def registerCustomOutputTask(name, path) {
|
||||
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||
return;
|
||||
}
|
||||
|
||||
tasks.register('build' + name, Copy) {
|
||||
group('development')
|
||||
outputs.upToDateWhen { false }
|
||||
dependsOn(iris)
|
||||
from(new File(buildDir, "Iris-" + version + ".jar"))
|
||||
into(file(path))
|
||||
rename { String fileName ->
|
||||
fileName.replace("Iris-" + version + ".jar", "Iris.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def registerCustomOutputTaskUnix(name, path) {
|
||||
if (System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||
return;
|
||||
}
|
||||
|
||||
tasks.register('build' + name, Copy) {
|
||||
group('development')
|
||||
outputs.upToDateWhen { false }
|
||||
dependsOn(iris)
|
||||
from(new File(buildDir, "Iris-" + version + ".jar"))
|
||||
into(file(path))
|
||||
rename { String fileName ->
|
||||
fileName.replace("Iris-" + version + ".jar", "Iris.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.build.dependsOn(shadowJar)
|
||||
|
||||
90
core/build.gradle
Normal file
90
core/build.gradle
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'java-library'
|
||||
id "io.freefair.lombok" version "6.3.0"
|
||||
}
|
||||
|
||||
def apiVersion = '1.19'
|
||||
def main = 'com.volmit.iris.Iris'
|
||||
|
||||
/**
|
||||
* We need parameter meta for the decree command system
|
||||
*/
|
||||
compileJava {
|
||||
options.compilerArgs << '-parameters'
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependencies.
|
||||
*
|
||||
* Provided or classpath dependencies are not shaded and are available on the runtime classpath
|
||||
*
|
||||
* Shaded dependencies are not available at runtime, nor are they available on mvn central so they
|
||||
* need to be shaded into the jar (increasing binary size)
|
||||
*
|
||||
* Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
|
||||
* plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
|
||||
* these dependencies if they are available on mvn central.
|
||||
*/
|
||||
dependencies {
|
||||
// Provided or Classpath
|
||||
compileOnly 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'org.apache.logging.log4j:log4j-api:2.19.0'
|
||||
compileOnly 'org.apache.logging.log4j:log4j-core:2.19.0'
|
||||
compileOnly 'commons-io:commons-io:2.13.0'
|
||||
compileOnly 'commons-lang:commons-lang:2.6'
|
||||
compileOnly 'com.github.oshi:oshi-core:5.8.5'
|
||||
compileOnly 'org.lz4:lz4-java:1.8.0'
|
||||
|
||||
// Third Party Integrations
|
||||
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
|
||||
compileOnly 'com.github.oraxen:oraxen:1.158.0'
|
||||
compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
||||
compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
|
||||
compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
|
||||
compileOnly 'net.Indyuce:MMOItems-API:6.9.5-SNAPSHOT'
|
||||
//implementation files('libs/CustomItems.jar')
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
|
||||
*/
|
||||
file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete()
|
||||
|
||||
/**
|
||||
* Expand properties into plugin yml
|
||||
*/
|
||||
processResources {
|
||||
filesMatching('**/plugin.yml') {
|
||||
expand(
|
||||
'name': rootProject.name.toString(),
|
||||
'version': rootProject.version.toString(),
|
||||
'main': main.toString(),
|
||||
'apiversion': apiVersion.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,7 @@ import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.json.JSONException;
|
||||
import com.volmit.iris.util.json.JSONObject;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
@@ -135,7 +136,7 @@ public class IrisSettings {
|
||||
|
||||
@Data
|
||||
public static class IrisSettingsPerformance {
|
||||
public boolean trimMantleInStudio = false;
|
||||
public boolean trimMantleInStudio = false;
|
||||
public int mantleKeepAlive = 30;
|
||||
public int cacheSize = 4_096;
|
||||
public int resourceLoaderCacheSize = 1_024;
|
||||
@@ -145,6 +146,7 @@ public class IrisSettings {
|
||||
|
||||
@Data
|
||||
public static class IrisSettingsGeneral {
|
||||
public boolean ignoreBootMode = false;
|
||||
public boolean commandSounds = true;
|
||||
public boolean debug = false;
|
||||
public boolean disableNMS = false;
|
||||
@@ -156,6 +158,8 @@ public class IrisSettings {
|
||||
public int spinh = -20;
|
||||
public int spins = 7;
|
||||
public int spinb = 8;
|
||||
public String cartographerMessage = "Iris does not allow cartographers in its world due to crashes.";
|
||||
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean canUseCustomColors(VolmitSender volmitSender) {
|
||||
@@ -173,6 +177,7 @@ public class IrisSettings {
|
||||
public static class IrisSettingsGenerator {
|
||||
public String defaultWorldType = "overworld";
|
||||
public int maxBiomeChildDepth = 4;
|
||||
// public boolean forceConvertTo320Height = false;
|
||||
public boolean preventLeafDecay = true;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.engine.object.IrisRange;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.format.C;
|
||||
@@ -61,13 +62,12 @@ public class ServerConfigurator {
|
||||
long tt = f.getLong("settings.timeout-time");
|
||||
|
||||
if (tt < TimeUnit.MINUTES.toSeconds(5)) {
|
||||
Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + TimeUnit.MINUTES.toSeconds(5) + " (5 minutes)");
|
||||
Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + TimeUnit.MINUTES.toSeconds(20) + " (5 minutes)");
|
||||
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
||||
f.set("settings.timeout-time", TimeUnit.MINUTES.toSeconds(5));
|
||||
f.save(spigotConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException {
|
||||
File spigotConfig = new File("config/paper-global.yml");
|
||||
FileConfiguration f = new YamlConfiguration();
|
||||
@@ -75,7 +75,7 @@ public class ServerConfigurator {
|
||||
long tt = f.getLong("watchdog.early-warning-delay");
|
||||
|
||||
if (tt < TimeUnit.MINUTES.toMillis(3)) {
|
||||
Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + TimeUnit.MINUTES.toMillis(3) + " (3 minutes)");
|
||||
Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + TimeUnit.MINUTES.toMillis(15) + " (3 minutes)");
|
||||
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
||||
f.set("watchdog.early-warning-delay", TimeUnit.MINUTES.toMillis(3));
|
||||
f.save(spigotConfig);
|
||||
@@ -84,7 +84,7 @@ public class ServerConfigurator {
|
||||
|
||||
private static List<File> getDatapacksFolder() {
|
||||
if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) {
|
||||
return new KList<File>().qadd(new File(IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
|
||||
return new KList<File>().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks"));
|
||||
}
|
||||
KList<File> worlds = new KList<>();
|
||||
Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks")));
|
||||
@@ -95,6 +95,29 @@ public class ServerConfigurator {
|
||||
public static void installDataPacks(boolean fullInstall) {
|
||||
Iris.info("Checking Data Packs...");
|
||||
File packs = new File("plugins/Iris/packs");
|
||||
double ultimateMaxHeight = 0;
|
||||
double ultimateMinHeight = 0;
|
||||
if (packs.exists() && packs.isDirectory()) {
|
||||
for (File pack : packs.listFiles()) {
|
||||
IrisData data = IrisData.get(pack);
|
||||
if (pack.isDirectory()) {
|
||||
File dimensionsFolder = new File(pack, "dimensions");
|
||||
if (dimensionsFolder.exists() && dimensionsFolder.isDirectory()) {
|
||||
for (File file : dimensionsFolder.listFiles()) {
|
||||
if (file.isFile() && file.getName().endsWith(".json")) {
|
||||
IrisDimension dim = data.getDimensionLoader().load(file.getName().split("\\Q.\\E")[0]);
|
||||
if (ultimateMaxHeight < dim.getDimensionHeight().getMax()) {
|
||||
ultimateMaxHeight = dim.getDimensionHeight().getMax();
|
||||
}
|
||||
if (ultimateMinHeight > dim.getDimensionHeight().getMin()) {
|
||||
ultimateMinHeight = dim.getDimensionHeight().getMin();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (packs.exists()) {
|
||||
for (File i : packs.listFiles()) {
|
||||
@@ -114,7 +137,7 @@ public class ServerConfigurator {
|
||||
|
||||
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
||||
for (File dpack : getDatapacksFolder()) {
|
||||
dim.installDataPack(() -> data, dpack);
|
||||
dim.installDataPack(() -> data, dpack, ultimateMaxHeight, ultimateMinHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.pregenerator.DeepSearchPregenerator;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.data.Dimension;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@Decree(name = "DeepSearch", aliases = "search", description = "Pregenerate your Iris worlds!")
|
||||
public class CommandDeepSearch implements DecreeExecutor {
|
||||
public String worldName;
|
||||
@Decree(description = "DeepSearch a world")
|
||||
public void start(
|
||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||
int radius,
|
||||
@Param(description = "The world to pregen", contextual = true)
|
||||
World world,
|
||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||
Vector center
|
||||
) {
|
||||
|
||||
worldName = world.getName();
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File TurboFile = new File(worldDirectory, "DeepSearch.json");
|
||||
if (TurboFile.exists()) {
|
||||
if (DeepSearchPregenerator.getInstance() != null) {
|
||||
sender().sendMessage(C.BLUE + "DeepSearch is already in progress");
|
||||
Iris.info(C.YELLOW + "DeepSearch is already in progress");
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
TurboFile.delete();
|
||||
} catch (Exception e){
|
||||
Iris.error("Failed to delete the old instance file of DeepSearch!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (sender().isPlayer() && access() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||
}
|
||||
|
||||
DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder()
|
||||
.world(world)
|
||||
.radiusBlocks(radius)
|
||||
.position(0)
|
||||
.build();
|
||||
|
||||
File SearchGenFile = new File(worldDirectory, "DeepSearch.json");
|
||||
DeepSearchPregenerator pregenerator = new DeepSearchPregenerator(DeepSearchJob, SearchGenFile);
|
||||
pregenerator.start();
|
||||
|
||||
String msg = C.GREEN + "DeepSearch started in " + C.GOLD + worldName + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
||||
sender().sendMessage(msg);
|
||||
Iris.info(msg);
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage(C.RED + "Epic fail. See console.");
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Stop the active DeepSearch task", aliases = "x")
|
||||
public void stop(@Param(aliases = "world", description = "The world to pause") World world) throws IOException {
|
||||
DeepSearchPregenerator DeepSearchInstance = DeepSearchPregenerator.getInstance();
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File turboFile = new File(worldDirectory, "DeepSearch.json");
|
||||
|
||||
if (DeepSearchInstance != null) {
|
||||
DeepSearchInstance.shutdownInstance(world);
|
||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
||||
} else if (turboFile.exists() && turboFile.delete()) {
|
||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
||||
} else if (turboFile.exists()) {
|
||||
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
|
||||
public void pause(
|
||||
@Param(aliases = "world", description = "The world to pause")
|
||||
World world
|
||||
) {
|
||||
if (TurboPregenerator.getInstance() != null) {
|
||||
TurboPregenerator.setPausedTurbo(world);
|
||||
sender().sendMessage(C.GREEN + "Paused/unpaused Turbo Pregen, now: " + (TurboPregenerator.isPausedTurbo(world) ? "Paused" : "Running") + ".");
|
||||
} else {
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File TurboFile = new File(worldDirectory, "DeepSearch.json");
|
||||
if (TurboFile.exists()){
|
||||
TurboPregenerator.loadTurboGenerator(world.getName());
|
||||
sender().sendMessage(C.YELLOW + "Started DeepSearch back up!");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active DeepSearch tasks to pause/unpause.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.core.service.IrisEngineSVC;
|
||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisCave;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.engine.object.IrisEntity;
|
||||
import com.volmit.iris.util.data.Dimension;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||
import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.mantle.TectonicPlate;
|
||||
import com.volmit.iris.util.math.Vector3d;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import io.lumine.mythic.bukkit.adapters.BukkitEntity;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import net.jpountz.lz4.LZ4FrameInputStream;
|
||||
import net.jpountz.lz4.LZ4FrameOutputStream;
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
@Decree(name = "Developer", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
|
||||
public class CommandDeveloper implements DecreeExecutor {
|
||||
private CommandTurboPregen turboPregen;
|
||||
|
||||
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
|
||||
public void EngineStatus() {
|
||||
List<World> IrisWorlds = new ArrayList<>();
|
||||
int TotalLoadedChunks = 0;
|
||||
int TotalQueuedTectonicPlates = 0;
|
||||
int TotalNotQueuedTectonicPlates = 0;
|
||||
int TotalTectonicPlates = 0;
|
||||
|
||||
long lowestUnloadDuration = 0;
|
||||
long highestUnloadDuration = 0;
|
||||
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
try {
|
||||
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||
IrisWorlds.add(world);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no
|
||||
}
|
||||
}
|
||||
|
||||
for (World world : IrisWorlds) {
|
||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||
TotalQueuedTectonicPlates += (int) engine.getMantle().getToUnload();
|
||||
TotalNotQueuedTectonicPlates += (int) engine.getMantle().getNotQueuedLoadedRegions();
|
||||
TotalTectonicPlates += engine.getMantle().getLoadedRegionCount();
|
||||
if (highestUnloadDuration <= (long) engine.getMantle().getTectonicDuration()) {
|
||||
highestUnloadDuration = (long) engine.getMantle().getTectonicDuration();
|
||||
}
|
||||
if (lowestUnloadDuration >= (long) engine.getMantle().getTectonicDuration()) {
|
||||
lowestUnloadDuration = (long) engine.getMantle().getTectonicDuration();
|
||||
}
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
if (chunk.isLoaded()) {
|
||||
TotalLoadedChunks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Iris.info("-------------------------");
|
||||
Iris.info(C.DARK_PURPLE + "Engine Status");
|
||||
Iris.info(C.DARK_PURPLE + "Total Loaded Chunks: " + C.LIGHT_PURPLE + TotalLoadedChunks);
|
||||
Iris.info(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + IrisEngineSVC.getTectonicLimit());
|
||||
Iris.info(C.DARK_PURPLE + "Tectonic Total Plates: " + C.LIGHT_PURPLE + TotalTectonicPlates);
|
||||
Iris.info(C.DARK_PURPLE + "Tectonic Active Plates: " + C.LIGHT_PURPLE + TotalNotQueuedTectonicPlates);
|
||||
Iris.info(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + TotalQueuedTectonicPlates);
|
||||
Iris.info(C.DARK_PURPLE + "Lowest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(lowestUnloadDuration));
|
||||
Iris.info(C.DARK_PURPLE + "Highest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(highestUnloadDuration));
|
||||
Iris.info(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize()));
|
||||
Iris.info("-------------------------");
|
||||
}
|
||||
|
||||
@Decree(description = "Test")
|
||||
public void benchmarkMantle(
|
||||
@Param(description = "The world to bench", aliases = {"world"})
|
||||
World world
|
||||
) throws IOException, ClassNotFoundException {
|
||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||
int maxHeight = engine.getTarget().getHeight();
|
||||
File folder = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
int c = 0;
|
||||
//MCAUtil.read()
|
||||
|
||||
File tectonicplates = new File(folder, "mantle");
|
||||
for (File i : Objects.requireNonNull(tectonicplates.listFiles())) {
|
||||
TectonicPlate.read(maxHeight, i);
|
||||
c++;
|
||||
Iris.info("Loaded count: " + c );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Decree(description = "Test")
|
||||
public void packBenchmark(
|
||||
@Param(description = "The pack to bench", aliases = {"pack"})
|
||||
IrisDimension dimension
|
||||
) {
|
||||
Iris.info("test");
|
||||
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1);
|
||||
|
||||
}
|
||||
|
||||
@Decree(description = "test")
|
||||
public void test() throws NoSuchFieldException, IllegalAccessException {
|
||||
IrisEngineSVC.instance.engineStatus();
|
||||
|
||||
}
|
||||
|
||||
@Decree(description = "UnloadChunks for good reasons.")
|
||||
public void unloadchunks() {
|
||||
List<World> IrisWorlds = new ArrayList<>();
|
||||
int chunksUnloaded = 0;
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
try {
|
||||
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||
IrisWorlds.add(world);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no
|
||||
}
|
||||
}
|
||||
|
||||
for (World world : IrisWorlds) {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
if (chunk.isLoaded()) {
|
||||
chunk.unload();
|
||||
chunksUnloaded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Iris.info(C.IRIS + "Chunks Unloaded: " + chunksUnloaded);
|
||||
|
||||
}
|
||||
|
||||
@Decree(description = "Test", aliases = {"ip"})
|
||||
public void network() {
|
||||
try {
|
||||
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
for (NetworkInterface ni : Collections.list(networkInterfaces)) {
|
||||
Iris.info("Display Name: %s", ni.getDisplayName());
|
||||
Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
|
||||
for (InetAddress ia : Collections.list(inetAddresses)) {
|
||||
Iris.info("IP: %s", ia.getHostAddress());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Test the compression algorithms")
|
||||
public void compression(
|
||||
@Param(description = "base IrisWorld") World world,
|
||||
@Param(description = "raw TectonicPlate File") String path,
|
||||
@Param(description = "Algorithm to Test") String algorithm,
|
||||
@Param(description = "Amount of Tests") int amount) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", Bukkit.getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(path);
|
||||
if (!file.exists()) return;
|
||||
|
||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||
if(engine != null) {
|
||||
int height = engine.getTarget().getHeight();
|
||||
ExecutorService service = Executors.newFixedThreadPool(1);
|
||||
VolmitSender sender = sender();
|
||||
service.submit(() -> {
|
||||
try {
|
||||
DataInputStream raw = new DataInputStream(new FileInputStream(file));
|
||||
TectonicPlate plate = new TectonicPlate(height, raw);
|
||||
raw.close();
|
||||
|
||||
double d1 = 0;
|
||||
double d2 = 0;
|
||||
long size = 0;
|
||||
File folder = new File("tmp");
|
||||
folder.mkdirs();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
File tmp = new File(folder, RandomStringUtils.randomAlphanumeric(10) + "." + algorithm + ".bin");
|
||||
DataOutputStream dos = createOutput(tmp, algorithm);
|
||||
long start = System.currentTimeMillis();
|
||||
plate.write(dos);
|
||||
dos.close();
|
||||
d1 += System.currentTimeMillis() - start;
|
||||
if (size == 0)
|
||||
size = tmp.length();
|
||||
start = System.currentTimeMillis();
|
||||
DataInputStream din = createInput(tmp, algorithm);
|
||||
new TectonicPlate(height, din);
|
||||
din.close();
|
||||
d2 += System.currentTimeMillis() - start;
|
||||
tmp.delete();
|
||||
}
|
||||
IO.delete(folder);
|
||||
sender.sendMessage(algorithm + " is " + Form.fileSize(size) + " big after compression");
|
||||
sender.sendMessage(algorithm + " Took " + d2/amount + "ms to read");
|
||||
sender.sendMessage(algorithm + " Took " + d1/amount + "ms to write");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
service.shutdown();
|
||||
} else {
|
||||
Iris.info(C.RED + "Engine is null!");
|
||||
}
|
||||
}
|
||||
|
||||
private DataInputStream createInput(File file, String algorithm) throws Throwable {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
|
||||
return new DataInputStream(switch (algorithm) {
|
||||
case "gzip" -> new GZIPInputStream(in);
|
||||
case "lz4f" -> new LZ4FrameInputStream(in);
|
||||
case "lz4b" -> new LZ4BlockInputStream(in);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + algorithm);
|
||||
});
|
||||
}
|
||||
|
||||
private DataOutputStream createOutput(File file, String algorithm) throws Throwable {
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
|
||||
return new DataOutputStream(switch (algorithm) {
|
||||
case "gzip" -> new GZIPOutputStream(out);
|
||||
case "lz4f" -> new LZ4FrameOutputStream(out);
|
||||
case "lz4b" -> new LZ4BlockOutputStream(out);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + algorithm);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ public class CommandFind implements DecreeExecutor {
|
||||
@Decree(description = "Find a biome")
|
||||
public void biome(
|
||||
@Param(description = "The biome to look for")
|
||||
IrisBiome biome
|
||||
IrisBiome biome,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
@@ -43,13 +45,15 @@ public class CommandFind implements DecreeExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
e.gotoBiome(biome, player());
|
||||
e.gotoBiome(biome, player(), teleport);
|
||||
}
|
||||
|
||||
@Decree(description = "Find a region")
|
||||
public void region(
|
||||
@Param(description = "The region to look for")
|
||||
IrisRegion region
|
||||
IrisRegion region,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
@@ -58,13 +62,15 @@ public class CommandFind implements DecreeExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
e.gotoRegion(region, player());
|
||||
e.gotoRegion(region, player(), teleport);
|
||||
}
|
||||
|
||||
@Decree(description = "Find a structure")
|
||||
public void structure(
|
||||
@Param(description = "The structure to look for")
|
||||
IrisJigsawStructure structure
|
||||
IrisJigsawStructure structure,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
@@ -73,13 +79,15 @@ public class CommandFind implements DecreeExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
e.gotoJigsaw(structure, player());
|
||||
e.gotoJigsaw(structure, player(), teleport);
|
||||
}
|
||||
|
||||
@Decree(description = "Find a point of interest.")
|
||||
public void poi(
|
||||
@Param(description = "The type of PoI to look for.")
|
||||
String type
|
||||
String type,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
if (e == null) {
|
||||
@@ -87,13 +95,15 @@ public class CommandFind implements DecreeExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
e.gotoPOI(type, player());
|
||||
e.gotoPOI(type, player(), teleport);
|
||||
}
|
||||
|
||||
@Decree(description = "Find an object")
|
||||
public void object(
|
||||
@Param(description = "The object to look for", customHandler = ObjectHandler.class)
|
||||
String object
|
||||
String object,
|
||||
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||
boolean teleport
|
||||
) {
|
||||
Engine e = engine();
|
||||
|
||||
@@ -102,6 +112,6 @@ public class CommandFind implements DecreeExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
e.gotoObject(object, player());
|
||||
e.gotoObject(object, player(), teleport);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,627 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.core.tools.IrisBenchmarking;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.core.safeguard.UtilsSFG;
|
||||
import com.volmit.iris.engine.object.IrisWorld;
|
||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||
import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.decree.specialhandlers.NullablePlayerHandler;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.Console;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.volmit.iris.Iris.service;
|
||||
import static com.volmit.iris.core.service.EditSVC.deletingWorld;
|
||||
import static com.volmit.iris.core.tools.IrisBenchmarking.inProgress;
|
||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode;
|
||||
import static com.volmit.iris.core.safeguard.ServerBootSFG.incompatibilities;
|
||||
import static org.bukkit.Bukkit.getServer;
|
||||
|
||||
@Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command")
|
||||
public class CommandIris implements DecreeExecutor {
|
||||
private CommandStudio studio;
|
||||
private CommandPregen pregen;
|
||||
private CommandLazyPregen lazyPregen;
|
||||
private CommandSettings settings;
|
||||
private CommandObject object;
|
||||
private CommandJigsaw jigsaw;
|
||||
private CommandWhat what;
|
||||
private CommandEdit edit;
|
||||
private CommandFind find;
|
||||
private CommandDeveloper developer;
|
||||
public static boolean worldCreation = false;
|
||||
String WorldToLoad;
|
||||
String WorldEngine;
|
||||
String worldNameToCheck = "YourWorldName";
|
||||
VolmitSender sender = Iris.getSender();
|
||||
|
||||
@Decree(description = "Create a new world", aliases = {"+", "c"})
|
||||
public void create(
|
||||
@Param(aliases = "world-name", description = "The name of the world to create")
|
||||
String name,
|
||||
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
|
||||
IrisDimension type,
|
||||
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
||||
long seed
|
||||
) {
|
||||
if(sender() instanceof Player) {
|
||||
if (incompatibilities.get("Multiverse-Core")) {
|
||||
sender().sendMessage(C.RED + "Your server has an incompatibility that may corrupt all worlds on the server if not handled properly.");
|
||||
sender().sendMessage(C.RED + "it is strongly advised for you to take action. see log for full detail");
|
||||
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||
sender().sendMessage(C.RED + "Command ran: /iris create");
|
||||
sender().sendMessage(C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||
}
|
||||
if (unstablemode && !incompatibilities.get("Multiverse-Core")) {
|
||||
sender().sendMessage(C.RED + "Your server is experiencing an incompatibility with the Iris plugin.");
|
||||
sender().sendMessage(C.RED + "Please rectify this problem to avoid further complications.");
|
||||
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||
sender().sendMessage(C.RED + "Command ran: /iris create");
|
||||
sender().sendMessage(C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
if (name.equals("iris")) {
|
||||
sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds.");
|
||||
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||
return;
|
||||
}
|
||||
if (name.equals("Benchmark")) {
|
||||
sender().sendMessage(C.RED + "You cannot use the world name \"Benchmark\" for creating worlds as Iris uses this directory for Benchmarking Packs.");
|
||||
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (new File(Bukkit.getWorldContainer(), name).exists()) {
|
||||
sender().sendMessage(C.RED + "That folder already exists!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
worldCreation = true;
|
||||
IrisToolbelt.createWorld()
|
||||
.dimension(type.getLoadKey())
|
||||
.name(name)
|
||||
.seed(seed)
|
||||
.sender(sender())
|
||||
.studio(false)
|
||||
.create();
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
||||
Iris.error("Exception raised during world creation: " + e.getMessage());
|
||||
Iris.reportError(e);
|
||||
worldCreation = false;
|
||||
return;
|
||||
}
|
||||
worldCreation = false;
|
||||
sender().sendMessage(C.GREEN + "Successfully created your world!");
|
||||
}
|
||||
|
||||
@Decree(description = "Teleport to another world", aliases = {"tp"}, sync = true)
|
||||
public void teleport(
|
||||
@Param(description = "World to teleport to")
|
||||
World world,
|
||||
@Param(description = "Player to teleport", defaultValue = "---", customHandler = NullablePlayerHandler.class)
|
||||
Player player
|
||||
) {
|
||||
if (player == null && sender().isPlayer())
|
||||
player = sender().player();
|
||||
|
||||
final Player target = player;
|
||||
if (target == null) {
|
||||
sender().sendMessage(C.RED + "The specified player does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
target.teleport(world.getSpawnLocation());
|
||||
new VolmitSender(target).sendMessage(C.GREEN + "You have been teleported to " + world.getName() + ".");
|
||||
}
|
||||
}.runTask(Iris.instance);
|
||||
}
|
||||
|
||||
@Decree(description = "Print version information")
|
||||
public void version() {
|
||||
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software");
|
||||
}
|
||||
|
||||
//todo Move to React
|
||||
@Decree(description = "Benchmark your server", origin = DecreeOrigin.CONSOLE)
|
||||
public void serverbenchmark() throws InterruptedException {
|
||||
if(!inProgress) {
|
||||
IrisBenchmarking.runBenchmark();
|
||||
} else {
|
||||
Iris.info(C.RED + "Benchmark already is in progress.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/todo
|
||||
@Decree(description = "Benchmark a pack", origin = DecreeOrigin.CONSOLE)
|
||||
public void packbenchmark(
|
||||
@Param(description = "Dimension to benchmark")
|
||||
IrisDimension type
|
||||
) throws InterruptedException {
|
||||
|
||||
BenchDimension = type.getLoadKey();
|
||||
|
||||
IrisPackBenchmarking.runBenchmark();
|
||||
} */
|
||||
|
||||
@Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER)
|
||||
public void height() {
|
||||
if (sender().isPlayer()) {
|
||||
sender().sendMessage(C.GREEN + "" + sender().player().getWorld().getMinHeight() + " to " + sender().player().getWorld().getMaxHeight());
|
||||
sender().sendMessage(C.GREEN + "Total Height: " + (sender().player().getWorld().getMaxHeight() - sender().player().getWorld().getMinHeight()));
|
||||
} else {
|
||||
World mainWorld = getServer().getWorlds().get(0);
|
||||
Iris.info(C.GREEN + "" + mainWorld.getMinHeight() + " to " + mainWorld.getMaxHeight());
|
||||
Iris.info(C.GREEN + "Total Height: " + (mainWorld.getMaxHeight() - mainWorld.getMinHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "QOL command to open a overworld studio world.", sync = true)
|
||||
public void so() {
|
||||
sender().sendMessage(C.GREEN + "Opening studio for the \"Overworld\" pack (seed: 1337)");
|
||||
Iris.service(StudioSVC.class).open(sender(), 1337, "overworld");
|
||||
}
|
||||
|
||||
@Decree(description = "Check if iris has access to that specific world")
|
||||
public void hasAccess(
|
||||
@Param(description = "The world to access", aliases = {"world"})
|
||||
World world
|
||||
) {
|
||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||
if (engine != null) {
|
||||
sender().sendMessage("Access granted successfully.");
|
||||
} else {
|
||||
sender().sendMessage(C.RED + "Failed to grant access.");
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "All Iris Worlds on the server.", aliases = {"worlds"})
|
||||
public void irisworlds() {
|
||||
List<World> IrisWorlds = new ArrayList<>();
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
try {
|
||||
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||
IrisWorlds.add(world);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no
|
||||
}
|
||||
}
|
||||
if (sender().isPlayer()) {
|
||||
sender.sendMessage(C.IRIS + "Iris Worlds:");
|
||||
for (World world : IrisWorlds) {
|
||||
sender.sendMessage(C.GREEN + "- " + world.getName());
|
||||
}
|
||||
} else {
|
||||
Iris.info(C.IRIS + "Iris Worlds:");
|
||||
for (World world : IrisWorlds) {
|
||||
sender.sendMessage(C.GREEN + "- " + world.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Remove an Iris world", aliases = {"del", "rm", "delete"}, sync = true)
|
||||
public void remove(
|
||||
@Param(description = "The world to remove")
|
||||
World world,
|
||||
@Param(description = "Whether to also remove the folder (if set to false, just does not load the world)", defaultValue = "true")
|
||||
boolean delete
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
||||
try {
|
||||
if (IrisToolbelt.removeWorld(world)) {
|
||||
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "Looks like the world was already removed from bukkit.yml");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
sender().sendMessage(C.RED + "Failed to save bukkit.yml because of " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
IrisToolbelt.evacuate(world, "Deleting world");
|
||||
deletingWorld = true;
|
||||
Bukkit.unloadWorld(world, false);
|
||||
int retries = 12;
|
||||
if (delete) {
|
||||
if (deleteDirectory(world.getWorldFolder())) {
|
||||
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
||||
} else {
|
||||
while(true){
|
||||
if (deleteDirectory(world.getWorldFolder())){
|
||||
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
||||
break;
|
||||
}
|
||||
retries--;
|
||||
if (retries == 0){
|
||||
sender().sendMessage(C.RED + "Failed to remove world folder");
|
||||
break;
|
||||
}
|
||||
J.sleep(3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
deletingWorld = false;
|
||||
}
|
||||
|
||||
public static boolean deleteDirectory(File dir) {
|
||||
if (dir.isDirectory()) {
|
||||
File[] children = dir.listFiles();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
boolean success = deleteDirectory(children[i]);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dir.delete();
|
||||
}
|
||||
|
||||
@Decree(description = "Set aura spins")
|
||||
public void aura(
|
||||
@Param(description = "The h color value", defaultValue = "-20")
|
||||
int h,
|
||||
@Param(description = "The s color value", defaultValue = "7")
|
||||
int s,
|
||||
@Param(description = "The b color value", defaultValue = "8")
|
||||
int b
|
||||
) {
|
||||
IrisSettings.get().getGeneral().setSpinh(h);
|
||||
IrisSettings.get().getGeneral().setSpins(s);
|
||||
IrisSettings.get().getGeneral().setSpinb(b);
|
||||
IrisSettings.get().forceSave();
|
||||
sender().sendMessage("<rainbow>Aura Spins updated to " + h + " " + s + " " + b);
|
||||
}
|
||||
|
||||
@Decree(description = "Bitwise calculations")
|
||||
public void bitwise(
|
||||
@Param(description = "The first value to run calculations on")
|
||||
int value1,
|
||||
@Param(description = "The operator: | & ^ ≺≺ ≻≻ %")
|
||||
String operator,
|
||||
@Param(description = "The second value to run calculations on")
|
||||
int value2
|
||||
) {
|
||||
Integer v = null;
|
||||
switch (operator) {
|
||||
case "|" -> v = value1 | value2;
|
||||
case "&" -> v = value1 & value2;
|
||||
case "^" -> v = value1 ^ value2;
|
||||
case "%" -> v = value1 % value2;
|
||||
case ">>" -> v = value1 >> value2;
|
||||
case "<<" -> v = value1 << value2;
|
||||
}
|
||||
if (v == null) {
|
||||
sender().sendMessage(C.RED + "The operator you entered: (" + operator + ") is invalid!");
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "" + value1 + " " + C.GREEN + operator.replaceAll("<", "≺").replaceAll(">", "≻").replaceAll("%", "%") + " " + C.GREEN + value2 + C.GREEN + " returns " + C.GREEN + v);
|
||||
}
|
||||
|
||||
@Decree(description = "Toggle debug")
|
||||
public void debug(
|
||||
@Param(name = "on", description = "Whether or not debug should be on", defaultValue = "other")
|
||||
Boolean on
|
||||
) {
|
||||
boolean to = on == null ? !IrisSettings.get().getGeneral().isDebug() : on;
|
||||
IrisSettings.get().getGeneral().setDebug(to);
|
||||
IrisSettings.get().forceSave();
|
||||
sender().sendMessage(C.GREEN + "Set debug to: " + to);
|
||||
}
|
||||
|
||||
@Decree(description = "Download a project.", aliases = "dl")
|
||||
public void download(
|
||||
@Param(name = "pack", description = "The pack to download", defaultValue = "overworld", aliases = "project")
|
||||
String pack,
|
||||
@Param(name = "branch", description = "The branch to download from", defaultValue = "main")
|
||||
String branch,
|
||||
@Param(name = "trim", description = "Whether or not to download a trimmed version (do not enable when editing)", defaultValue = "false")
|
||||
boolean trim,
|
||||
@Param(name = "overwrite", description = "Whether or not to overwrite the pack with the downloaded one", aliases = "force", defaultValue = "false")
|
||||
boolean overwrite
|
||||
) {
|
||||
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
|
||||
if (pack.equals("overworld")) {
|
||||
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip";
|
||||
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
|
||||
} else {
|
||||
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Get metrics for your world", aliases = "measure", origin = DecreeOrigin.PLAYER)
|
||||
public void metrics() {
|
||||
if (!IrisToolbelt.isIrisWorld(world())) {
|
||||
sender().sendMessage(C.RED + "You must be in an Iris world");
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Sending metrics...");
|
||||
engine().printMetrics(sender());
|
||||
}
|
||||
|
||||
@Decree(description = "Reload configuration file (this is also done automatically)")
|
||||
public void reload() {
|
||||
IrisSettings.invalidate();
|
||||
IrisSettings.get();
|
||||
sender().sendMessage(C.GREEN + "Hotloaded settings");
|
||||
}
|
||||
|
||||
@Decree(description = "Update the pack of a world (UNSAFE!)", name = "^world", aliases = "update-world")
|
||||
public void updateWorld(
|
||||
@Param(description = "The world to update", contextual = true)
|
||||
World world,
|
||||
@Param(description = "The pack to install into the world", contextual = true, aliases = "dimension")
|
||||
IrisDimension pack,
|
||||
@Param(description = "Make sure to make a backup & read the warnings first!", defaultValue = "false", aliases = "c")
|
||||
boolean confirm,
|
||||
@Param(description = "Should Iris download the pack again for you", defaultValue = "false", name = "fresh-download", aliases = {"fresh", "new"})
|
||||
boolean freshDownload
|
||||
) {
|
||||
if (!confirm) {
|
||||
sender().sendMessage(new String[]{
|
||||
C.RED + "You should always make a backup before using this",
|
||||
C.YELLOW + "Issues caused by this can be, but are not limited to:",
|
||||
C.YELLOW + " - Broken chunks (cut-offs) between old and new chunks (before & after the update)",
|
||||
C.YELLOW + " - Regenerated chunks that do not fit in with the old chunks",
|
||||
C.YELLOW + " - Structures not spawning again when regenerating",
|
||||
C.YELLOW + " - Caves not lining up",
|
||||
C.YELLOW + " - Terrain layers not lining up",
|
||||
C.RED + "Now that you are aware of the risks, and have made a back-up:",
|
||||
C.RED + "/iris ^world " + world.getName() + " " + pack.getLoadKey() + " confirm=true"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
File folder = world.getWorldFolder();
|
||||
folder.mkdirs();
|
||||
|
||||
if (freshDownload) {
|
||||
Iris.service(StudioSVC.class).downloadSearch(sender(), pack.getLoadKey(), false, true);
|
||||
}
|
||||
|
||||
Iris.service(StudioSVC.class).installIntoWorld(sender(), pack.getLoadKey(), folder);
|
||||
}
|
||||
|
||||
@Decree(description = "Unload an Iris World", origin = DecreeOrigin.PLAYER, sync = true)
|
||||
public void unloadWorld(
|
||||
@Param(description = "The world to unload")
|
||||
World world
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Unloading world: " + world.getName());
|
||||
try {
|
||||
IrisToolbelt.evacuate(world);
|
||||
Bukkit.unloadWorld(world, false);
|
||||
sender().sendMessage(C.GREEN + "World unloaded successfully.");
|
||||
} catch (Exception e) {
|
||||
sender().sendMessage(C.RED + "Failed to unload the world: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Load an Iris World", origin = DecreeOrigin.PLAYER, sync = true, aliases = {"import"})
|
||||
public void loadWorld(
|
||||
@Param(description = "The name of the world to load")
|
||||
String world
|
||||
) {
|
||||
World worldloaded = Bukkit.getWorld(world);
|
||||
worldNameToCheck = world;
|
||||
boolean worldExists = doesWorldExist(worldNameToCheck);
|
||||
WorldEngine = world;
|
||||
|
||||
if (!worldExists) {
|
||||
sender().sendMessage(C.YELLOW + world + " Doesnt exist on the server.");
|
||||
return;
|
||||
}
|
||||
WorldToLoad = world;
|
||||
File BUKKIT_YML = new File("bukkit.yml");
|
||||
String pathtodim = world + File.separator +"iris"+File.separator +"pack"+File.separator +"dimensions"+File.separator;
|
||||
File directory = new File(Bukkit.getWorldContainer(), pathtodim);
|
||||
|
||||
String dimension = null;
|
||||
if (directory.exists() && directory.isDirectory()) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isFile()) {
|
||||
String fileName = file.getName();
|
||||
if (fileName.endsWith(".json")) {
|
||||
dimension = fileName.substring(0, fileName.length() - 5);
|
||||
sender().sendMessage(C.BLUE + "Generator: " + dimension);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sender().sendMessage(C.GOLD + world + " is not an iris world.");
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Loading world: " + world);
|
||||
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
|
||||
String gen = "Iris:" + dimension;
|
||||
ConfigurationSection section = yml.contains("worlds") ? yml.getConfigurationSection("worlds") : yml.createSection("worlds");
|
||||
if (!section.contains(world)) {
|
||||
section.createSection(world).set("generator", gen);
|
||||
try {
|
||||
yml.save(BUKKIT_YML);
|
||||
Iris.info("Registered \"" + world + "\" in bukkit.yml");
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to update bukkit.yml!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
checkForBukkitWorlds();
|
||||
sender().sendMessage(C.GREEN + world + " loaded successfully.");
|
||||
}
|
||||
@Decree(description = "Evacuate an iris world", origin = DecreeOrigin.PLAYER, sync = true)
|
||||
public void evacuate(
|
||||
@Param(description = "Evacuate the world")
|
||||
World world
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||
return;
|
||||
}
|
||||
sender().sendMessage(C.GREEN + "Evacuating world" + world.getName());
|
||||
IrisToolbelt.evacuate(world);
|
||||
}
|
||||
|
||||
boolean doesWorldExist(String worldName) {
|
||||
File worldContainer = Bukkit.getWorldContainer();
|
||||
File worldDirectory = new File(worldContainer, worldName);
|
||||
return worldDirectory.exists() && worldDirectory.isDirectory();
|
||||
}
|
||||
private void checkForBukkitWorlds() {
|
||||
FileConfiguration fc = new YamlConfiguration();
|
||||
try {
|
||||
fc.load(new File("bukkit.yml"));
|
||||
ConfigurationSection section = fc.getConfigurationSection("worlds");
|
||||
if (section == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> worldsToLoad = Collections.singletonList(WorldToLoad);
|
||||
|
||||
for (String s : section.getKeys(false)) {
|
||||
if (!worldsToLoad.contains(s)) {
|
||||
continue;
|
||||
}
|
||||
ConfigurationSection entry = section.getConfigurationSection(s);
|
||||
if (!entry.contains("generator", true)) {
|
||||
continue;
|
||||
}
|
||||
String generator = entry.getString("generator");
|
||||
if (generator.startsWith("Iris:")) {
|
||||
generator = generator.split("\\Q:\\E")[1];
|
||||
} else if (generator.equalsIgnoreCase("Iris")) {
|
||||
generator = IrisSettings.get().getGenerator().getDefaultWorldType();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
Iris.info("2 World: %s | Generator: %s", s, generator);
|
||||
if (Bukkit.getWorlds().stream().anyMatch(w -> w.getName().equals(s))) {
|
||||
continue;
|
||||
}
|
||||
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
||||
new WorldCreator(s)
|
||||
.generator(getDefaultWorldGenerator(s, generator))
|
||||
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
||||
.createWorld();
|
||||
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
|
||||
Iris.debug("Default World Generator Called for " + worldName + " using ID: " + id);
|
||||
if (worldName.equals("test")) {
|
||||
try {
|
||||
throw new RuntimeException();
|
||||
} catch (Throwable e) {
|
||||
Iris.info(e.getStackTrace()[1].getClassName());
|
||||
if (e.getStackTrace()[1].getClassName().contains("com.onarandombox.MultiverseCore")) {
|
||||
Iris.debug("MVC Test detected, Quick! Send them the dummy!");
|
||||
return new DummyChunkGenerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
IrisDimension dim;
|
||||
if (id == null || id.isEmpty()) {
|
||||
dim = IrisData.loadAnyDimension(IrisSettings.get().getGenerator().getDefaultWorldType());
|
||||
} else {
|
||||
dim = IrisData.loadAnyDimension(id);
|
||||
}
|
||||
Iris.debug("Generator ID: " + id + " requested by bukkit/plugin");
|
||||
|
||||
if (dim == null) {
|
||||
Iris.warn("Unable to find dimension type " + id + " Looking for online packs...");
|
||||
|
||||
service(StudioSVC.class).downloadSearch(new VolmitSender(Bukkit.getConsoleSender()), id, true);
|
||||
dim = IrisData.loadAnyDimension(id);
|
||||
|
||||
if (dim == null) {
|
||||
throw new RuntimeException("Can't find dimension " + id + "!");
|
||||
} else {
|
||||
Iris.info("Resolved missing dimension, proceeding with generation.");
|
||||
}
|
||||
}
|
||||
Iris.debug("Assuming IrisDimension: " + dim.getName());
|
||||
IrisWorld w = IrisWorld.builder()
|
||||
.name(worldName)
|
||||
.seed(1337)
|
||||
.environment(dim.getEnvironment())
|
||||
.worldFolder(new File(Bukkit.getWorldContainer(), worldName))
|
||||
.minHeight(dim.getMinHeight())
|
||||
.maxHeight(dim.getMaxHeight())
|
||||
.build();
|
||||
Iris.debug("Generator Config: " + w.toString());
|
||||
File ff = new File(w.worldFolder(), "iris/pack");
|
||||
if (!ff.exists() || ff.listFiles().length == 0) {
|
||||
ff.mkdirs();
|
||||
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile());
|
||||
}
|
||||
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@Decree(name = "lazypregen", aliases = "lazy", description = "Pregenerate your Iris worlds!")
|
||||
public class CommandLazyPregen implements DecreeExecutor {
|
||||
public String worldName;
|
||||
@Decree(description = "Pregenerate a world")
|
||||
public void start(
|
||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||
int radius,
|
||||
@Param(description = "The world to pregen", contextual = true)
|
||||
World world,
|
||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||
Vector center,
|
||||
@Param(aliases = "maxcpm", description = "Limit the chunks per minute the pregen will generate", defaultValue = "999999999")
|
||||
int cpm,
|
||||
@Param(aliases = "silent", description = "Silent generation", defaultValue = "false")
|
||||
boolean silent
|
||||
) {
|
||||
|
||||
worldName = world.getName();
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File lazyFile = new File(worldDirectory, "lazygen.json");
|
||||
if (lazyFile.exists()) {
|
||||
sender().sendMessage(C.BLUE + "Lazy pregen is already in progress");
|
||||
Iris.info(C.YELLOW + "Lazy pregen is already in progress");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (sender().isPlayer() && access() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||
}
|
||||
|
||||
LazyPregenerator.LazyPregenJob pregenJob = LazyPregenerator.LazyPregenJob.builder()
|
||||
.world(worldName)
|
||||
.healingPosition(0)
|
||||
.healing(false)
|
||||
.chunksPerMinute(cpm)
|
||||
.radiusBlocks(radius)
|
||||
.position(0)
|
||||
.silent(silent)
|
||||
.build();
|
||||
|
||||
File lazyGenFile = new File(worldDirectory, "lazygen.json");
|
||||
LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, lazyGenFile);
|
||||
pregenerator.start();
|
||||
|
||||
String msg = C.GREEN + "LazyPregen started in " + C.GOLD + worldName + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
||||
sender().sendMessage(msg);
|
||||
Iris.info(msg);
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage(C.RED + "Epic fail. See console.");
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
||||
public void stop(
|
||||
@Param(aliases = "world", description = "The world to pause")
|
||||
World world
|
||||
) throws IOException {
|
||||
if (LazyPregenerator.getInstance() != null) {
|
||||
LazyPregenerator.getInstance().shutdownInstance(world);
|
||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed lazygen instance for " + world.getName());
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
|
||||
public void pause(
|
||||
@Param(aliases = "world", description = "The world to pause")
|
||||
World world
|
||||
) {
|
||||
if (LazyPregenerator.getInstance() != null) {
|
||||
LazyPregenerator.getInstance().setPausedLazy(world);
|
||||
sender().sendMessage(C.GREEN + "Paused/unpaused Lazy Pregen, now: " + (LazyPregenerator.getInstance().isPausedLazy(world) ? "Paused" : "Running") + ".");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active Lazy Pregen tasks to pause/unpause.");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
||||
public class CommandObject implements DecreeExecutor {
|
||||
@@ -167,7 +166,7 @@ public class CommandObject implements DecreeExecutor {
|
||||
}
|
||||
|
||||
List<Material> sortedMatsList = amounts.keySet().stream().map(BlockData::getMaterial)
|
||||
.sorted().collect(Collectors.toList());
|
||||
.sorted().toList();
|
||||
Set<Material> sortedMats = new TreeSet<>(Comparator.comparingInt(materials::get).reversed());
|
||||
sortedMats.addAll(sortedMatsList);
|
||||
sender().sendMessage("== Blocks in object ==");
|
||||
@@ -216,6 +215,9 @@ public class CommandObject implements DecreeExecutor {
|
||||
|
||||
|
||||
Location[] b = WandSVC.getCuboid(player());
|
||||
if (b == null) {
|
||||
return;
|
||||
}
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
@@ -242,6 +244,9 @@ public class CommandObject implements DecreeExecutor {
|
||||
if (WandSVC.isHoldingWand(player())) {
|
||||
Location[] g = WandSVC.getCuboid(player());
|
||||
|
||||
if (g == null) {
|
||||
return;
|
||||
}
|
||||
if (!here) {
|
||||
// TODO: WARNING HEIGHT
|
||||
g[1] = player().getTargetBlock(null, 256).getLocation().clone();
|
||||
@@ -265,6 +270,10 @@ public class CommandObject implements DecreeExecutor {
|
||||
if (WandSVC.isHoldingIrisWand(player())) {
|
||||
Location[] g = WandSVC.getCuboid(player());
|
||||
|
||||
if (g == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!here) {
|
||||
// TODO: WARNING HEIGHT
|
||||
g[0] = player().getTargetBlock(null, 256).getLocation().clone();
|
||||
@@ -332,7 +341,7 @@ public class CommandObject implements DecreeExecutor {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sender().sendMessage("Placed " + object);
|
||||
sender().sendMessage(C.IRIS + "Placed " + object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,6 +392,9 @@ public class CommandObject implements DecreeExecutor {
|
||||
Location a1 = b[0].clone();
|
||||
Location a2 = b[1].clone();
|
||||
Direction d = Direction.closest(player().getLocation().getDirection()).reverse();
|
||||
if (d == null) {
|
||||
return; // HOW DID THIS HAPPEN
|
||||
}
|
||||
a1.add(d.toVector().multiply(amount));
|
||||
a2.add(d.toVector().multiply(amount));
|
||||
Cuboid cursor = new Cuboid(a1, a2);
|
||||
@@ -401,7 +413,7 @@ public class CommandObject implements DecreeExecutor {
|
||||
ObjectSVC service = Iris.service(ObjectSVC.class);
|
||||
int actualReverts = Math.min(service.getUndos().size(), amount);
|
||||
service.revertChanges(actualReverts);
|
||||
sender().sendMessage("Reverted " + actualReverts + " pastes!");
|
||||
sender().sendMessage(C.BLUE + "Reverted " + actualReverts + C.BLUE +" pastes!");
|
||||
}
|
||||
|
||||
@Decree(description = "Gets an object wand and grabs the current WorldEdit selection.", aliases = "we", origin = DecreeOrigin.PLAYER, studio = true)
|
||||
@@ -19,7 +19,9 @@
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
@@ -27,9 +29,12 @@ import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
||||
public class CommandPregen implements DecreeExecutor {
|
||||
@Decree(description = "Pregenerate a world")
|
||||
@@ -40,7 +45,7 @@ public class CommandPregen implements DecreeExecutor {
|
||||
World world,
|
||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||
Vector center
|
||||
) {
|
||||
) {
|
||||
try {
|
||||
if (sender().isPlayer() && access() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||
@@ -50,7 +55,8 @@ public class CommandPregen implements DecreeExecutor {
|
||||
int w = (radius >> 9 + 1) * 2;
|
||||
IrisToolbelt.pregenerate(PregenTask
|
||||
.builder()
|
||||
.center(new Position2(center))
|
||||
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
|
||||
.gui(true)
|
||||
.width(w)
|
||||
.height(w)
|
||||
.build(), world);
|
||||
@@ -67,7 +73,7 @@ public class CommandPregen implements DecreeExecutor {
|
||||
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
||||
public void stop() {
|
||||
if (PregeneratorJob.shutdownInstance()) {
|
||||
sender().sendMessage(C.GREEN + "Stopped pregeneration task");
|
||||
Iris.info( C.BLUE + "Finishing up mca region...");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||
}
|
||||
@@ -26,12 +26,15 @@ import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.project.IrisProject;
|
||||
import com.volmit.iris.core.service.ConversionSVC;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.core.tools.IrisConverter;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.*;
|
||||
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.decree.DecreeContext;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||
import com.volmit.iris.util.decree.annotations.Decree;
|
||||
@@ -45,11 +48,17 @@ import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.json.JSONArray;
|
||||
import com.volmit.iris.util.json.JSONObject;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.O;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import com.volmit.iris.util.scheduling.jobs.QueueJob;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
@@ -67,12 +76,16 @@ import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
||||
public class CommandStudio implements DecreeExecutor {
|
||||
private CommandFind find;
|
||||
private CommandEdit edit;
|
||||
private CommandDeepSearch deepSearch;
|
||||
|
||||
public static String hrf(Duration duration) {
|
||||
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
||||
@@ -143,12 +156,83 @@ public class CommandStudio implements DecreeExecutor {
|
||||
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
||||
}
|
||||
|
||||
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
|
||||
public void regen(
|
||||
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
|
||||
int radius
|
||||
) {
|
||||
if (IrisToolbelt.isIrisWorld(player().getWorld())) {
|
||||
VolmitSender sender = sender();
|
||||
J.a(() -> {
|
||||
DecreeContext.touch(sender);
|
||||
PlatformChunkGenerator plat = IrisToolbelt.access(player().getWorld());
|
||||
Engine engine = plat.getEngine();
|
||||
try {
|
||||
Chunk cx = player().getLocation().getChunk();
|
||||
KList<Runnable> js = new KList<>();
|
||||
BurstExecutor b = MultiBurst.burst.burst();
|
||||
b.setMulticore(false);
|
||||
int rad = engine.getMantle().getRealRadius();
|
||||
for (int i = -(radius + rad); i <= radius + rad; i++) {
|
||||
for (int j = -(radius + rad); j <= radius + rad; j++) {
|
||||
engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = -radius; i <= radius; i++) {
|
||||
for (int j = -radius; j <= radius; j++) {
|
||||
int finalJ = j;
|
||||
int finalI = i;
|
||||
b.queue(() -> plat.injectChunkReplacement(player().getWorld(), finalI + cx.getX(), finalJ + cx.getZ(), (f) -> {
|
||||
synchronized (js) {
|
||||
js.add(f);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
b.complete();
|
||||
sender().sendMessage(C.GREEN + "Regenerating " + Form.f(js.size()) + " Sections");
|
||||
QueueJob<Runnable> r = new QueueJob<>() {
|
||||
final KList<Future<?>> futures = new KList<>();
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
futures.add(J.sfut(runnable));
|
||||
|
||||
if (futures.size() > 64) {
|
||||
while (futures.isNotEmpty()) {
|
||||
try {
|
||||
futures.remove(0).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Regenerating";
|
||||
}
|
||||
};
|
||||
r.queue(js);
|
||||
r.execute(sender());
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage("Unable to parse view-distance");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
sender().sendMessage(C.RED + "You must be in an Iris World to use regen!");
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Convert objects in the \"convert\" folder")
|
||||
public void convert() {
|
||||
Iris.service(ConversionSVC.class).check(sender());
|
||||
//IrisConverter.convertSchematics(sender());
|
||||
}
|
||||
|
||||
|
||||
@Decree(description = "Execute a script", aliases = "run", origin = DecreeOrigin.PLAYER)
|
||||
public void execute(
|
||||
@Param(description = "The script to run")
|
||||
@@ -281,6 +365,7 @@ public class CommandStudio implements DecreeExecutor {
|
||||
@Param(description = "The dimension to profile", contextual = true, defaultValue = "default")
|
||||
IrisDimension dimension
|
||||
) {
|
||||
// Todo: Make this more accurate
|
||||
File pack = dimension.getLoadFile().getParentFile().getParentFile();
|
||||
File report = Iris.instance.getDataFile("profile.txt");
|
||||
IrisProject project = new IrisProject(pack);
|
||||
@@ -464,19 +549,16 @@ public class CommandStudio implements DecreeExecutor {
|
||||
sender().sendMessage(C.GREEN + "Done! " + report.getPath());
|
||||
}
|
||||
|
||||
@Decree(description = "Summon an Iris Entity", origin = DecreeOrigin.PLAYER)
|
||||
public void summon(
|
||||
@Param(description = "The Iris Entity to spawn")
|
||||
@Decree(description = "Spawn an Iris entity", aliases = "summon", origin = DecreeOrigin.PLAYER)
|
||||
public void spawn(
|
||||
@Param(description = "The entity to spawn")
|
||||
IrisEntity entity,
|
||||
@Param(description = "The location at which to spawn the entity", defaultValue = "self")
|
||||
@Param(description = "The location to spawn the entity at", contextual = true)
|
||||
Vector location
|
||||
) {
|
||||
if (!sender().isPlayer()) {
|
||||
sender().sendMessage(C.RED + "Players only (this is a config error. Ask support to add DecreeOrigin.PLAYER to the command you tried to run)");
|
||||
return;
|
||||
if (!IrisToolbelt.isIrisWorld(player().getWorld())) {
|
||||
sender().sendMessage(C.RED + "You have to be in an Iris world to spawn entities properly. Trying to spawn the best we can do.");
|
||||
}
|
||||
|
||||
sender().sendMessage(C.GREEN + "Spawning entity");
|
||||
entity.spawn(engine(), new Location(world(), location.getX(), location.getY(), location.getZ()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.commands;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
||||
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@Decree(name = "turbopregen", aliases = "turbo", description = "Pregenerate your Iris worlds!")
|
||||
public class CommandTurboPregen implements DecreeExecutor {
|
||||
public String worldName;
|
||||
@Decree(description = "Pregenerate a world")
|
||||
public void start(
|
||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
||||
int radius,
|
||||
@Param(description = "The world to pregen", contextual = true)
|
||||
World world,
|
||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||
Vector center
|
||||
) {
|
||||
|
||||
worldName = world.getName();
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File TurboFile = new File(worldDirectory, "turbogen.json");
|
||||
if (TurboFile.exists()) {
|
||||
if (TurboPregenerator.getInstance() != null) {
|
||||
sender().sendMessage(C.BLUE + "Turbo pregen is already in progress");
|
||||
Iris.info(C.YELLOW + "Turbo pregen is already in progress");
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
TurboFile.delete();
|
||||
} catch (Exception e){
|
||||
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (sender().isPlayer() && access() == null) {
|
||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
||||
}
|
||||
|
||||
TurboPregenerator.TurboPregenJob pregenJob = TurboPregenerator.TurboPregenJob.builder()
|
||||
.world(worldName)
|
||||
.radiusBlocks(radius)
|
||||
.position(0)
|
||||
.build();
|
||||
|
||||
File TurboGenFile = new File(worldDirectory, "turbogen.json");
|
||||
TurboPregenerator pregenerator = new TurboPregenerator(pregenJob, TurboGenFile);
|
||||
pregenerator.start();
|
||||
|
||||
String msg = C.GREEN + "TurboPregen started in " + C.GOLD + worldName + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
||||
sender().sendMessage(msg);
|
||||
Iris.info(msg);
|
||||
} catch (Throwable e) {
|
||||
sender().sendMessage(C.RED + "Epic fail. See console.");
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
||||
public void stop(@Param(aliases = "world", description = "The world to pause") World world) throws IOException {
|
||||
TurboPregenerator turboPregenInstance = TurboPregenerator.getInstance();
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File turboFile = new File(worldDirectory, "turbogen.json");
|
||||
|
||||
if (turboPregenInstance != null) {
|
||||
turboPregenInstance.shutdownInstance(world);
|
||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
||||
} else if (turboFile.exists() && turboFile.delete()) {
|
||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
||||
} else if (turboFile.exists()) {
|
||||
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
|
||||
public void pause(
|
||||
@Param(aliases = "world", description = "The world to pause")
|
||||
World world
|
||||
) {
|
||||
if (TurboPregenerator.getInstance() != null) {
|
||||
TurboPregenerator.setPausedTurbo(world);
|
||||
sender().sendMessage(C.GREEN + "Paused/unpaused Turbo Pregen, now: " + (TurboPregenerator.isPausedTurbo(world) ? "Paused" : "Running") + ".");
|
||||
} else {
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File TurboFile = new File(worldDirectory, "turbogen.json");
|
||||
if (TurboFile.exists()){
|
||||
TurboPregenerator.loadTurboGenerator(world.getName());
|
||||
sender().sendMessage(C.YELLOW + "Started Turbo Pregen back up!");
|
||||
} else {
|
||||
sender().sendMessage(C.YELLOW + "No active Turbo Pregen tasks to pause/unpause.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,9 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.edit.BlockSignal;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisRegion;
|
||||
import com.volmit.iris.util.data.B;
|
||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||
@@ -37,6 +39,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Decree(name = "what", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris What?")
|
||||
@@ -82,6 +85,19 @@ public class CommandWhat implements DecreeExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "What region am i in?", origin = DecreeOrigin.PLAYER)
|
||||
public void region() {
|
||||
try {
|
||||
Chunk chunk = world().getChunkAt(player().getLocation().getBlockZ() / 16, player().getLocation().getBlockZ() / 16);
|
||||
IrisRegion r = engine().getRegion(chunk);
|
||||
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
||||
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
sender().sendMessage(C.IRIS + "Iris worlds only.");
|
||||
}
|
||||
}
|
||||
|
||||
@Decree(description = "What block am i looking at?", origin = DecreeOrigin.PLAYER)
|
||||
public void block() {
|
||||
BlockData bd;
|
||||
@@ -147,7 +163,7 @@ public class CommandWhat implements DecreeExecutor {
|
||||
|
||||
sender().sendMessage("Found " + v.get() + " Nearby Markers (" + marker + ")");
|
||||
} else {
|
||||
sender().sendMessage("Iris worlds only.");
|
||||
sender().sendMessage(C.IRIS + "Iris worlds only.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,11 +162,11 @@ public class JigsawEditor implements Listener {
|
||||
removeKey(o.getJSONObject(path[0]), s.toArray(new String[0]));
|
||||
}
|
||||
|
||||
private List<JSONObject> getObjectsInArray(JSONObject a, String key) {
|
||||
private List<JSONObject> getObjectsInArray(JSONObject a) { // This gets all the objects in an array that are connectors
|
||||
KList<JSONObject> o = new KList<>();
|
||||
|
||||
for (int i = 0; i < a.getJSONArray(key).length(); i++) {
|
||||
o.add(a.getJSONArray(key).getJSONObject(i));
|
||||
for (int i = 0; i < a.getJSONArray("connectors").length(); i++) {
|
||||
o.add(a.getJSONArray("connectors").getJSONObject(i));
|
||||
}
|
||||
|
||||
return o;
|
||||
@@ -185,7 +185,7 @@ public class JigsawEditor implements Listener {
|
||||
j.remove("placementOptions"); // otherwise
|
||||
|
||||
// Remove key in all objects in array
|
||||
for (JSONObject i : getObjectsInArray(j, "connectors")) {
|
||||
for (JSONObject i : getObjectsInArray(j)) {
|
||||
removeKey(i, "rotateConnector");
|
||||
}
|
||||
|
||||
@@ -277,8 +277,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
|
||||
Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
||||
int rgb = color.getRGB();
|
||||
img.setRGB(xx, z, rgb);
|
||||
} catch (Throwable xxx) {
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -24,6 +24,7 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
|
||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
@@ -44,6 +45,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
|
||||
|
||||
public class PregeneratorJob implements PregenListener {
|
||||
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
|
||||
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
|
||||
@@ -86,7 +89,7 @@ public class PregeneratorJob implements PregenListener {
|
||||
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
|
||||
});
|
||||
|
||||
if (IrisSettings.get().getGui().isUseServerLaunchedGuis()) {
|
||||
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
|
||||
open();
|
||||
}
|
||||
|
||||
@@ -154,12 +157,10 @@ public class PregeneratorJob implements PregenListener {
|
||||
}
|
||||
|
||||
public void drawRegion(int x, int z, Color color) {
|
||||
J.a(() -> {
|
||||
PregenTask.iterateRegion(x, z, (xx, zz) -> {
|
||||
draw(xx, zz, color);
|
||||
J.sleep(3);
|
||||
});
|
||||
});
|
||||
J.a(() -> PregenTask.iterateRegion(x, z, (xx, zz) -> {
|
||||
draw(xx, zz, color);
|
||||
J.sleep(3);
|
||||
}));
|
||||
}
|
||||
|
||||
public void draw(int x, int z, Color color) {
|
||||
@@ -168,7 +169,7 @@ public class PregeneratorJob implements PregenListener {
|
||||
renderer.func.accept(new Position2(x, z), color);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
Iris.error("Failed to draw pregen");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,8 +187,8 @@ public class PregeneratorJob implements PregenListener {
|
||||
monitor.close();
|
||||
J.sleep(3000);
|
||||
frame.setVisible(false);
|
||||
} catch (Throwable e) {
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
Iris.error("Error closing pregen gui");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -209,8 +210,8 @@ public class PregeneratorJob implements PregenListener {
|
||||
frame.add(renderer);
|
||||
frame.setSize(1000, 1000);
|
||||
frame.setVisible(true);
|
||||
} catch (Throwable e) {
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
Iris.error("Error opening pregen gui");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,68 +1,85 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.gui.components;
|
||||
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
public class IrisRenderer {
|
||||
private final Engine renderer;
|
||||
|
||||
public IrisRenderer(Engine renderer) {
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public BufferedImage render(double sx, double sz, double size, int resolution, RenderType currentType) {
|
||||
BufferedImage image = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_RGB);
|
||||
BiFunction<Double, Double, Integer> colorFunction = (d, dx) -> Color.black.getRGB();
|
||||
|
||||
switch (currentType) {
|
||||
case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case BIOME_LAND ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case BIOME_SEA ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case REGION ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB();
|
||||
case CAVE_LAND ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case HEIGHT ->
|
||||
colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB();
|
||||
}
|
||||
|
||||
double x, z;
|
||||
int i, j;
|
||||
for (i = 0; i < resolution; i++) {
|
||||
x = IrisInterpolation.lerp(sx, sx + size, (double) i / (double) (resolution));
|
||||
|
||||
for (j = 0; j < resolution; j++) {
|
||||
z = IrisInterpolation.lerp(sz, sz + size, (double) j / (double) (resolution));
|
||||
image.setRGB(i, j, colorFunction.apply(x, z));
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.gui.components;
|
||||
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisBiomeGeneratorLink;
|
||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class IrisRenderer {
|
||||
private final Engine renderer;
|
||||
|
||||
public IrisRenderer(Engine renderer) {
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public BufferedImage render(double sx, double sz, double size, int resolution, RenderType currentType) {
|
||||
BufferedImage image = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_RGB);
|
||||
BiFunction<Double, Double, Integer> colorFunction = (d, dx) -> Color.black.getRGB();
|
||||
|
||||
switch (currentType) {
|
||||
case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case BIOME_LAND ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case BIOME_SEA ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case REGION ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB();
|
||||
case CAVE_LAND ->
|
||||
colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB();
|
||||
case HEIGHT ->
|
||||
colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB();
|
||||
case CONTINENT -> colorFunction = (x, z) -> {
|
||||
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
||||
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
||||
Color c;
|
||||
if (g.getMax() <= 0) {
|
||||
// Max is below water level, so it is most likely an ocean biome
|
||||
c = Color.BLUE;
|
||||
} else if (g.getMin() < 0) {
|
||||
// Min is below water level, but max is not, so it is most likely a shore biome
|
||||
c = Color.YELLOW;
|
||||
} else {
|
||||
// Both min and max are above water level, so it is most likely a land biome
|
||||
c = Color.GREEN;
|
||||
}
|
||||
return c.getRGB();
|
||||
};
|
||||
}
|
||||
|
||||
double x, z;
|
||||
int i, j;
|
||||
for (i = 0; i < resolution; i++) {
|
||||
x = IrisInterpolation.lerp(sx, sx + size, (double) i / (double) (resolution));
|
||||
|
||||
for (j = 0; j < resolution; j++) {
|
||||
z = IrisInterpolation.lerp(sz, sz + size, (double) j / (double) (resolution));
|
||||
image.setRGB(i, j, colorFunction.apply(x, z));
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -19,5 +19,5 @@
|
||||
package com.volmit.iris.core.gui.components;
|
||||
|
||||
public enum RenderType {
|
||||
BIOME, BIOME_LAND, BIOME_SEA, REGION, CAVE_LAND, HEIGHT, OBJECT_LOAD, DECORATOR_LOAD, LAYER_LOAD
|
||||
BIOME, BIOME_LAND, BIOME_SEA, REGION, CAVE_LAND, HEIGHT, OBJECT_LOAD, DECORATOR_LOAD, CONTINENT, LAYER_LOAD
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
//package com.volmit.iris.core.link;
|
||||
//
|
||||
//import com.jojodmo.customitems.api.CustomItemsAPI;
|
||||
//import com.jojodmo.customitems.item.custom.CustomItem;
|
||||
//import com.jojodmo.customitems.item.custom.block.CustomMushroomBlock;
|
||||
//import com.jojodmo.customitems.version.SafeMaterial;
|
||||
//import com.volmit.iris.util.collection.KList;
|
||||
//import com.volmit.iris.util.reflect.WrappedField;
|
||||
//import com.volmit.iris.util.reflect.WrappedReturningMethod;
|
||||
//import org.bukkit.block.BlockFace;
|
||||
//import org.bukkit.block.data.BlockData;
|
||||
//import org.bukkit.block.data.MultipleFacing;
|
||||
//import org.bukkit.inventory.ItemStack;
|
||||
//
|
||||
//import java.util.Map;
|
||||
//import java.util.MissingResourceException;
|
||||
//
|
||||
//public class CustomItemsDataProvider extends ExternalDataProvider {
|
||||
//
|
||||
// private static final String FIELD_FACES = "faces";
|
||||
// private static final String METHOD_GET_MATERIAL = "getMaterial";
|
||||
//
|
||||
// private WrappedField<CustomMushroomBlock, Map<Integer, boolean[]>> mushroomFaces;
|
||||
// private WrappedReturningMethod<CustomMushroomBlock, SafeMaterial> mushroomMaterial;
|
||||
//
|
||||
// public CustomItemsDataProvider() {
|
||||
// super("CustomItems");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void init() {
|
||||
// this.mushroomFaces = new WrappedField<>(CustomMushroomBlock.class, FIELD_FACES);
|
||||
// this.mushroomMaterial = new WrappedReturningMethod<>(CustomMushroomBlock.class, METHOD_GET_MATERIAL);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||
// CustomItem item = CustomItem.get(blockId.key());
|
||||
// if(item == null) {
|
||||
// throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
// } else if(item.getBlockTexture().isSpawner()) {
|
||||
// throw new MissingResourceException("Iris does not yet support SpawnerBlocks from CustomItems.", blockId.namespace(), blockId.key());
|
||||
// } else if(item.getBlockTexture() != null && item.getBlockTexture().isValid()) {
|
||||
// throw new MissingResourceException("Tried to fetch BlockData for a CustomItem that is not placeable!", blockId.namespace(), blockId.key());
|
||||
// }
|
||||
// return getMushroomData(item);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||
// ItemStack stack = CustomItemsAPI.getCustomItem(itemId.key());
|
||||
// if(stack == null) {
|
||||
// throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||
// }
|
||||
// return stack;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Identifier[] getBlockTypes() {
|
||||
// KList<Identifier> names = new KList<>();
|
||||
// for (String name : CustomItemsAPI.listBlockCustomItemIDs()) {
|
||||
// try {
|
||||
// Identifier key = new Identifier("cui", name);
|
||||
// if (getItemStack(key) != null)
|
||||
// names.add(key);
|
||||
// } catch (MissingResourceException ignored) { }
|
||||
// }
|
||||
//
|
||||
// return names.toArray(new Identifier[0]);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Identifier[] getItemTypes() {
|
||||
// KList<Identifier> names = new KList<>();
|
||||
// for (String name : CustomItemsAPI.listCustomItemIDs()) {
|
||||
// try {
|
||||
// Identifier key = new Identifier("cui", name);
|
||||
// if (getItemStack(key) != null)
|
||||
// names.add(key);
|
||||
// } catch (MissingResourceException ignored) { }
|
||||
// }
|
||||
//
|
||||
// return names.toArray(new Identifier[0]);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isValidProvider(Identifier key, boolean isItem) {
|
||||
// return key.namespace().equalsIgnoreCase("cui");
|
||||
// }
|
||||
//
|
||||
// private BlockData getMushroomData(CustomItem item) {
|
||||
// MultipleFacing data = (MultipleFacing)mushroomMaterial.invoke(item.getBlockTexture().getMushroomId()).parseMaterial().createBlockData();
|
||||
// boolean[] values = mushroomFaces.get().get(item.getBlockTexture().getMushroomId());
|
||||
// data.setFace(BlockFace.DOWN, values[0]);
|
||||
// data.setFace(BlockFace.EAST, values[1]);
|
||||
// data.setFace(BlockFace.NORTH, values[2]);
|
||||
// data.setFace(BlockFace.SOUTH, values[3]);
|
||||
// data.setFace(BlockFace.UP, values[4]);
|
||||
// data.setFace(BlockFace.WEST, values[5]);
|
||||
// return data;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.ssomar.score.api.executableitems.ExecutableItemsAPI;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ExecutableItemsDataProvider extends ExternalDataProvider {
|
||||
public ExecutableItemsDataProvider() {
|
||||
super("ExecutableItems");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
Iris.info("Setting up ExecutableItems Link...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||
return ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(itemId.key())
|
||||
.map(item -> item.buildItem(1, Optional.empty()))
|
||||
.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getBlockTypes() {
|
||||
return new Identifier[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getItemTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
for (String name : ExecutableItemsAPI.getExecutableItemsManager().getExecutableItemIdsList()) {
|
||||
try {
|
||||
Identifier key = new Identifier("executable_items", name);
|
||||
if (getItemStack(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProvider(Identifier key, boolean isItem) {
|
||||
return key.namespace().equalsIgnoreCase("executable_items") && isItem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class ExternalDataProvider {
|
||||
|
||||
@Getter
|
||||
private final String pluginId;
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return Bukkit.getPluginManager().getPlugin(pluginId);
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return getPlugin() != null && getPlugin().isEnabled();
|
||||
}
|
||||
|
||||
public abstract void init();
|
||||
|
||||
public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException;
|
||||
|
||||
public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException;
|
||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {};
|
||||
|
||||
public abstract Identifier[] getBlockTypes();
|
||||
|
||||
public abstract Identifier[] getItemTypes();
|
||||
|
||||
public abstract boolean isValidProvider(Identifier id, boolean isItem);
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.data.IrisBlockData;
|
||||
import com.volmit.iris.util.reflect.WrappedField;
|
||||
import com.volmit.iris.util.reflect.WrappedReturningMethod;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Leaves;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class HMCLeavesDataProvider extends ExternalDataProvider {
|
||||
private Object apiInstance;
|
||||
private WrappedReturningMethod<Object, Material> worldBlockType;
|
||||
private WrappedReturningMethod<Object, Boolean> setCustomBlock;
|
||||
private Map<String, Object> blockDataMap = Map.of();
|
||||
private Map<String, Supplier<ItemStack>> itemDataField = Map.of();
|
||||
|
||||
public HMCLeavesDataProvider() {
|
||||
super("HMCLeaves");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginId() {
|
||||
return "HMCLeaves";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
try {
|
||||
worldBlockType = new WrappedReturningMethod<>((Class<Object>) Class.forName("io.github.fisher2911.hmcleaves.data.BlockData"), "worldBlockType");
|
||||
apiInstance = getApiInstance(Class.forName("io.github.fisher2911.hmcleaves.api.HMCLeavesAPI"));
|
||||
setCustomBlock = new WrappedReturningMethod<>((Class<Object>) apiInstance.getClass(), "setCustomBlock", Location.class, String.class, boolean.class);
|
||||
Object config = getLeavesConfig(apiInstance.getClass());
|
||||
blockDataMap = getMap(config, "blockDataMap");
|
||||
itemDataField = getMap(config, "itemSupplierMap");
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to initialize HMCLeavesDataProvider: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||
Object o = blockDataMap.get(blockId.key());
|
||||
if (o == null)
|
||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
Material material = worldBlockType.invoke(o, new Object[0]);
|
||||
if (material == null)
|
||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
BlockData blockData = Bukkit.createBlockData(material);
|
||||
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
||||
leaves.setPersistent(true);
|
||||
return new IrisBlockData(blockData, blockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||
if (!itemDataField.containsKey(itemId.key()))
|
||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||
return itemDataField.get(itemId.key()).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||
Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), false});
|
||||
if (result == null || !result)
|
||||
Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ());
|
||||
else if (IrisSettings.get().getGenerator().preventLeafDecay) {
|
||||
BlockData blockData = block.getBlockData();
|
||||
if (blockData instanceof Leaves leaves)
|
||||
leaves.setPersistent(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getBlockTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
for (String name : blockDataMap.keySet()) {
|
||||
try {
|
||||
Identifier key = new Identifier("hmcleaves", name);
|
||||
if (getBlockData(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getItemTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
for (String name : itemDataField.keySet()) {
|
||||
try {
|
||||
Identifier key = new Identifier("hmcleaves", name);
|
||||
if (getItemStack(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||
return (isItem ? itemDataField.keySet() : blockDataMap.keySet()).contains(id.key());
|
||||
}
|
||||
|
||||
private <C, T> Map<String, T> getMap(C config, String name) {
|
||||
WrappedField<C, Map<String, T>> field = new WrappedField<>((Class<C>) config.getClass(), name);
|
||||
return field.get(config);
|
||||
}
|
||||
|
||||
private <A> A getApiInstance(Class<A> apiClass) {
|
||||
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
||||
return instance.invoke();
|
||||
}
|
||||
|
||||
private <A, C> C getLeavesConfig(Class<A> apiClass) {
|
||||
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
||||
WrappedField<A, C> config = new WrappedField<>(apiClass, "config");
|
||||
return config.get(instance.invoke());
|
||||
}
|
||||
}
|
||||
33
core/src/main/java/com/volmit/iris/core/link/Identifier.java
Normal file
33
core/src/main/java/com/volmit/iris/core/link/Identifier.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
|
||||
public record Identifier(String namespace, String key) {
|
||||
|
||||
private static final String DEFAULT_NAMESPACE = "minecraft";
|
||||
|
||||
public static Identifier fromString(String id) {
|
||||
String[] strings = id.split(":", 2);
|
||||
if (strings.length == 1) {
|
||||
return new Identifier(DEFAULT_NAMESPACE, strings[0]);
|
||||
} else {
|
||||
return new Identifier(strings[0], strings[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return namespace + ":" + key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Identifier i) {
|
||||
return i.namespace().equals(this.namespace) && i.key().equals(this.key);
|
||||
} else if (obj instanceof NamespacedKey i) {
|
||||
return i.getNamespace().equals(this.namespace) && i.getKey().equals(this.key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,27 +25,28 @@ import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
// See/update https://app.gitbook.com/@volmitsoftware/s/iris/compatability/papi/
|
||||
public class IrisPapiExpansion extends PlaceholderExpansion {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
public @NotNull String getIdentifier() {
|
||||
return "iris";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
public @NotNull String getAuthor() {
|
||||
return "Volmit Software";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
public @NotNull String getVersion() {
|
||||
return Iris.instance.getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import dev.lone.itemsadder.api.CustomBlock;
|
||||
import dev.lone.itemsadder.api.CustomStack;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
public class ItemAdderDataProvider extends ExternalDataProvider {
|
||||
|
||||
private KList<String> itemNamespaces, blockNamespaces;
|
||||
|
||||
public ItemAdderDataProvider() {
|
||||
super("ItemsAdder");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
this.itemNamespaces = new KList<>();
|
||||
this.blockNamespaces = new KList<>();
|
||||
|
||||
for (Identifier i : getItemTypes()) {
|
||||
itemNamespaces.addIfMissing(i.namespace());
|
||||
}
|
||||
for (Identifier i : getBlockTypes()) {
|
||||
blockNamespaces.addIfMissing(i.namespace());
|
||||
Iris.info("Found ItemAdder Block: " + i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||
return CustomBlock.getBaseBlockData(blockId.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||
CustomStack stack = CustomStack.getInstance(itemId.toString());
|
||||
if (stack == null) {
|
||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||
}
|
||||
return stack.getItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getBlockTypes() {
|
||||
KList<Identifier> keys = new KList<>();
|
||||
for (String s : CustomBlock.getNamespacedIdsInRegistry()) {
|
||||
keys.add(Identifier.fromString(s));
|
||||
}
|
||||
return keys.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getItemTypes() {
|
||||
KList<Identifier> keys = new KList<>();
|
||||
for (String s : CustomStack.getNamespacedIdsInRegistry()) {
|
||||
keys.add(Identifier.fromString(s));
|
||||
}
|
||||
return keys.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||
return isItem ? this.itemNamespaces.contains(id.namespace()) : this.blockNamespaces.contains(id.namespace());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class MMOItemsDataProvider extends ExternalDataProvider {
|
||||
|
||||
public MMOItemsDataProvider() {
|
||||
super("MMOItems");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
Iris.info("Setting up MMOItems Link...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||
int id = -1;
|
||||
try {
|
||||
id = Integer.parseInt(blockId.key());
|
||||
} catch (NumberFormatException ignored) {}
|
||||
CustomBlock block = api().getCustomBlocks().getBlock(id);
|
||||
if (block == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
return block.getState().getBlockData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||
String[] parts = itemId.namespace().split("_", 2);
|
||||
if (parts.length != 2)
|
||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||
CompletableFuture<ItemStack> future = new CompletableFuture<>();
|
||||
Runnable run = () -> future.complete(api().getItem(parts[1], itemId.key()));
|
||||
if (Bukkit.isPrimaryThread()) run.run();
|
||||
else J.s(run);
|
||||
ItemStack item = null;
|
||||
try {
|
||||
item = future.get();
|
||||
} catch (InterruptedException | ExecutionException ignored) {}
|
||||
if (item == null)
|
||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getBlockTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
for (Integer id : api().getCustomBlocks().getBlockIds()) {
|
||||
try {
|
||||
Identifier key = new Identifier("mmoitems", String.valueOf(id));
|
||||
if (getBlockData(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getItemTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
Runnable run = () -> {
|
||||
for (Type type : api().getTypes().getAll()) {
|
||||
for (String name : api().getTemplates().getTemplateNames(type)) {
|
||||
try {
|
||||
Identifier key = new Identifier("mmoitems_" + type.getId(), name);
|
||||
if (getItemStack(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (Bukkit.isPrimaryThread()) run.run();
|
||||
else {
|
||||
try {
|
||||
J.sfut(run).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Iris.error("Failed getting MMOItems item types!");
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||
return isItem ? id.namespace().split("_", 2).length == 2 : id.namespace().equals("mmoitems");
|
||||
}
|
||||
|
||||
private MMOItems api() {
|
||||
return MMOItems.plugin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import io.lumine.mythic.bukkit.MythicBukkit;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
|
||||
public class MythicMobsLink {
|
||||
|
||||
public MythicMobsLink() {
|
||||
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return getPlugin() != null;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return Bukkit.getPluginManager().getPlugin("MythicMobs");
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn a mythic mob at this location
|
||||
*
|
||||
* @param mob The mob
|
||||
* @param location The location
|
||||
* @return The mob, or null if it can't be spawned
|
||||
*/
|
||||
public @Nullable
|
||||
Entity spawnMob(String mob, Location location) {
|
||||
return isEnabled() ? MythicBukkit.inst().getMobManager().spawnMob(mob, location).getEntity().getBukkitEntity() : null;
|
||||
}
|
||||
|
||||
public Collection<String> getMythicMobTypes() {
|
||||
return isEnabled() ? MythicBukkit.inst().getMobManager().getMobNames() : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.data.B;
|
||||
import com.volmit.iris.util.data.IrisBlockData;
|
||||
import com.volmit.iris.util.reflect.WrappedField;
|
||||
import io.th0rgal.oraxen.api.OraxenItems;
|
||||
import io.th0rgal.oraxen.items.ItemBuilder;
|
||||
import io.th0rgal.oraxen.mechanics.Mechanic;
|
||||
import io.th0rgal.oraxen.mechanics.MechanicFactory;
|
||||
import io.th0rgal.oraxen.mechanics.MechanicsManager;
|
||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanic;
|
||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanicFactory;
|
||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureFactory;
|
||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic;
|
||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory;
|
||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.MultipleFacing;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class OraxenDataProvider extends ExternalDataProvider {
|
||||
|
||||
private static final String FIELD_FACTORIES_MAP = "FACTORIES_BY_MECHANIC_ID";
|
||||
|
||||
private WrappedField<MechanicsManager, Map<String, MechanicFactory>> factories;
|
||||
|
||||
public OraxenDataProvider() {
|
||||
super("Oraxen");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
Iris.info("Setting up Oraxen Link...");
|
||||
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
|
||||
if (this.factories.hasFailed()) {
|
||||
Iris.error("Failed to set up Oraxen Link: Unable to fetch MechanicFactoriesMap!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||
MechanicFactory factory = getFactory(blockId);
|
||||
if (factory instanceof NoteBlockMechanicFactory f)
|
||||
return f.createNoteBlockData(blockId.key());
|
||||
else if (factory instanceof BlockMechanicFactory f) {
|
||||
MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM);
|
||||
BlockMechanic.setBlockFacing(newBlockData, ((BlockMechanic) f.getMechanic(blockId.key())).getCustomVariation());
|
||||
return newBlockData;
|
||||
} else if (factory instanceof StringBlockMechanicFactory f) {
|
||||
return f.createTripwireData(blockId.key());
|
||||
} else if (factory instanceof FurnitureFactory) {
|
||||
return new IrisBlockData(B.getAir(), blockId);
|
||||
} else
|
||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
|
||||
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||
Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key());
|
||||
if (mechanic instanceof FurnitureMechanic f) {
|
||||
f.place(block.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getBlockTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
for (String name : OraxenItems.getItemNames()) {
|
||||
try {
|
||||
Identifier key = new Identifier("oraxen", name);
|
||||
if (getBlockData(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier[] getItemTypes() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
for (String name : OraxenItems.getItemNames()) {
|
||||
try {
|
||||
Identifier key = new Identifier("oraxen", name);
|
||||
if (getItemStack(key) != null)
|
||||
names.add(key);
|
||||
} catch (MissingResourceException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
if (super.isReady()) {
|
||||
if (factories == null) {
|
||||
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
|
||||
}
|
||||
return super.isReady() && !factories.hasFailed();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProvider(Identifier key, boolean isItem) {
|
||||
return key.namespace().equalsIgnoreCase("oraxen");
|
||||
}
|
||||
|
||||
private MechanicFactory getFactory(Identifier key) throws MissingResourceException {
|
||||
return factories.get().values().stream()
|
||||
.filter(i -> i.getItems().contains(key.key()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", key.namespace(), key.key()));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package com.volmit.iris.core.link;
|
||||
|
||||
import com.volmit.iris.util.data.Cuboid;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class WorldEditLink {
|
||||
private static Boolean enabled = null;
|
||||
|
||||
public static Cuboid getSelection(Player p) {
|
||||
if (!hasWorldEdit())
|
||||
return null;
|
||||
|
||||
try {
|
||||
Object instance = Class.forName("com.sk89q.worldedit.WorldEdit").getDeclaredMethod("getInstance").invoke(null);
|
||||
Object sessionManager = instance.getClass().getDeclaredMethod("getSessionManager").invoke(instance);
|
||||
@@ -23,10 +29,15 @@ public class WorldEditLink {
|
||||
(int) min.getClass().getDeclaredMethod("getY").invoke(max),
|
||||
(int) min.getClass().getDeclaredMethod("getZ").invoke(max)
|
||||
);
|
||||
} catch (Throwable e) {
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasWorldEdit() {
|
||||
if (enabled == null)
|
||||
enabled = Bukkit.getPluginManager().isPluginEnabled("WorldEdit");
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
public class ImageResourceLoader extends ResourceLoader<IrisImage> {
|
||||
public ImageResourceLoader(File root, IrisData idm, String folderName, String resourceTypeName) {
|
||||
@@ -66,6 +67,17 @@ public class ImageResourceLoader extends ResourceLoader<IrisImage> {
|
||||
}
|
||||
}
|
||||
|
||||
void getPNGFiles(File directory, Set<String> m) {
|
||||
for (File file : directory.listFiles()) {
|
||||
if (file.isFile() && file.getName().endsWith(".png")) {
|
||||
m.add(file.getName().replaceAll("\\Q.png\\E", ""));
|
||||
} else if (file.isDirectory()) {
|
||||
getPNGFiles(file, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String[] getPossibleKeys() {
|
||||
if (possibleKeys != null) {
|
||||
return possibleKeys;
|
||||
@@ -74,26 +86,31 @@ public class ImageResourceLoader extends ResourceLoader<IrisImage> {
|
||||
Iris.debug("Building " + resourceTypeName + " Possibility Lists");
|
||||
KSet<String> m = new KSet<>();
|
||||
|
||||
|
||||
for (File i : getFolders()) {
|
||||
for (File j : i.listFiles()) {
|
||||
if (j.isFile() && j.getName().endsWith(".png")) {
|
||||
m.add(j.getName().replaceAll("\\Q.png\\E", ""));
|
||||
} else if (j.isDirectory()) {
|
||||
for (File k : j.listFiles()) {
|
||||
if (k.isFile() && k.getName().endsWith(".png")) {
|
||||
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.png\\E", ""));
|
||||
} else if (k.isDirectory()) {
|
||||
for (File l : k.listFiles()) {
|
||||
if (l.isFile() && l.getName().endsWith(".png")) {
|
||||
m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.png\\E", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getPNGFiles(i, m);
|
||||
}
|
||||
|
||||
// for (File i : getFolders()) {
|
||||
// for (File j : i.listFiles()) {
|
||||
// if (j.isFile() && j.getName().endsWith(".png")) {
|
||||
// m.add(j.getName().replaceAll("\\Q.png\\E", ""));
|
||||
// } else if (j.isDirectory()) {
|
||||
// for (File k : j.listFiles()) {
|
||||
// if (k.isFile() && k.getName().endsWith(".png")) {
|
||||
// m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.png\\E", ""));
|
||||
// } else if (k.isDirectory()) {
|
||||
// for (File l : k.listFiles()) {
|
||||
// if (l.isFile() && l.getName().endsWith(".png")) {
|
||||
// m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.png\\E", ""));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
KList<String> v = new KList<>(m);
|
||||
possibleKeys = v.toArray(new String[0]);
|
||||
return possibleKeys;
|
||||
@@ -369,8 +369,7 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory {
|
||||
}
|
||||
}
|
||||
|
||||
String ff = g.substring(1).split("\\Q.\\E")[0];
|
||||
return ff;
|
||||
return g.substring(1).split("\\Q.\\E")[0];
|
||||
} else {
|
||||
Iris.error("Forign file from loader " + f.getPath() + " (loader realm: " + getDataFolder().getPath() + ")");
|
||||
}
|
||||
@@ -29,6 +29,8 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import java.io.File;
|
||||
|
||||
public class MatterObjectResourceLoader extends ResourceLoader<IrisMatterObject> {
|
||||
private String[] possibleKeys;
|
||||
|
||||
public MatterObjectResourceLoader(File root, IrisData idm, String folderName, String resourceTypeName) {
|
||||
super(root, idm, folderName, resourceTypeName, IrisMatterObject.class);
|
||||
loadCache = new KCache<>(this::loadRaw, IrisSettings.get().getPerformance().getObjectLoaderCacheSize());
|
||||
@@ -63,6 +65,16 @@ public class MatterObjectResourceLoader extends ResourceLoader<IrisMatterObject>
|
||||
}
|
||||
}
|
||||
|
||||
private void findMatFiles(File dir, KSet<String> m) {
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.isFile() && file.getName().endsWith(".mat")) {
|
||||
m.add(file.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
} else if (file.isDirectory()) {
|
||||
findMatFiles(file, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getPossibleKeys() {
|
||||
if (possibleKeys != null) {
|
||||
return possibleKeys;
|
||||
@@ -71,24 +83,8 @@ public class MatterObjectResourceLoader extends ResourceLoader<IrisMatterObject>
|
||||
Iris.debug("Building " + resourceTypeName + " Possibility Lists");
|
||||
KSet<String> m = new KSet<>();
|
||||
|
||||
for (File i : getFolders()) {
|
||||
for (File j : i.listFiles()) {
|
||||
if (j.isFile() && j.getName().endsWith(".mat")) {
|
||||
m.add(j.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
} else if (j.isDirectory()) {
|
||||
for (File k : j.listFiles()) {
|
||||
if (k.isFile() && k.getName().endsWith(".mat")) {
|
||||
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
} else if (k.isDirectory()) {
|
||||
for (File l : k.listFiles()) {
|
||||
if (l.isFile() && l.getName().endsWith(".mat")) {
|
||||
m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (File folder : getFolders()) {
|
||||
findMatFiles(folder, m);
|
||||
}
|
||||
|
||||
KList<String> v = new KList<>(m);
|
||||
@@ -96,6 +92,40 @@ public class MatterObjectResourceLoader extends ResourceLoader<IrisMatterObject>
|
||||
return possibleKeys;
|
||||
}
|
||||
|
||||
|
||||
// public String[] getPossibleKeys() {
|
||||
// if (possibleKeys != null) {
|
||||
// return possibleKeys;
|
||||
// }
|
||||
//
|
||||
// Iris.debug("Building " + resourceTypeName + " Possibility Lists");
|
||||
// KSet<String> m = new KSet<>();
|
||||
//
|
||||
// for (File i : getFolders()) {
|
||||
// for (File j : i.listFiles()) {
|
||||
// if (j.isFile() && j.getName().endsWith(".mat")) {
|
||||
// m.add(j.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
// } else if (j.isDirectory()) {
|
||||
// for (File k : j.listFiles()) {
|
||||
// if (k.isFile() && k.getName().endsWith(".mat")) {
|
||||
// m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
// } else if (k.isDirectory()) {
|
||||
// for (File l : k.listFiles()) {
|
||||
// if (l.isFile() && l.getName().endsWith(".mat")) {
|
||||
// m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.mat\\E", ""));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// KList<String> v = new KList<>(m);
|
||||
// possibleKeys = v.toArray(new String[0]);
|
||||
// return possibleKeys;
|
||||
// }
|
||||
|
||||
public File findFile(String name) {
|
||||
for (File i : getFolders(name)) {
|
||||
for (File j : i.listFiles()) {
|
||||
@@ -40,6 +40,8 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Locale;
|
||||
@@ -52,6 +54,8 @@ import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(exclude = "manager")
|
||||
@ToString(exclude = "manager")
|
||||
public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
|
||||
public static final AtomicDouble tlt = new AtomicDouble(0);
|
||||
private static final int CACHE_SIZE = 100000;
|
||||
@@ -21,13 +21,13 @@ package com.volmit.iris.core.loader;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.engine.object.IrisScript;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.data.KCache;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ScriptResourceLoader extends ResourceLoader<IrisScript> {
|
||||
public ScriptResourceLoader(File root, IrisData idm, String folderName, String resourceTypeName) {
|
||||
@@ -60,39 +60,70 @@ public class ScriptResourceLoader extends ResourceLoader<IrisScript> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String[] getPossibleKeys() {
|
||||
if (possibleKeys != null) {
|
||||
return possibleKeys;
|
||||
}
|
||||
|
||||
Iris.debug("Building " + resourceTypeName + " Possibility Lists");
|
||||
KSet<String> m = new KSet<>();
|
||||
Set<String> keys = new HashSet<>();
|
||||
|
||||
for (File i : getFolders()) {
|
||||
for (File j : i.listFiles()) {
|
||||
if (j.isFile() && j.getName().endsWith(".js")) {
|
||||
m.add(j.getName().replaceAll("\\Q.js\\E", ""));
|
||||
} else if (j.isDirectory()) {
|
||||
for (File k : j.listFiles()) {
|
||||
if (k.isFile() && k.getName().endsWith(".js")) {
|
||||
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.js\\E", ""));
|
||||
} else if (k.isDirectory()) {
|
||||
for (File l : k.listFiles()) {
|
||||
if (l.isFile() && l.getName().endsWith(".js")) {
|
||||
m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.js\\E", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i.isDirectory()) {
|
||||
keys.addAll(getKeysInDirectory(i));
|
||||
}
|
||||
}
|
||||
|
||||
KList<String> v = new KList<>(m);
|
||||
possibleKeys = v.toArray(new String[0]);
|
||||
possibleKeys = keys.toArray(new String[0]);
|
||||
return possibleKeys;
|
||||
}
|
||||
|
||||
private Set<String> getKeysInDirectory(File directory) {
|
||||
Set<String> keys = new HashSet<>();
|
||||
for (File file : directory.listFiles()) {
|
||||
if (file.isFile() && file.getName().endsWith(".js")) {
|
||||
keys.add(file.getName().replaceAll("\\Q.js\\E", ""));
|
||||
} else if (file.isDirectory()) {
|
||||
keys.addAll(getKeysInDirectory(file));
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
// public String[] getPossibleKeys() {
|
||||
// if (possibleKeys != null) {
|
||||
// return possibleKeys;
|
||||
// }
|
||||
//
|
||||
// Iris.debug("Building " + resourceTypeName + " Possibility Lists");
|
||||
// KSet<String> m = new KSet<>();
|
||||
//
|
||||
// for (File i : getFolders()) {
|
||||
// for (File j : i.listFiles()) {
|
||||
// if (j.isFile() && j.getName().endsWith(".js")) {
|
||||
// m.add(j.getName().replaceAll("\\Q.js\\E", ""));
|
||||
// } else if (j.isDirectory()) {
|
||||
// for (File k : j.listFiles()) {
|
||||
// if (k.isFile() && k.getName().endsWith(".js")) {
|
||||
// m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.js\\E", ""));
|
||||
// } else if (k.isDirectory()) {
|
||||
// for (File l : k.listFiles()) {
|
||||
// if (l.isFile() && l.getName().endsWith(".js")) {
|
||||
// m.add(j.getName() + "/" + k.getName() + "/" + l.getName().replaceAll("\\Q.js\\E", ""));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// KList<String> v = new KList<>(m);
|
||||
// possibleKeys = v.toArray(new String[0]);
|
||||
// return possibleKeys;
|
||||
// }
|
||||
|
||||
public File findFile(String name) {
|
||||
for (File i : getFolders(name)) {
|
||||
for (File j : i.listFiles()) {
|
||||
@@ -20,15 +20,10 @@ package com.volmit.iris.core.nms;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.nms.v19_3.NMSBinding19_3;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class INMS {
|
||||
//@builder
|
||||
private static final KMap<String, Class<? extends INMSBinding>> bindings = new KMap<String, Class<? extends INMSBinding>>()
|
||||
.qput("v1_19_R2", NMSBinding19_3.class);
|
||||
//@done
|
||||
private static final INMSBinding binding = bind();
|
||||
|
||||
@@ -56,17 +51,19 @@ public class INMS {
|
||||
String code = getNMSTag();
|
||||
Iris.info("Locating NMS Binding for " + code);
|
||||
|
||||
if (bindings.containsKey(code)) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.volmit.iris.core.nms."+code+".NMSBinding");
|
||||
try {
|
||||
INMSBinding b = bindings.get(code).getConstructor().newInstance();
|
||||
Iris.info("Craftbukkit " + code + " <-> " + b.getClass().getSimpleName() + " Successfully Bound");
|
||||
|
||||
return b;
|
||||
Object b = clazz.getConstructor().newInstance();
|
||||
if (b instanceof INMSBinding binding) {
|
||||
Iris.info("Craftbukkit " + code + " <-> " + b.getClass().getSimpleName() + " Successfully Bound");
|
||||
return binding;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException|NoClassDefFoundError classNotFoundException) {}
|
||||
|
||||
Iris.info("Craftbukkit " + code + " <-> " + NMSBinding1X.class.getSimpleName() + " Successfully Bound");
|
||||
Iris.warn("Note: Some features of Iris may not work the same since you are on an unsupported version of Minecraft.");
|
||||
@@ -18,7 +18,12 @@
|
||||
|
||||
package com.volmit.iris.core.nms;
|
||||
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisEntity;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.math.Vector3d;
|
||||
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
||||
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||
@@ -27,8 +32,13 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Dolphin;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface INMSBinding {
|
||||
boolean hasTile(Location l);
|
||||
@@ -67,6 +77,8 @@ public interface INMSBinding {
|
||||
|
||||
Object getBiomeBase(Object registry, Biome biome);
|
||||
|
||||
KList<Biome> getBiomes();
|
||||
|
||||
boolean isBukkit();
|
||||
|
||||
int getBiomeId(Biome biome);
|
||||
@@ -90,4 +102,14 @@ public interface INMSBinding {
|
||||
MCAPaletteAccess createPalette();
|
||||
|
||||
void injectBiomesFromMantle(Chunk e, Mantle mantle);
|
||||
|
||||
ItemStack applyCustomNbt(ItemStack itemStack, KMap<String, Object> customNbt) throws IllegalArgumentException;
|
||||
|
||||
void setTreasurePos(Dolphin dolphin, com.volmit.iris.core.nms.container.BlockPos pos);
|
||||
|
||||
void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException;
|
||||
|
||||
Vector3d getBoundingbox(org.bukkit.entity.EntityType entity);
|
||||
|
||||
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.volmit.iris.core.nms.container;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BlockPos {
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.volmit.iris.core.nms.container;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Pair<A, B> {
|
||||
private A a;
|
||||
private B b;
|
||||
}
|
||||
@@ -20,7 +20,12 @@ package com.volmit.iris.core.nms.v1X;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMSBinding;
|
||||
import com.volmit.iris.core.nms.container.BlockPos;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.math.Vector3d;
|
||||
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
||||
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||
@@ -28,8 +33,12 @@ import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Dolphin;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class NMSBinding1X implements INMSBinding {
|
||||
private static final boolean supportsCustomHeight = testCustomHeight();
|
||||
@@ -64,6 +73,30 @@ public class NMSBinding1X implements INMSBinding {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack applyCustomNbt(ItemStack itemStack, KMap<String, Object> customNbt) throws IllegalArgumentException {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTreasurePos(Dolphin dolphin, BlockPos pos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException {
|
||||
|
||||
}
|
||||
|
||||
public Vector3d getBoundingbox() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) {
|
||||
return location.getWorld().spawnEntity(location, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeTile(CompoundTag s, Location newPosition) {
|
||||
|
||||
@@ -143,6 +176,11 @@ public class NMSBinding1X implements INMSBinding {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KList<Biome> getBiomes() {
|
||||
return new KList<>(Biome.values()).qdel(Biome.CUSTOM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBukkit() {
|
||||
return true;
|
||||
@@ -177,6 +215,11 @@ public class NMSBinding1X implements INMSBinding {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAPaletteAccess createPalette() {
|
||||
Iris.error("Cannot use the global data palette! Iris is incapable of using MCA generation on this version of minecraft!");
|
||||
@@ -0,0 +1,275 @@
|
||||
package com.volmit.iris.core.pregenerator;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class DeepSearchPregenerator extends Thread implements Listener {
|
||||
@Getter
|
||||
private static DeepSearchPregenerator instance;
|
||||
private final DeepSearchJob job;
|
||||
private final File destination;
|
||||
private final int maxPosition;
|
||||
private World world;
|
||||
private final ChronoLatch latch;
|
||||
private static AtomicInteger foundChunks;
|
||||
private final AtomicInteger foundLast;
|
||||
private final AtomicInteger foundTotalChunks;
|
||||
private final AtomicLong startTime;
|
||||
private final RollingSequence chunksPerSecond;
|
||||
private final RollingSequence chunksPerMinute;
|
||||
private final AtomicInteger chunkCachePos;
|
||||
private final AtomicInteger chunkCacheSize;
|
||||
private int pos;
|
||||
private final AtomicInteger foundCacheLast;
|
||||
private final AtomicInteger foundCache;
|
||||
private LinkedHashMap<Integer, Position2> chunkCache;
|
||||
private KList<Position2> chunkQueue;
|
||||
private final ReentrantLock cacheLock;
|
||||
|
||||
private static final Map<String, DeepSearchJob> jobs = new HashMap<>();
|
||||
|
||||
public DeepSearchPregenerator(DeepSearchJob job, File destination) {
|
||||
this.job = job;
|
||||
this.chunkCacheSize = new AtomicInteger(); // todo
|
||||
this.chunkCachePos = new AtomicInteger(1000);
|
||||
this.foundCacheLast = new AtomicInteger();
|
||||
this.foundCache = new AtomicInteger();
|
||||
this.cacheLock = new ReentrantLock();
|
||||
this.destination = destination;
|
||||
this.chunkCache = new LinkedHashMap<>();
|
||||
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||
}).count();
|
||||
this.world = Bukkit.getWorld(job.getWorld().getUID());
|
||||
this.chunkQueue = new KList<>();
|
||||
this.latch = new ChronoLatch(3000);
|
||||
this.startTime = new AtomicLong(M.ms());
|
||||
this.chunksPerSecond = new RollingSequence(10);
|
||||
this.chunksPerMinute = new RollingSequence(10);
|
||||
foundChunks = new AtomicInteger(0);
|
||||
this.foundLast = new AtomicInteger(0);
|
||||
this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
||||
|
||||
this.pos = 0;
|
||||
jobs.put(job.getWorld().getName(), job);
|
||||
DeepSearchPregenerator.instance = this;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e) {
|
||||
if (e.getWorld().equals(world)) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (!interrupted()) {
|
||||
tick();
|
||||
}
|
||||
try {
|
||||
saveNow();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
DeepSearchJob job = jobs.get(world.getName());
|
||||
// chunkCache(); //todo finish this
|
||||
if (latch.flip() && !job.paused) {
|
||||
if (cacheLock.isLocked()) {
|
||||
Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get());
|
||||
} else {
|
||||
long eta = computeETA();
|
||||
save();
|
||||
int secondGenerated = foundChunks.get() - foundLast.get();
|
||||
foundLast.set(foundChunks.get());
|
||||
secondGenerated = secondGenerated / 3;
|
||||
chunksPerSecond.put(secondGenerated);
|
||||
chunksPerMinute.put(secondGenerated * 60);
|
||||
Iris.info("DeepFinder: " + C.IRIS + world.getName() + C.RESET + " Searching: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
|
||||
}
|
||||
|
||||
}
|
||||
if (foundChunks.get() >= foundTotalChunks.get()) {
|
||||
Iris.info("Completed DeepSearch!");
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private long computeETA() {
|
||||
return (long) ((foundTotalChunks.get() - foundChunks.get()) / chunksPerSecond.getAverage()) * 1000;
|
||||
// todo broken
|
||||
}
|
||||
|
||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
private void queueSystem(Position2 chunk) {
|
||||
if (chunkQueue.isEmpty()) {
|
||||
for (int limit = 512; limit != 0; limit--) {
|
||||
pos = job.getPosition() + 1;
|
||||
chunkQueue.add(getChunk(pos));
|
||||
}
|
||||
} else {
|
||||
//MCAUtil.read();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void findInChunk(World world, int x, int z) throws IOException {
|
||||
int xx = x * 16;
|
||||
int zz = z * 16;
|
||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int j = 0; j < 16; j++) {
|
||||
int height = engine.getHeight(xx + i, zz + j);
|
||||
if (height > 300) {
|
||||
File found = new File("plugins" + "iris" + "found.txt");
|
||||
FileWriter writer = new FileWriter(found);
|
||||
if (!found.exists()) {
|
||||
found.createNewFile();
|
||||
}
|
||||
IrisBiome biome = engine.getBiome(xx, engine.getHeight(), zz);
|
||||
Iris.info("Found at! " + xx + ", " + zz + "Biome ID: " + biome.getName() + ", ");
|
||||
writer.write("Biome at: X: " + xx + " Z: " + zz + "Biome ID: " + biome.getName() + ", ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Position2 getChunk(int position) {
|
||||
int p = -1;
|
||||
AtomicInteger xx = new AtomicInteger();
|
||||
AtomicInteger zz = new AtomicInteger();
|
||||
Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||
xx.set(x);
|
||||
zz.set(z);
|
||||
});
|
||||
|
||||
while (s.hasNext() && p++ < position) {
|
||||
s.next();
|
||||
}
|
||||
|
||||
return new Position2(xx.get(), zz.get());
|
||||
}
|
||||
|
||||
public void save() {
|
||||
J.a(() -> {
|
||||
try {
|
||||
saveNow();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setPausedDeep(World world) {
|
||||
DeepSearchJob job = jobs.get(world.getName());
|
||||
if (isPausedDeep(world)){
|
||||
job.paused = false;
|
||||
} else {
|
||||
job.paused = true;
|
||||
}
|
||||
|
||||
if ( job.paused) {
|
||||
Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||
} else {
|
||||
Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPausedDeep(World world) {
|
||||
DeepSearchJob job = jobs.get(world.getName());
|
||||
return job != null && job.isPaused();
|
||||
}
|
||||
|
||||
public void shutdownInstance(World world) throws IOException {
|
||||
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||
DeepSearchJob job = jobs.get(world.getName());
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File deepFile = new File(worldDirectory, "DeepSearch.json");
|
||||
|
||||
if (job == null) {
|
||||
Iris.error("No DeepSearch job found for world: " + world.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!job.isPaused()) {
|
||||
job.setPaused(true);
|
||||
}
|
||||
save();
|
||||
jobs.remove(world.getName());
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (deepFile.exists()){
|
||||
deepFile.delete();
|
||||
J.sleep(1000);
|
||||
}
|
||||
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
|
||||
}
|
||||
}.runTaskLater(Iris.instance, 20L);
|
||||
} catch (Exception e) {
|
||||
Iris.error("Failed to shutdown DeepSearch for " + world.getName());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
saveNow();
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void saveNow() throws IOException {
|
||||
IO.writeAll(this.destination, new Gson().toJson(job));
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class DeepSearchJob {
|
||||
private World world;
|
||||
@Builder.Default
|
||||
private int radiusBlocks = 5000;
|
||||
@Builder.Default
|
||||
private int position = 0;
|
||||
@Builder.Default
|
||||
boolean paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
package com.volmit.iris.core.pregenerator;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.pack.IrisPack;
|
||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.math.M;
|
||||
@@ -34,6 +38,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
public class IrisPregenerator {
|
||||
private final PregenTask task;
|
||||
private final PregeneratorMethod generator;
|
||||
@@ -44,10 +49,11 @@ public class IrisPregenerator {
|
||||
private final RollingSequence chunksPerSecond;
|
||||
private final RollingSequence chunksPerMinute;
|
||||
private final RollingSequence regionsPerMinute;
|
||||
private final AtomicInteger generated;
|
||||
private final KList<Integer> chunksPerSecondHistory;
|
||||
private static AtomicInteger generated;
|
||||
private final AtomicInteger generatedLast;
|
||||
private final AtomicInteger generatedLastMinute;
|
||||
private final AtomicInteger totalChunks;
|
||||
private static AtomicInteger totalChunks;
|
||||
private final AtomicLong startTime;
|
||||
private final ChronoLatch minuteLatch;
|
||||
private final AtomicReference<String> currentGeneratorMethod;
|
||||
@@ -72,6 +78,7 @@ public class IrisPregenerator {
|
||||
chunksPerSecond = new RollingSequence(10);
|
||||
chunksPerMinute = new RollingSequence(10);
|
||||
regionsPerMinute = new RollingSequence(10);
|
||||
chunksPerSecondHistory = new KList<>();
|
||||
generated = new AtomicInteger(0);
|
||||
generatedLast = new AtomicInteger(0);
|
||||
generatedLastMinute = new AtomicInteger(0);
|
||||
@@ -85,6 +92,7 @@ public class IrisPregenerator {
|
||||
int secondGenerated = generated.get() - generatedLast.get();
|
||||
generatedLast.set(generated.get());
|
||||
chunksPerSecond.put(secondGenerated);
|
||||
chunksPerSecondHistory.add(secondGenerated);
|
||||
|
||||
if (minuteLatch.flip()) {
|
||||
int minuteGenerated = generated.get() - generatedLastMinute.get();
|
||||
@@ -101,19 +109,28 @@ public class IrisPregenerator {
|
||||
eta, M.ms() - startTime.get(), currentGeneratorMethod.get());
|
||||
|
||||
if (cl.flip()) {
|
||||
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (" + Form.pc((double) generated.get() / (double) totalChunks.get(), 0) + ") " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
|
||||
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
||||
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
||||
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
|
||||
} else {
|
||||
Iris.info("Benchmarking: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
|
||||
}
|
||||
}
|
||||
|
||||
return 1000;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private long computeETA() {
|
||||
return (long) ((totalChunks.get() - generated.get()) *
|
||||
((double) (M.ms() - startTime.get()) / (double) generated.get()));
|
||||
return (long) (totalChunks.get() > 1024 ? // Generated chunks exceed 1/8th of total?
|
||||
// If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers)
|
||||
((totalChunks.get() - generated.get()) * ((double) (M.ms() - startTime.get()) / (double) generated.get())) :
|
||||
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
|
||||
((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
shutdown.set(true);
|
||||
}
|
||||
@@ -125,6 +142,11 @@ public class IrisPregenerator {
|
||||
task.iterateRegions((x, z) -> visitRegion(x, z, true));
|
||||
task.iterateRegions((x, z) -> visitRegion(x, z, false));
|
||||
shutdown();
|
||||
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
||||
Iris.info(C.IRIS + "Pregen stopped.");
|
||||
} else {
|
||||
IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRegions() {
|
||||
@@ -141,7 +163,10 @@ public class IrisPregenerator {
|
||||
generator.close();
|
||||
ticker.interrupt();
|
||||
listener.onClose();
|
||||
getMantle().trim(0);
|
||||
Mantle mantle = getMantle();
|
||||
if (mantle != null) {
|
||||
mantle.trim(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitRegion(int x, int z, boolean regions) {
|
||||
@@ -0,0 +1,286 @@
|
||||
package com.volmit.iris.core.pregenerator;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LazyPregenerator extends Thread implements Listener {
|
||||
@Getter
|
||||
private static LazyPregenerator instance;
|
||||
private final LazyPregenJob job;
|
||||
private final File destination;
|
||||
private final int maxPosition;
|
||||
private World world;
|
||||
private final long rate;
|
||||
private final ChronoLatch latch;
|
||||
private static AtomicInteger lazyGeneratedChunks;
|
||||
private final AtomicInteger generatedLast;
|
||||
private final AtomicInteger lazyTotalChunks;
|
||||
private final AtomicLong startTime;
|
||||
private final RollingSequence chunksPerSecond;
|
||||
private final RollingSequence chunksPerMinute;
|
||||
|
||||
private static final Map<String, LazyPregenJob> jobs = new HashMap<>();
|
||||
|
||||
public LazyPregenerator(LazyPregenJob job, File destination) {
|
||||
this.job = job;
|
||||
this.destination = destination;
|
||||
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||
}).count();
|
||||
this.world = Bukkit.getWorld(job.getWorld());
|
||||
this.rate = Math.round((1D / (job.getChunksPerMinute() / 60D)) * 1000D);
|
||||
this.latch = new ChronoLatch(15000);
|
||||
this.startTime = new AtomicLong(M.ms());
|
||||
this.chunksPerSecond = new RollingSequence(10);
|
||||
this.chunksPerMinute = new RollingSequence(10);
|
||||
lazyGeneratedChunks = new AtomicInteger(0);
|
||||
this.generatedLast = new AtomicInteger(0);
|
||||
this.lazyTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
||||
jobs.put(job.getWorld(), job);
|
||||
LazyPregenerator.instance = this;
|
||||
}
|
||||
|
||||
public LazyPregenerator(File file) throws IOException {
|
||||
this(new Gson().fromJson(IO.readAll(file), LazyPregenJob.class), file);
|
||||
}
|
||||
|
||||
public static void loadLazyGenerators() {
|
||||
for (World i : Bukkit.getWorlds()) {
|
||||
File lazygen = new File(i.getWorldFolder(), "lazygen.json");
|
||||
if (lazygen.exists()) {
|
||||
try {
|
||||
LazyPregenerator p = new LazyPregenerator(lazygen);
|
||||
p.start();
|
||||
Iris.info("Started Lazy Pregenerator: " + p.job);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e) {
|
||||
if (e.getWorld().equals(world)) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (!interrupted()) {
|
||||
J.sleep(rate);
|
||||
tick();
|
||||
}
|
||||
|
||||
try {
|
||||
saveNow();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
LazyPregenJob job = jobs.get(world.getName());
|
||||
if (latch.flip() && !job.paused) {
|
||||
long eta = computeETA();
|
||||
save();
|
||||
int secondGenerated = lazyGeneratedChunks.get() - generatedLast.get();
|
||||
generatedLast.set(lazyGeneratedChunks.get());
|
||||
secondGenerated = secondGenerated / 15;
|
||||
chunksPerSecond.put(secondGenerated);
|
||||
chunksPerMinute.put(secondGenerated * 60);
|
||||
if (!job.isSilent()) {
|
||||
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(lazyGeneratedChunks.get()) + " of " + Form.f(lazyTotalChunks.get()) + " " + Form.f((int) chunksPerMinute.getAverage()) + "/m ETA: " + Form.duration((double) eta, 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (lazyGeneratedChunks.get() >= lazyTotalChunks.get()) {
|
||||
if (job.isHealing()) {
|
||||
int pos = (job.getHealingPosition() + 1) % maxPosition;
|
||||
job.setHealingPosition(pos);
|
||||
tickRegenerate(getChunk(pos));
|
||||
} else {
|
||||
Iris.info("Completed Lazy Gen!");
|
||||
interrupt();
|
||||
}
|
||||
} else {
|
||||
int pos = job.getPosition() + 1;
|
||||
job.setPosition(pos);
|
||||
if (!job.paused) {
|
||||
tickGenerate(getChunk(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long computeETA() {
|
||||
return (long) ((lazyTotalChunks.get() - lazyGeneratedChunks.get()) / chunksPerMinute.getAverage()) * 1000;
|
||||
// todo broken
|
||||
}
|
||||
|
||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
private void tickGenerate(Position2 chunk) {
|
||||
executorService.submit(() -> {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
if (PaperLib.isPaper()) {
|
||||
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
|
||||
.thenAccept((i) -> {
|
||||
Iris.verbose("Generated Async " + chunk);
|
||||
latch.countDown();
|
||||
});
|
||||
} else {
|
||||
J.s(() -> {
|
||||
world.getChunkAt(chunk.getX(), chunk.getZ());
|
||||
Iris.verbose("Generated " + chunk);
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException ignored) {}
|
||||
lazyGeneratedChunks.addAndGet(1);
|
||||
});
|
||||
}
|
||||
|
||||
private void tickRegenerate(Position2 chunk) {
|
||||
J.s(() -> world.regenerateChunk(chunk.getX(), chunk.getZ()));
|
||||
Iris.verbose("Regenerated " + chunk);
|
||||
}
|
||||
|
||||
public Position2 getChunk(int position) {
|
||||
int p = -1;
|
||||
AtomicInteger xx = new AtomicInteger();
|
||||
AtomicInteger zz = new AtomicInteger();
|
||||
Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||
xx.set(x);
|
||||
zz.set(z);
|
||||
});
|
||||
|
||||
while (s.hasNext() && p++ < position) {
|
||||
s.next();
|
||||
}
|
||||
|
||||
return new Position2(xx.get(), zz.get());
|
||||
}
|
||||
|
||||
public void save() {
|
||||
J.a(() -> {
|
||||
try {
|
||||
saveNow();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setPausedLazy(World world) {
|
||||
LazyPregenJob job = jobs.get(world.getName());
|
||||
if (isPausedLazy(world)){
|
||||
job.paused = false;
|
||||
} else {
|
||||
job.paused = true;
|
||||
}
|
||||
|
||||
if ( job.paused) {
|
||||
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||
} else {
|
||||
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPausedLazy(World world) {
|
||||
LazyPregenJob job = jobs.get(world.getName());
|
||||
return job != null && job.isPaused();
|
||||
}
|
||||
|
||||
public void shutdownInstance(World world) throws IOException {
|
||||
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||
LazyPregenJob job = jobs.get(world.getName());
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File lazyFile = new File(worldDirectory, "lazygen.json");
|
||||
|
||||
if (job == null) {
|
||||
Iris.error("No Lazygen job found for world: " + world.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!job.isPaused()) {
|
||||
job.setPaused(true);
|
||||
}
|
||||
save();
|
||||
jobs.remove(world.getName());
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (lazyFile.exists()){
|
||||
lazyFile.delete();
|
||||
J.sleep(1000);
|
||||
}
|
||||
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
|
||||
}
|
||||
}.runTaskLater(Iris.instance, 20L);
|
||||
} catch (Exception e) {
|
||||
Iris.error("Failed to shutdown Lazygen for " + world.getName());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
saveNow();
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void saveNow() throws IOException {
|
||||
IO.writeAll(this.destination, new Gson().toJson(job));
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class LazyPregenJob {
|
||||
private String world;
|
||||
@Builder.Default
|
||||
private int healingPosition = 0;
|
||||
@Builder.Default
|
||||
private boolean healing = false;
|
||||
@Builder.Default
|
||||
private int chunksPerMinute = 32;
|
||||
@Builder.Default
|
||||
private int radiusBlocks = 5000;
|
||||
@Builder.Default
|
||||
private int position = 0;
|
||||
@Builder.Default
|
||||
boolean silent = false;
|
||||
@Builder.Default
|
||||
boolean paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ public class PregenTask {
|
||||
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
|
||||
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
||||
|
||||
@Builder.Default
|
||||
private boolean gui = false;
|
||||
@Builder.Default
|
||||
private Position2 center = new Position2(0, 0);
|
||||
@Builder.Default
|
||||
@@ -0,0 +1,342 @@
|
||||
package com.volmit.iris.core.pregenerator;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.parallel.HyperLock;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import org.apache.logging.log4j.core.util.ExecutorServices;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.checkerframework.checker.units.qual.N;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class TurboPregenerator extends Thread implements Listener {
|
||||
@Getter
|
||||
private static TurboPregenerator instance;
|
||||
private final TurboPregenJob job;
|
||||
private final File destination;
|
||||
private final int maxPosition;
|
||||
private World world;
|
||||
private final ChronoLatch latch;
|
||||
private static AtomicInteger turboGeneratedChunks;
|
||||
private final AtomicInteger generatedLast;
|
||||
private final AtomicLong cachedLast;
|
||||
private final RollingSequence cachePerSecond;
|
||||
private final AtomicInteger turboTotalChunks;
|
||||
private final AtomicLong startTime;
|
||||
private final RollingSequence chunksPerSecond;
|
||||
private final RollingSequence chunksPerMinute;
|
||||
private KList<Position2> queue;
|
||||
private ConcurrentHashMap<Integer, Position2> cache;
|
||||
private AtomicInteger maxWaiting;
|
||||
private ReentrantLock cachinglock;
|
||||
private AtomicBoolean caching;
|
||||
private final HyperLock hyperLock;
|
||||
private MultiBurst burst;
|
||||
private static final Map<String, TurboPregenJob> jobs = new HashMap<>();
|
||||
|
||||
public TurboPregenerator(TurboPregenJob job, File destination) {
|
||||
this.job = job;
|
||||
queue = new KList<>(512);
|
||||
this.maxWaiting = new AtomicInteger(128);
|
||||
this.destination = destination;
|
||||
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||
}).count();
|
||||
this.world = Bukkit.getWorld(job.getWorld());
|
||||
this.latch = new ChronoLatch(3000);
|
||||
this.burst = MultiBurst.burst;
|
||||
this.hyperLock = new HyperLock();
|
||||
this.startTime = new AtomicLong(M.ms());
|
||||
this.cachePerSecond = new RollingSequence(10);
|
||||
this.chunksPerSecond = new RollingSequence(10);
|
||||
this.chunksPerMinute = new RollingSequence(10);
|
||||
turboGeneratedChunks = new AtomicInteger(0);
|
||||
this.generatedLast = new AtomicInteger(0);
|
||||
this.cachedLast = new AtomicLong(0);
|
||||
this.caching = new AtomicBoolean(false);
|
||||
this.turboTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
||||
cache = new ConcurrentHashMap<>(turboTotalChunks.get());
|
||||
this.cachinglock = new ReentrantLock();
|
||||
jobs.put(job.getWorld(), job);
|
||||
TurboPregenerator.instance = this;
|
||||
}
|
||||
|
||||
public TurboPregenerator(File file) throws IOException {
|
||||
this(new Gson().fromJson(IO.readAll(file), TurboPregenerator.TurboPregenJob.class), file);
|
||||
}
|
||||
|
||||
public static void loadTurboGenerator(String i) {
|
||||
World x = Bukkit.getWorld(i);
|
||||
File turbogen = new File(x.getWorldFolder(), "turbogen.json");
|
||||
if (turbogen.exists()) {
|
||||
try {
|
||||
TurboPregenerator p = new TurboPregenerator(turbogen);
|
||||
p.start();
|
||||
Iris.info("Started Turbo Pregenerator: " + p.job);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e) {
|
||||
if (e.getWorld().equals(world)) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (!interrupted()) {
|
||||
tick();
|
||||
}
|
||||
|
||||
try {
|
||||
saveNow();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
TurboPregenJob job = jobs.get(world.getName());
|
||||
if (!cachinglock.isLocked() && cache.isEmpty() && !caching.get()) {
|
||||
ExecutorService cache = Executors.newFixedThreadPool(1);
|
||||
cache.submit(this::cache);
|
||||
}
|
||||
|
||||
if (latch.flip() && caching.get()) {
|
||||
long secondCached = cache.mappingCount() - cachedLast.get();
|
||||
cachedLast.set(cache.mappingCount());
|
||||
secondCached = secondCached / 3;
|
||||
cachePerSecond.put(secondCached);
|
||||
Iris.info("TurboGen: " + C.IRIS + world.getName() + C.RESET + C.BLUE + " Caching: " + Form.f(cache.mappingCount()) + " of " + Form.f(turboTotalChunks.get()) + " " + Form.f((int) cachePerSecond.getAverage()) + "/s");
|
||||
}
|
||||
|
||||
if (latch.flip() && !job.paused && !cachinglock.isLocked()) {
|
||||
long eta = computeETA();
|
||||
save();
|
||||
int secondGenerated = turboGeneratedChunks.get() - generatedLast.get();
|
||||
generatedLast.set(turboGeneratedChunks.get());
|
||||
secondGenerated = secondGenerated / 3;
|
||||
chunksPerSecond.put(secondGenerated);
|
||||
chunksPerMinute.put(secondGenerated * 60);
|
||||
Iris.info("TurboGen: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(turboGeneratedChunks.get()) + " of " + Form.f(turboTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
|
||||
|
||||
}
|
||||
if (turboGeneratedChunks.get() >= turboTotalChunks.get()) {
|
||||
Iris.info("Completed Turbo Gen!");
|
||||
interrupt();
|
||||
} else {
|
||||
if (!cachinglock.isLocked()) {
|
||||
int pos = job.getPosition() + 1;
|
||||
job.setPosition(pos);
|
||||
if (!job.paused) {
|
||||
if (queue.size() < maxWaiting.get()) {
|
||||
Position2 chunk = cache.get(pos);
|
||||
queue.add(chunk);
|
||||
}
|
||||
waitForChunksPartial();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cache() {
|
||||
if (!cachinglock.isLocked()) {
|
||||
cachinglock.lock();
|
||||
caching.set(true);
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
BurstExecutor b = MultiBurst.burst.burst(turboTotalChunks.get());
|
||||
b.setMulticore(true);
|
||||
int[] list = IntStream.rangeClosed(0, turboTotalChunks.get()).toArray();
|
||||
AtomicInteger order = new AtomicInteger(turboTotalChunks.get());
|
||||
|
||||
int threads = Runtime.getRuntime().availableProcessors();
|
||||
if (threads > 1) threads--;
|
||||
ExecutorService process = Executors.newFixedThreadPool(threads);
|
||||
|
||||
for (int id : list) {
|
||||
b.queue(() -> {
|
||||
cache.put(id, getChunk(id));
|
||||
order.addAndGet(-1);
|
||||
});
|
||||
}
|
||||
b.complete();
|
||||
|
||||
if (order.get() < 0) {
|
||||
cachinglock.unlock();
|
||||
caching.set(false);
|
||||
Iris.info("Completed Caching in: " + Form.duration(p.getMilliseconds(), 2));
|
||||
}
|
||||
} else {
|
||||
Iris.error("TurboCache is locked!");
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForChunksPartial() {
|
||||
while (!queue.isEmpty() && maxWaiting.get() > queue.size()) {
|
||||
try {
|
||||
for (Position2 c : new KList<>(queue)) {
|
||||
tickGenerate(c);
|
||||
queue.remove(c);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long computeETA() {
|
||||
return (long) ((turboTotalChunks.get() - turboGeneratedChunks.get()) / chunksPerMinute.getAverage()) * 1000;
|
||||
// todo broken
|
||||
}
|
||||
|
||||
private final ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||
private void tickGenerate(Position2 chunk) {
|
||||
executorService.submit(() -> {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
|
||||
.thenAccept((i) -> {
|
||||
latch.countDown();
|
||||
});
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
turboGeneratedChunks.addAndGet(1);
|
||||
});
|
||||
}
|
||||
|
||||
public Position2 getChunk(int position) {
|
||||
int p = -1;
|
||||
AtomicInteger xx = new AtomicInteger();
|
||||
AtomicInteger zz = new AtomicInteger();
|
||||
Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||
xx.set(x);
|
||||
zz.set(z);
|
||||
});
|
||||
|
||||
while (s.hasNext() && p++ < position) {
|
||||
s.next();
|
||||
}
|
||||
|
||||
return new Position2(xx.get(), zz.get());
|
||||
}
|
||||
|
||||
public void save() {
|
||||
J.a(() -> {
|
||||
try {
|
||||
saveNow();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setPausedTurbo(World world) {
|
||||
TurboPregenJob job = jobs.get(world.getName());
|
||||
if (isPausedTurbo(world)) {
|
||||
job.paused = false;
|
||||
} else {
|
||||
job.paused = true;
|
||||
}
|
||||
|
||||
if (job.paused) {
|
||||
Iris.info(C.BLUE + "TurboGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||
} else {
|
||||
Iris.info(C.BLUE + "TurboGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPausedTurbo(World world) {
|
||||
TurboPregenJob job = jobs.get(world.getName());
|
||||
return job != null && job.isPaused();
|
||||
}
|
||||
|
||||
public void shutdownInstance(World world) throws IOException {
|
||||
Iris.info("turboGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||
TurboPregenJob job = jobs.get(world.getName());
|
||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||
File turboFile = new File(worldDirectory, "turbogen.json");
|
||||
|
||||
if (job == null) {
|
||||
Iris.error("No turbogen job found for world: " + world.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!job.isPaused()) {
|
||||
job.setPaused(true);
|
||||
}
|
||||
save();
|
||||
jobs.remove(world.getName());
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (turboFile.exists()) {
|
||||
turboFile.delete();
|
||||
J.sleep(1000);
|
||||
}
|
||||
Iris.info("turboGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
|
||||
}
|
||||
}.runTaskLater(Iris.instance, 20L);
|
||||
} catch (Exception e) {
|
||||
Iris.error("Failed to shutdown turbogen for " + world.getName());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
saveNow();
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void saveNow() throws IOException {
|
||||
IO.writeAll(this.destination, new Gson().toJson(job));
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class TurboPregenJob {
|
||||
private String world;
|
||||
@Builder.Default
|
||||
private int radiusBlocks = 5000;
|
||||
@Builder.Default
|
||||
private int position = 0;
|
||||
@Builder.Default
|
||||
boolean paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,20 +23,28 @@ import com.volmit.iris.core.pregenerator.PregenListener;
|
||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
private final World world;
|
||||
private final MultiBurst burst;
|
||||
private final KList<Future<?>> future;
|
||||
private final Map<Chunk, Long> lastUse;
|
||||
|
||||
public AsyncPregenMethod(World world, int threads) {
|
||||
if (!PaperLib.isPaper()) {
|
||||
@@ -46,6 +54,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
this.world = world;
|
||||
burst = MultiBurst.burst;
|
||||
future = new KList<>(1024);
|
||||
this.lastUse = new KMap<>();
|
||||
}
|
||||
|
||||
private void unloadAndSaveAllChunks() {
|
||||
@@ -56,8 +65,12 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Chunk i : world.getLoadedChunks()) {
|
||||
i.unload(true);
|
||||
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||
Long lastUseTime = lastUse.get(i);
|
||||
if (lastUseTime != null && M.ms() - lastUseTime >= 10000) {
|
||||
i.unload();
|
||||
lastUse.remove(i);
|
||||
}
|
||||
}
|
||||
world.save();
|
||||
}).get();
|
||||
@@ -72,7 +85,8 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
if (i == null) {
|
||||
|
||||
}
|
||||
|
||||
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
||||
lastUse.put(c, M.ms());
|
||||
listener.onChunkGenerated(x, z);
|
||||
listener.onChunkCleaned(x, z);
|
||||
return 0;
|
||||
@@ -18,25 +18,33 @@
|
||||
|
||||
package com.volmit.iris.core.pregenerator.methods;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class MedievalPregenMethod implements PregeneratorMethod {
|
||||
private final World world;
|
||||
private final KList<CompletableFuture<?>> futures;
|
||||
private final Map<Chunk, Long> lastUse;
|
||||
|
||||
public MedievalPregenMethod(World world) {
|
||||
this.world = world;
|
||||
futures = new KList<>();
|
||||
this.lastUse = new KMap<>();
|
||||
}
|
||||
|
||||
private void waitForChunks() {
|
||||
@@ -52,11 +60,19 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
||||
}
|
||||
|
||||
private void unloadAndSaveAllChunks() {
|
||||
waitForChunks();
|
||||
try {
|
||||
J.sfut(() -> {
|
||||
for (Chunk i : world.getLoadedChunks()) {
|
||||
i.unload(true);
|
||||
if (world == null) {
|
||||
Iris.warn("World was null somehow...");
|
||||
return;
|
||||
}
|
||||
|
||||
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||
Long lastUseTime = lastUse.get(i);
|
||||
if (lastUseTime != null && M.ms() - lastUseTime >= 10) {
|
||||
i.unload();
|
||||
lastUse.remove(i);
|
||||
}
|
||||
}
|
||||
world.save();
|
||||
}).get();
|
||||
@@ -104,6 +120,8 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
||||
listener.onChunkGenerating(x, z);
|
||||
futures.add(J.sfut(() -> {
|
||||
world.getChunkAt(x, z);
|
||||
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
||||
lastUse.put(c, M.ms());
|
||||
listener.onChunkGenerated(x, z);
|
||||
listener.onChunkCleaned(x, z);
|
||||
}));
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
public class IrisSafeguard {
|
||||
public static boolean unstablemode = false;
|
||||
public static boolean warningmode = false;
|
||||
public static boolean stablemode = false;
|
||||
|
||||
public static void IrisSafeguardSystem() {
|
||||
Iris.info("Enabled Iris SafeGuard");
|
||||
ServerBootSFG.BootCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.util.format.C;
|
||||
|
||||
public class ModesSFG {
|
||||
public static void selectMode() {
|
||||
if (IrisSafeguard.unstablemode) {
|
||||
Iris.safeguard(C.DARK_RED + "Iris is running in Unstable Mode");
|
||||
unstable();
|
||||
}
|
||||
if (IrisSafeguard.warningmode) {
|
||||
Iris.safeguard(C.GOLD + "Iris is running in Warning Mode");
|
||||
warning();
|
||||
}
|
||||
if (IrisSafeguard.stablemode) {
|
||||
stable();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stable() {
|
||||
Iris.safeguard(C.BLUE + "Iris is running Stable");
|
||||
}
|
||||
|
||||
public static void unstable() {
|
||||
|
||||
UtilsSFG.printIncompatibleWarnings();
|
||||
|
||||
if (IrisSafeguard.unstablemode) {
|
||||
Iris.info("");
|
||||
Iris.info(C.DARK_GRAY + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||
Iris.info(C.RED + "Iris is running in unstable mode which may cause the following issues:");
|
||||
Iris.info(C.DARK_RED + "Server Issues");
|
||||
Iris.info(C.RED + "- Server won't boot");
|
||||
Iris.info(C.RED + "- Data Loss");
|
||||
Iris.info(C.RED + "- Unexpected behavior.");
|
||||
Iris.info(C.RED + "- And More...");
|
||||
Iris.info(C.DARK_RED + "World Issues");
|
||||
Iris.info(C.RED + "- Worlds can't load due to corruption.");
|
||||
Iris.info(C.RED + "- Worlds may slowly corrupt until they can't load.");
|
||||
Iris.info(C.RED + "- World data loss.");
|
||||
Iris.info(C.RED + "- And More...");
|
||||
Iris.info(C.DARK_RED + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.");
|
||||
Iris.info(C.DARK_RED + "CAUSE: " + C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||
|
||||
if (IrisSettings.get().getGeneral().ignoreBootMode) {
|
||||
Iris.info(C.DARK_RED + "Boot Unstable is set to true, continuing with the startup process.");
|
||||
} else {
|
||||
Iris.info(C.DARK_RED + "Go to plugins/iris/settings.json and set ignoreBootMode to true if you wish to proceed.");
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// no
|
||||
}
|
||||
}
|
||||
}
|
||||
Iris.info("");
|
||||
}
|
||||
}
|
||||
|
||||
public static void warning() {
|
||||
|
||||
UtilsSFG.printIncompatibleWarnings();
|
||||
|
||||
if (IrisSafeguard.warningmode) {
|
||||
Iris.info("");
|
||||
Iris.info(C.DARK_GRAY + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||
Iris.info(C.GOLD + "Iris is running in warning mode which may cause the following issues:");
|
||||
Iris.info(C.YELLOW + "- Data Loss");
|
||||
Iris.info(C.YELLOW + "- Errors");
|
||||
Iris.info(C.YELLOW + "- Broken worlds");
|
||||
Iris.info(C.YELLOW + "- Unexpected behavior.");
|
||||
Iris.info(C.YELLOW + "- And perhaps further complications.");
|
||||
Iris.info(C.GOLD + "CAUSE: " + C.YELLOW + UtilsSFG.MSGIncompatibleWarnings());
|
||||
Iris.info("");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
public class PerformanceSFG {
|
||||
public static void calculatePerformance() {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.File;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import static com.volmit.iris.Iris.getJavaVersion;
|
||||
import static com.volmit.iris.Iris.instance;
|
||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||
|
||||
public class ServerBootSFG {
|
||||
public static final Map<String, Boolean> incompatibilities = new HashMap<>();
|
||||
public static boolean isJDK17 = true;
|
||||
public static boolean hasEnoughDiskSpace = true;
|
||||
public static boolean isJRE = false;
|
||||
public static boolean hasPrivileges = true;
|
||||
public static boolean unsuportedversion = false;
|
||||
protected static boolean safeguardPassed;
|
||||
public static boolean passedserversoftware = true;
|
||||
protected static int count;
|
||||
protected static byte severityLow;
|
||||
protected static byte severityMedium;
|
||||
protected static byte severityHigh;
|
||||
public static String allIncompatibilities;
|
||||
|
||||
public static void BootCheck() {
|
||||
Iris.info("Checking for possible conflicts..");
|
||||
org.bukkit.plugin.PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
Plugin[] plugins = pluginManager.getPlugins();
|
||||
|
||||
incompatibilities.clear();
|
||||
incompatibilities.put("Multiverse-Core", false);
|
||||
incompatibilities.put("dynmap", false);
|
||||
incompatibilities.put("TerraformGenerator", false);
|
||||
incompatibilities.put("Stratos", false);
|
||||
|
||||
String pluginName;
|
||||
for (Plugin plugin : plugins) {
|
||||
pluginName = plugin.getName();
|
||||
Boolean flag = incompatibilities.get(pluginName);
|
||||
if (flag != null && !flag) {
|
||||
severityHigh++;
|
||||
incompatibilities.put(pluginName, true);
|
||||
}
|
||||
}
|
||||
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (Map.Entry<String, Boolean> entry : incompatibilities.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
joiner.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
if (
|
||||
!instance.getServer().getVersion().contains("Purpur") &&
|
||||
!instance.getServer().getVersion().contains("Paper") &&
|
||||
!instance.getServer().getVersion().contains("Spigot") &&
|
||||
!instance.getServer().getVersion().contains("Pufferfish") &&
|
||||
!instance.getServer().getVersion().contains("Bukkit")) {
|
||||
passedserversoftware = false;
|
||||
joiner.add("Server Software");
|
||||
severityHigh++;
|
||||
}
|
||||
|
||||
if (INMS.get() instanceof NMSBinding1X) {
|
||||
unsuportedversion = true;
|
||||
joiner.add("Unsupported Minecraft Version");
|
||||
severityHigh++;
|
||||
}
|
||||
|
||||
if (getJavaVersion() != 17) {
|
||||
isJDK17 = false;
|
||||
joiner.add("Unsupported Java version");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
if (!isJDK()) {
|
||||
isJRE = true;
|
||||
joiner.add("Unsupported JDK");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
// if (!hasPrivileges()){
|
||||
// hasPrivileges = false;
|
||||
// joiner.add("Insufficient Privileges");
|
||||
// severityMedium++;
|
||||
// } Some servers dont like this
|
||||
|
||||
if (!enoughDiskSpace()){
|
||||
hasEnoughDiskSpace = false;
|
||||
joiner.add("Insufficient Disk Space");
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
allIncompatibilities = joiner.toString();
|
||||
|
||||
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
||||
count = severityHigh + severityMedium + severityLow;
|
||||
if (safeguardPassed) {
|
||||
stablemode = true;
|
||||
Iris.safeguard("Stable mode has been activated.");
|
||||
}
|
||||
if (!safeguardPassed) {
|
||||
if (severityMedium >= 1 && severityHigh == 0) {
|
||||
warningmode = true;
|
||||
Iris.safeguard("Warning mode has been activated.");
|
||||
}
|
||||
if (severityHigh >= 1) {
|
||||
unstablemode = true;
|
||||
Iris.safeguard("Unstable mode has been activated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isJDK() {
|
||||
try {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
// If the compiler is null, it means this is a JRE environment, not a JDK.
|
||||
return compiler != null;
|
||||
} catch (Exception ignored) {}
|
||||
return false;
|
||||
}
|
||||
public static boolean hasPrivileges() {
|
||||
Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json");
|
||||
try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
|
||||
if (Files.isReadable(pv) && Files.isWritable(pv)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean enoughDiskSpace() {
|
||||
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
||||
double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0);
|
||||
if (gigabytes > 3){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkJavac(String path) {
|
||||
return !path.isEmpty() && (new File(path, "javac").exists() || new File(path, "javac.exe").exists());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.format.C;
|
||||
|
||||
public class UtilsSFG {
|
||||
public static void splash() {
|
||||
ModesSFG.selectMode();
|
||||
}
|
||||
|
||||
public static void printIncompatibleWarnings() {
|
||||
// String SupportedIrisVersion = getDescription().getVersion(); //todo Automatic version
|
||||
|
||||
if (ServerBootSFG.safeguardPassed) {
|
||||
Iris.safeguard(C.BLUE + "0 Conflicts found");
|
||||
} else {
|
||||
if (IrisSafeguard.unstablemode) {
|
||||
Iris.safeguard(C.DARK_RED + "" + ServerBootSFG.count + " Conflicts found");
|
||||
}
|
||||
if (IrisSafeguard.warningmode) {
|
||||
Iris.safeguard(C.YELLOW + "" + ServerBootSFG.count + " Conflicts found");
|
||||
}
|
||||
|
||||
if (ServerBootSFG.incompatibilities.get("Multiverse-Core")) {
|
||||
Iris.safeguard(C.RED + "Multiverse");
|
||||
Iris.safeguard(C.RED + "- The plugin Multiverse is not compatible with the server.");
|
||||
Iris.safeguard(C.RED + "- If you want to have a world manager, consider using PhantomWorlds or MyWorlds instead.");
|
||||
}
|
||||
if (ServerBootSFG.incompatibilities.get("dynmap")) {
|
||||
Iris.safeguard(C.RED + "Dynmap");
|
||||
Iris.safeguard(C.RED + "- The plugin Dynmap is not compatible with the server.");
|
||||
Iris.safeguard(C.RED + "- If you want to have a map plugin like Dynmap, consider Bluemap.");
|
||||
}
|
||||
if (ServerBootSFG.incompatibilities.get("TerraformGenerator") || ServerBootSFG.incompatibilities.get("Stratos")) {
|
||||
Iris.safeguard(C.YELLOW + "Terraform Generator / Stratos");
|
||||
Iris.safeguard(C.YELLOW + "- Iris is not compatible with other worldgen plugins.");
|
||||
}
|
||||
if (ServerBootSFG.unsuportedversion) {
|
||||
Iris.safeguard(C.RED + "Server Version");
|
||||
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.20.4");
|
||||
}
|
||||
if (!ServerBootSFG.passedserversoftware) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead.");
|
||||
}
|
||||
if (!ServerBootSFG.hasPrivileges) {
|
||||
Iris.safeguard(C.YELLOW + "Insufficient Privileges");
|
||||
Iris.safeguard(C.YELLOW + "- The server has insufficient Privileges to run iris. Please contact support.");
|
||||
}
|
||||
if (!ServerBootSFG.hasEnoughDiskSpace) {
|
||||
Iris.safeguard(C.YELLOW + "Insufficient Disk Space");
|
||||
Iris.safeguard(C.YELLOW + "- The server has insufficient Free DiskSpace to run iris required 3GB+.");
|
||||
}
|
||||
if (!ServerBootSFG.isJDK17) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 Instead of JDK " + Iris.getJavaVersion());
|
||||
}
|
||||
if (ServerBootSFG.isJRE) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported Server JDK");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 Instead of JRE " + Iris.getJavaVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String MSGIncompatibleWarnings() {
|
||||
return ServerBootSFG.allIncompatibilities;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
@@ -124,17 +125,32 @@ public class BoardSVC implements IrisService, BoardProvider {
|
||||
int y = player.getLocation().getBlockY() - player.getWorld().getMinHeight();
|
||||
int z = player.getLocation().getBlockZ();
|
||||
|
||||
lines.add("&7&m ");
|
||||
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
||||
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
||||
lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount());
|
||||
lines.add("&7&m ");
|
||||
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
||||
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z) + player.getWorld().getMinHeight()));
|
||||
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
||||
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||
lines.add("&7&m ");
|
||||
if(IrisSettings.get().getGeneral().debug){
|
||||
lines.add("&7&m ");
|
||||
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
||||
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
||||
lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount());
|
||||
lines.add(C.LIGHT_PURPLE + "Carving" + C.GRAY + ": " + engine.getMantle().isCarved(x,y,z));
|
||||
lines.add("&7&m ");
|
||||
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
||||
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
||||
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
||||
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||
lines.add("&7&m ");
|
||||
} else {
|
||||
lines.add("&7&m ");
|
||||
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
||||
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
||||
lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount());
|
||||
lines.add("&7&m ");
|
||||
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
||||
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
||||
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
||||
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||
lines.add("&7&m ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +1,93 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||
import com.volmit.iris.util.function.Consumer4;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.matter.MatterStructurePOI;
|
||||
import com.volmit.iris.util.plugin.IrisService;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftDolphin;
|
||||
import org.bukkit.entity.Dolphin;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.generator.structure.StructureType;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class DolphinSVC implements IrisService {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerInteractEntityEvent event) {
|
||||
if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material hand = event.getPlayer().getInventory().getItem(event.getHand()).getType();
|
||||
if (event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))) {
|
||||
Engine e = IrisToolbelt.access(event.getPlayer().getWorld()).getEngine();
|
||||
searchNearestTreasure(e, event.getPlayer().getLocation().getBlockX() >> 4, event.getPlayer().getLocation().getBlockZ() >> 4, e.getMantle().getRadius() - 1, StructureType.BURIED_TREASURE, (x, y, z, p) -> {
|
||||
event.setCancelled(true);
|
||||
Dolphin d = (Dolphin) event.getRightClicked();
|
||||
CraftDolphin cd = (CraftDolphin) d;
|
||||
d.getWorld().playSound(d, Sound.ENTITY_DOLPHIN_EAT, SoundCategory.NEUTRAL, 1, 1);
|
||||
cd.getHandle().setTreasurePos(new BlockPos(x, y, z));
|
||||
cd.getHandle().setGotFish(true);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
public void findTreasure(Engine engine, int chunkX, int chunkY, StructureType type, Consumer4<Integer, Integer, Integer, MatterStructurePOI> consumer) {
|
||||
AtomicReference<MatterStructurePOI> ref = new AtomicReference<>();
|
||||
engine.getMantle().getMantle().iterateChunk(chunkX, chunkY, MatterStructurePOI.class, ref.get() == null ? (x, y, z, d) -> {
|
||||
if (d.getType().equals(type.getKey().getKey())) {
|
||||
ref.set(d);
|
||||
consumer.accept(x, y, z, d);
|
||||
}
|
||||
} : (x, y, z, d) -> {
|
||||
});
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
public void searchNearestTreasure(Engine engine, int chunkX, int chunkY, int radius, StructureType type, Consumer4<Integer, Integer, Integer, MatterStructurePOI> consumer) {
|
||||
AtomicReference<MatterStructurePOI> ref = new AtomicReference<>();
|
||||
new Spiraler(radius * 2, radius * 2, (x, z) -> findTreasure(engine, x, z, type, ref.get() == null ? (i, d, g, a) -> {
|
||||
ref.set(a);
|
||||
consumer.accept(i, d, g, a);
|
||||
} : (i, d, g, a) -> {
|
||||
})).setOffset(chunkX, chunkY).drain();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.container.BlockPos;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||
import com.volmit.iris.util.function.Consumer4;
|
||||
import com.volmit.iris.util.math.Spiraler;
|
||||
import com.volmit.iris.util.matter.MatterStructurePOI;
|
||||
import com.volmit.iris.util.plugin.IrisService;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.entity.Dolphin;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.generator.structure.StructureType;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class DolphinSVC implements IrisService {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerInteractEntityEvent event) {
|
||||
if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material hand = event.getPlayer().getInventory().getItem(event.getHand()).getType();
|
||||
if (event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))) {
|
||||
Engine e = IrisToolbelt.access(event.getPlayer().getWorld()).getEngine();
|
||||
searchNearestTreasure(e, event.getPlayer().getLocation().getBlockX() >> 4, event.getPlayer().getLocation().getBlockZ() >> 4, e.getMantle().getRadius() - 1, StructureType.BURIED_TREASURE, (x, y, z, p) -> {
|
||||
event.setCancelled(true);
|
||||
Dolphin d = (Dolphin) event.getRightClicked();
|
||||
INMS.get().setTreasurePos(d, new BlockPos(x, y, z));
|
||||
d.getWorld().playSound(d, Sound.ENTITY_DOLPHIN_EAT, SoundCategory.NEUTRAL, 1, 1);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
public void findTreasure(Engine engine, int chunkX, int chunkY, StructureType type, Consumer4<Integer, Integer, Integer, MatterStructurePOI> consumer) {
|
||||
AtomicReference<MatterStructurePOI> ref = new AtomicReference<>();
|
||||
engine.getMantle().getMantle().iterateChunk(chunkX, chunkY, MatterStructurePOI.class, ref.get() == null ? (x, y, z, d) -> {
|
||||
if (d.getType().equals(type.getKey().getKey())) {
|
||||
ref.set(d);
|
||||
consumer.accept(x, y, z, d);
|
||||
}
|
||||
} : (x, y, z, d) -> {
|
||||
});
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
public void searchNearestTreasure(Engine engine, int chunkX, int chunkY, int radius, StructureType type, Consumer4<Integer, Integer, Integer, MatterStructurePOI> consumer) {
|
||||
AtomicReference<MatterStructurePOI> ref = new AtomicReference<>();
|
||||
new Spiraler(radius * 2, radius * 2, (x, z) -> findTreasure(engine, x, z, type, ref.get() == null ? (i, d, g, a) -> {
|
||||
ref.set(a);
|
||||
consumer.accept(i, d, g, a);
|
||||
} : (i, d, g, a) -> {
|
||||
})).setOffset(chunkX, chunkY).drain();
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.bukkit.event.world.WorldUnloadEvent;
|
||||
|
||||
public class EditSVC implements IrisService {
|
||||
private KMap<World, BlockEditor> editors;
|
||||
public static boolean deletingWorld = false;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -71,11 +72,12 @@ public class EditSVC implements IrisService {
|
||||
|
||||
@EventHandler
|
||||
public void on(WorldUnloadEvent e) {
|
||||
if (editors.containsKey(e.getWorld())) {
|
||||
if (editors.containsKey(e.getWorld()) && !deletingWorld) {
|
||||
editors.remove(e.getWorld()).close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void update() {
|
||||
for (World i : editors.k()) {
|
||||
if (M.ms() - editors.get(i).last() > 1000) {
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.link.*;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.plugin.IrisService;
|
||||
import lombok.Data;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Optional;
|
||||
|
||||
@Data
|
||||
public class ExternalDataSVC implements IrisService {
|
||||
|
||||
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
Iris.info("Loading ExternalDataProvider...");
|
||||
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
|
||||
|
||||
providers.add(new OraxenDataProvider());
|
||||
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
|
||||
Iris.info("Oraxen found, loading OraxenDataProvider...");
|
||||
}
|
||||
providers.add(new ItemAdderDataProvider());
|
||||
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
|
||||
Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
|
||||
}
|
||||
providers.add(new ExecutableItemsDataProvider());
|
||||
if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) {
|
||||
Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider...");
|
||||
}
|
||||
providers.add(new HMCLeavesDataProvider());
|
||||
if (Bukkit.getPluginManager().getPlugin("HMCLeaves") != null) {
|
||||
Iris.info("BlockAdder found, loading HMCLeavesDataProvider...");
|
||||
}
|
||||
providers.add(new MMOItemsDataProvider());
|
||||
if (Bukkit.getPluginManager().getPlugin("MMOItems") != null) {
|
||||
Iris.info("MMOItems found, loading MMOItemsDataProvider...");
|
||||
}
|
||||
|
||||
for (ExternalDataProvider p : providers) {
|
||||
if (p.isReady()) {
|
||||
activeProviders.add(p);
|
||||
p.init();
|
||||
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent e) {
|
||||
if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
|
||||
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
|
||||
activeProviders.add(edp);
|
||||
edp.init();
|
||||
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<BlockData> getBlockData(Identifier key) {
|
||||
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
|
||||
if (provider.isEmpty())
|
||||
return Optional.empty();
|
||||
try {
|
||||
return Optional.of(provider.get().getBlockData(key));
|
||||
} catch (MissingResourceException e) {
|
||||
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<ItemStack> getItemStack(Identifier key) {
|
||||
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst();
|
||||
if (provider.isEmpty()) {
|
||||
Iris.warn("No matching Provider found for modded material \"%s\"!", key);
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(provider.get().getItemStack(key));
|
||||
} catch (MissingResourceException e) {
|
||||
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, false)).findFirst();
|
||||
if (provider.isEmpty()) {
|
||||
Iris.warn("No matching Provider found for modded material \"%s\"!", blockId);
|
||||
return;
|
||||
}
|
||||
provider.get().processUpdate(engine, block, blockId);
|
||||
}
|
||||
|
||||
public Identifier[] getAllBlockIdentifiers() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
activeProviders.forEach(p -> names.add(p.getBlockTypes()));
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
|
||||
public Identifier[] getAllItemIdentifiers() {
|
||||
KList<Identifier> names = new KList<>();
|
||||
activeProviders.forEach(p -> names.add(p.getItemTypes()));
|
||||
return names.toArray(new Identifier[0]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.mantle.TectonicPlate;
|
||||
import com.volmit.iris.util.misc.getHardware;
|
||||
import com.volmit.iris.util.plugin.IrisService;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.Looper;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.ServerLoadEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class IrisEngineSVC implements IrisService {
|
||||
public static IrisEngineSVC instance;
|
||||
public boolean isServerShuttingDown = false;
|
||||
public boolean isServerLoaded = false;
|
||||
private static final AtomicInteger tectonicLimit = new AtomicInteger(30);
|
||||
private ReentrantLock lastUseLock;
|
||||
private KMap<World, Long> lastUse;
|
||||
private List<World> IrisWorlds;
|
||||
private Looper cacheTicker;
|
||||
private Looper trimTicker;
|
||||
private Looper unloadTicker;
|
||||
private Looper updateTicker;
|
||||
private PrecisionStopwatch trimAlive;
|
||||
private PrecisionStopwatch unloadAlive;
|
||||
public PrecisionStopwatch trimActiveAlive;
|
||||
public PrecisionStopwatch unloadActiveAlive;
|
||||
private AtomicInteger TotalTectonicPlates;
|
||||
private AtomicInteger TotalQueuedTectonicPlates;
|
||||
private AtomicInteger TotalNotQueuedTectonicPlates;
|
||||
private AtomicBoolean IsUnloadAlive;
|
||||
private AtomicBoolean IsTrimAlive;
|
||||
ChronoLatch cl;
|
||||
|
||||
public List<World> corruptedIrisWorlds = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
this.cl = new ChronoLatch(5000);
|
||||
lastUse = new KMap<>();
|
||||
lastUseLock = new ReentrantLock();
|
||||
IrisWorlds = new ArrayList<>();
|
||||
IsUnloadAlive = new AtomicBoolean(true);
|
||||
IsTrimAlive = new AtomicBoolean(true);
|
||||
trimActiveAlive = new PrecisionStopwatch();
|
||||
unloadActiveAlive = new PrecisionStopwatch();
|
||||
trimAlive = new PrecisionStopwatch();
|
||||
unloadAlive = new PrecisionStopwatch();
|
||||
TotalTectonicPlates = new AtomicInteger();
|
||||
TotalQueuedTectonicPlates = new AtomicInteger();
|
||||
TotalNotQueuedTectonicPlates = new AtomicInteger();
|
||||
tectonicLimit.set(2);
|
||||
long t = getHardware.getProcessMemory();
|
||||
while (t > 200) {
|
||||
tectonicLimit.getAndAdd(1);
|
||||
t = t - 200;
|
||||
}
|
||||
this.setup();
|
||||
trimAlive.begin();
|
||||
unloadAlive.begin();
|
||||
trimActiveAlive.begin();
|
||||
unloadActiveAlive.begin();
|
||||
|
||||
updateTicker.start();
|
||||
cacheTicker.start();
|
||||
trimTicker.start();
|
||||
unloadTicker.start();
|
||||
instance = this;
|
||||
|
||||
}
|
||||
|
||||
public void engineStatus() {
|
||||
boolean trimAlive = trimTicker.isAlive();
|
||||
boolean unloadAlive = unloadTicker.isAlive();
|
||||
Iris.info("Status:");
|
||||
Iris.info("- Trim: " + trimAlive);
|
||||
Iris.info("- Unload: " + unloadAlive);
|
||||
|
||||
}
|
||||
|
||||
public static int getTectonicLimit() {
|
||||
return tectonicLimit.get();
|
||||
}
|
||||
|
||||
public void EngineReport() {
|
||||
Iris.info(C.RED + "CRITICAL ENGINE FAILURE! The Tectonic Trim subsystem has not responded for: " + Form.duration(trimAlive.getMillis()) + ".");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldUnload(WorldUnloadEvent event) {
|
||||
updateWorlds();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldLoad(WorldLoadEvent event) {
|
||||
updateWorlds();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerBoot(ServerLoadEvent event) {
|
||||
isServerLoaded = true;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
if (event.getPlugin().equals(Iris.instance)) {
|
||||
isServerShuttingDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateWorlds() {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
try {
|
||||
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||
IrisWorlds.add(world);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// no
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
cacheTicker = new Looper() {
|
||||
@Override
|
||||
protected long loop() {
|
||||
long now = System.currentTimeMillis();
|
||||
lastUseLock.lock();
|
||||
try {
|
||||
for (World key : new ArrayList<>(lastUse.keySet())) {
|
||||
Long last = lastUse.get(key);
|
||||
if (last == null)
|
||||
continue;
|
||||
if (now - last > 60000) {
|
||||
lastUse.remove(key);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lastUseLock.unlock();
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
};
|
||||
|
||||
updateTicker = new Looper() {
|
||||
@Override
|
||||
protected long loop() {
|
||||
try {
|
||||
TotalQueuedTectonicPlates.set(0);
|
||||
TotalNotQueuedTectonicPlates.set(0);
|
||||
TotalTectonicPlates.set(0);
|
||||
for (World world : IrisWorlds) {
|
||||
Engine engine = Objects.requireNonNull(IrisToolbelt.access(world)).getEngine();
|
||||
TotalQueuedTectonicPlates.addAndGet((int) engine.getMantle().getToUnload());
|
||||
TotalNotQueuedTectonicPlates.addAndGet((int) engine.getMantle().getNotQueuedLoadedRegions());
|
||||
TotalTectonicPlates.addAndGet(engine.getMantle().getLoadedRegionCount());
|
||||
}
|
||||
if (!isServerShuttingDown && isServerLoaded) {
|
||||
if (!trimTicker.isAlive()) {
|
||||
Iris.info(C.IRIS + "TrimTicker found dead! Booting it up!");
|
||||
try {
|
||||
trimTicker.start();
|
||||
} catch (Exception e) {
|
||||
Iris.error("What happened?");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!unloadTicker.isAlive()) {
|
||||
Iris.info(C.IRIS + "UnloadTicker found dead! Booting it up!");
|
||||
try {
|
||||
unloadTicker.start();
|
||||
} catch (Exception e) {
|
||||
Iris.error("What happened?");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
};
|
||||
|
||||
trimTicker = new Looper() {
|
||||
private final Supplier<Engine> supplier = createSupplier();
|
||||
@Override
|
||||
protected long loop() {
|
||||
long start = System.currentTimeMillis();
|
||||
trimAlive.reset();
|
||||
try {
|
||||
Engine engine = supplier.get();
|
||||
if (engine != null) {
|
||||
engine.getMantle().trim(tectonicLimit.get() / lastUse.size());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
Iris.info(C.RED + "EngineSVC: Failed to trim. Please contact support!");
|
||||
e.printStackTrace();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int size = lastUse.size();
|
||||
long time = (size > 0 ? 1000/size : 1000) - (System.currentTimeMillis() - start);
|
||||
if (time <= 0)
|
||||
return 0;
|
||||
return time;
|
||||
}
|
||||
};
|
||||
|
||||
unloadTicker = new Looper() {
|
||||
private final Supplier<Engine> supplier = createSupplier();
|
||||
|
||||
@Override
|
||||
protected long loop() {
|
||||
long start = System.currentTimeMillis();
|
||||
unloadAlive.reset();
|
||||
try {
|
||||
Engine engine = supplier.get();
|
||||
if (engine != null) {
|
||||
long unloadStart = System.currentTimeMillis();
|
||||
int count = engine.getMantle().unloadTectonicPlate(tectonicLimit.get() / lastUse.size());
|
||||
if (count > 0) {
|
||||
Iris.debug(C.GOLD + "Unloaded " + C.YELLOW + count + " TectonicPlates in " + C.RED + Form.duration(System.currentTimeMillis() - unloadStart, 2));
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
Iris.info(C.RED + "EngineSVC: Failed to unload.");
|
||||
e.printStackTrace();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int size = lastUse.size();
|
||||
long time = (size > 0 ? 1000/size : 1000) - (System.currentTimeMillis() - start);
|
||||
if (time <= 0)
|
||||
return 0;
|
||||
return time;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Supplier<Engine> createSupplier() {
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
return () -> {
|
||||
List<World> worlds = Bukkit.getWorlds();
|
||||
if (i.get() >= worlds.size()) {
|
||||
i.set(0);
|
||||
}
|
||||
try {
|
||||
for (int j = 0; j < worlds.size(); j++) {
|
||||
World world = worlds.get(i.getAndIncrement());
|
||||
PlatformChunkGenerator generator = IrisToolbelt.access(world);
|
||||
if (i.get() >= worlds.size()) {
|
||||
i.set(0);
|
||||
}
|
||||
|
||||
if (generator != null) {
|
||||
Engine engine = generator.getEngine();
|
||||
if (engine != null && !engine.isStudio()) {
|
||||
lastUseLock.lock();
|
||||
lastUse.put(world, System.currentTimeMillis());
|
||||
lastUseLock.unlock();
|
||||
return engine;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Iris.info(C.RED + "EngineSVC: Failed to create supplier.");
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
cacheTicker.interrupt();
|
||||
trimTicker.interrupt();
|
||||
unloadTicker.interrupt();
|
||||
lastUse.clear();
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,11 @@
|
||||
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.plugin.IrisService;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
@@ -68,19 +70,22 @@ public class ObjectSVC implements IrisService {
|
||||
* @param blocks The blocks to remove
|
||||
*/
|
||||
private void revert(Map<Block, BlockData> blocks) {
|
||||
int amount = 0;
|
||||
Iterator<Map.Entry<Block, BlockData>> it = blocks.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Block, BlockData> entry = it.next();
|
||||
BlockData data = entry.getValue();
|
||||
entry.getKey().setBlockData(data, false);
|
||||
it.remove();
|
||||
Bukkit.getScheduler().runTask(Iris.instance, () -> {
|
||||
int amount = 0;
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Block, BlockData> entry = it.next();
|
||||
BlockData data = entry.getValue();
|
||||
entry.getKey().setBlockData(data, false);
|
||||
|
||||
amount++;
|
||||
it.remove();
|
||||
|
||||
if (amount > 200) {
|
||||
J.s(() -> revert(blocks), 1);
|
||||
amount++;
|
||||
|
||||
if (amount > 200) {
|
||||
J.s(() -> revert(blocks), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
package com.volmit.iris.core.service;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.format.C;
|
||||
@@ -70,7 +71,7 @@ public class VillageSVC implements IrisService {
|
||||
|
||||
List<Player> playersInWorld = event.getEntity().getWorld().getPlayers();
|
||||
|
||||
String message = C.GOLD + "Iris does not allow cartographers in its world due to crashes.";
|
||||
String message = C.GOLD + IrisSettings.get().getGeneral().cartographerMessage;
|
||||
|
||||
Iris.info("Cancelled Cartographer Villager to prevent server crash at " + eventLocation + "!");
|
||||
|
||||
@@ -54,6 +54,7 @@ import java.util.Objects;
|
||||
|
||||
public class WandSVC implements IrisService {
|
||||
private static ItemStack dust;
|
||||
private static ItemStack wand;
|
||||
|
||||
public static void pasteSchematic(IrisObject s, Location at) {
|
||||
s.place(at);
|
||||
@@ -226,17 +227,19 @@ public class WandSVC implements IrisService {
|
||||
return getCuboidFromItem(p.getInventory().getItemInMainHand());
|
||||
}
|
||||
|
||||
Cuboid c = WorldEditLink.getSelection(p);
|
||||
if (IrisSettings.get().getWorld().worldEditWandCUI) {
|
||||
Cuboid c = WorldEditLink.getSelection(p);
|
||||
|
||||
if (c != null) {
|
||||
return new Location[]{c.getLowerNE(), c.getUpperSW()};
|
||||
if (c != null) {
|
||||
return new Location[]{c.getLowerNE(), c.getUpperSW()};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isHoldingWand(Player p) {
|
||||
return isHoldingIrisWand(p) || WorldEditLink.getSelection(p) != null;
|
||||
return isHoldingIrisWand(p) || (IrisSettings.get().getWorld().worldEditWandCUI && WorldEditLink.getSelection(p) != null);
|
||||
}
|
||||
|
||||
public static boolean isHoldingIrisWand(Player p) {
|
||||
@@ -251,7 +254,6 @@ public class WandSVC implements IrisService {
|
||||
* @return True if it is
|
||||
*/
|
||||
public static boolean isWand(ItemStack is) {
|
||||
ItemStack wand = createWand();
|
||||
if (is.getItemMeta() == null) return false;
|
||||
return is.getType().equals(wand.getType()) &&
|
||||
is.getItemMeta().getDisplayName().equals(wand.getItemMeta().getDisplayName()) &&
|
||||
@@ -261,7 +263,7 @@ public class WandSVC implements IrisService {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
ItemStack wand = createWand();
|
||||
wand = createWand();
|
||||
dust = createDust();
|
||||
|
||||
J.ar(() -> {
|
||||
@@ -0,0 +1,626 @@
|
||||
package com.volmit.iris.core.tools;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.CentralProcessor;
|
||||
import oshi.hardware.GlobalMemory;
|
||||
import oshi.hardware.HWDiskStore;
|
||||
import oshi.software.os.OperatingSystem;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import static com.google.common.math.LongMath.isPrime;
|
||||
import static com.volmit.iris.util.misc.getHardware.getCPUModel;
|
||||
import static com.volmit.iris.util.misc.getHardware.getDiskModel;
|
||||
public class IrisBenchmarking {
|
||||
static String ServerOS;
|
||||
static String filePath = "benchmark.dat";
|
||||
static double avgWriteSpeedMBps;
|
||||
static double avgReadSpeedMBps;
|
||||
static double highestWriteSpeedMBps;
|
||||
static double highestReadSpeedMBps;
|
||||
static double lowestWriteSpeedMBps;
|
||||
static double lowestReadSpeedMBps;
|
||||
static double calculateIntegerMath;
|
||||
static double calculateFloatingPoint;
|
||||
static double calculatePrimeNumbers;
|
||||
static double calculateStringSorting;
|
||||
static double calculateDataEncryption;
|
||||
static double calculateDataCompression;
|
||||
static String currentRunning = "None";
|
||||
static int BenchmarksCompleted = 0;
|
||||
static int BenchmarksTotal = 7;
|
||||
static int totalTasks = 10;
|
||||
static int currentTasks = 0;
|
||||
static double WindowsCPUCompression;
|
||||
static double WindowsCPUEncryption;
|
||||
static double WindowsCPUCSHA1;
|
||||
static double elapsedTimeNs;
|
||||
static boolean Winsat = false;
|
||||
static boolean WindowsDiskSpeed = false;
|
||||
public static boolean inProgress = false;
|
||||
static double startTime;
|
||||
// Good enough for now. . .
|
||||
|
||||
public static void runBenchmark() throws InterruptedException {
|
||||
inProgress = true;
|
||||
getServerOS();
|
||||
deleteTestFile(filePath);
|
||||
AtomicReference<Double> doneCalculateDiskSpeed = new AtomicReference<>((double) 0);
|
||||
startBenchmarkTimer();
|
||||
Iris.info("Benchmark Started!");
|
||||
Iris.warn("Although it may seem momentarily paused, it's actively processing.");
|
||||
BenchmarksCompleted = 0;
|
||||
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
currentRunning = "calculateDiskSpeed";
|
||||
progressBar();
|
||||
if (ServerOS.contains("Windows") && isRunningAsAdmin()) {
|
||||
WindowsDiskSpeed = true;
|
||||
WindowsDiskSpeedTest();
|
||||
} else {
|
||||
warningFallback();
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
doneCalculateDiskSpeed.set(roundToTwoDecimalPlaces(calculateDiskSpeed()));
|
||||
BenchmarksCompleted++;
|
||||
}
|
||||
|
||||
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "WindowsCpuSpeedTest";
|
||||
progressBar();
|
||||
if (ServerOS.contains("Windows") && isRunningAsAdmin()) {
|
||||
Winsat = true;
|
||||
WindowsCpuSpeedTest();
|
||||
} else {
|
||||
Iris.info("Skipping:" + C.BLUE + " Windows System Assessment Tool Benchmarks");
|
||||
if (!ServerOS.contains("Windows")) {
|
||||
Iris.info("Required Software:" + C.BLUE + " Windows");
|
||||
BenchmarksTotal = 6;
|
||||
}
|
||||
if (!isRunningAsAdmin()) {
|
||||
Iris.info(C.RED + "ERROR: " + C.DARK_RED + "Elevated privileges missing");
|
||||
BenchmarksTotal = 6;
|
||||
}
|
||||
}
|
||||
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "calculateIntegerMath";
|
||||
progressBar();
|
||||
calculateIntegerMath = roundToTwoDecimalPlaces(calculateIntegerMath());
|
||||
BenchmarksCompleted++;
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "calculateFloatingPoint";
|
||||
progressBar();
|
||||
calculateFloatingPoint = roundToTwoDecimalPlaces(calculateFloatingPoint());
|
||||
BenchmarksCompleted++;
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "calculateStringSorting";
|
||||
progressBar();
|
||||
calculateStringSorting = roundToTwoDecimalPlaces(calculateStringSorting());
|
||||
BenchmarksCompleted++;
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "calculatePrimeNumbers";
|
||||
progressBar();
|
||||
calculatePrimeNumbers = roundToTwoDecimalPlaces(calculatePrimeNumbers());
|
||||
BenchmarksCompleted++;
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "calculateDataEncryption";
|
||||
progressBar();
|
||||
calculateDataEncryption = roundToTwoDecimalPlaces(calculateDataEncryption());
|
||||
BenchmarksCompleted++;
|
||||
}).thenRun(() -> {
|
||||
currentRunning = "calculateDataCompression";
|
||||
progressBar();
|
||||
calculateDataCompression = roundToTwoDecimalPlaces(calculateDataCompression());
|
||||
BenchmarksCompleted++;
|
||||
}).thenRun(() -> {
|
||||
elapsedTimeNs = stopBenchmarkTimer();
|
||||
results();
|
||||
inProgress = false;
|
||||
});
|
||||
|
||||
try {
|
||||
future.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void progressBar() {
|
||||
Iris.info("-----------------------------------------------------");
|
||||
Iris.info("Currently Running: " + C.BLUE + currentRunning);
|
||||
// Iris.info("Tasks: " + "Current Tasks: " + C.BLUE + currentTasks + C.WHITE + " / " + "Total Tasks: " + C.BLUE + totalTasks);
|
||||
Iris.info("Benchmarks Completed: " + C.BLUE + BenchmarksCompleted + C.WHITE + " / " + "Total: " + C.BLUE + BenchmarksTotal);
|
||||
Iris.info("-----------------------------------------------------");
|
||||
}
|
||||
|
||||
public static void results() {
|
||||
|
||||
SystemInfo systemInfo = new SystemInfo();
|
||||
GlobalMemory globalMemory = systemInfo.getHardware().getMemory();
|
||||
long totalMemoryMB = globalMemory.getTotal() / (1024 * 1024);
|
||||
long availableMemoryMB = globalMemory.getAvailable() / (1024 * 1024);
|
||||
long totalPageSize = globalMemory.getPageSize() / (1024 * 1024);
|
||||
long usedMemoryMB = totalMemoryMB - availableMemoryMB;
|
||||
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
|
||||
|
||||
Iris.info("OS: " + ServerOS);
|
||||
if (!isRunningAsAdmin() || !ServerOS.contains("Windows")) {
|
||||
Iris.info(C.GOLD + "For the full results use Windows + Admin Rights..");
|
||||
}
|
||||
Iris.info("CPU Model: " + getCPUModel());
|
||||
Iris.info("CPU Score: " + "WIP");
|
||||
Iris.info("- Integer Math: " + calculateIntegerMath + " MOps/Sec");
|
||||
Iris.info("- Floating Point Math: " + calculateFloatingPoint + " MOps/Sec");
|
||||
Iris.info("- Find Prime Numbers: " + calculatePrimeNumbers + " Primes/Sec");
|
||||
Iris.info("- Random String Sorting: " + calculateStringSorting + " Thousand Strings/Sec");
|
||||
Iris.info("- Data Encryption: " + formatDouble(calculateDataEncryption) + " MBytes/Sec");
|
||||
Iris.info("- Data Compression: " + formatDouble(calculateDataCompression) + " MBytes/Sec");
|
||||
|
||||
if (WindowsDiskSpeed) {
|
||||
Iris.info("Disk Model: " + getDiskModel());
|
||||
Iris.info(C.BLUE + "- Running with Windows System Assessment Tool");
|
||||
Iris.info("- Sequential 64.0 Write: " + C.BLUE + formatDouble(avgWriteSpeedMBps) + " Mbps");
|
||||
Iris.info("- Sequential 64.0 Read: " + C.BLUE + formatDouble(avgReadSpeedMBps) + " Mbps");
|
||||
} else {
|
||||
Iris.info("Disk Model: " + getDiskModel());
|
||||
Iris.info(C.GREEN + "- Running in Native Mode");
|
||||
Iris.info("- Average Write Speed: " + C.GREEN + formatDouble(avgWriteSpeedMBps) + " Mbps");
|
||||
Iris.info("- Average Read Speed: " + C.GREEN + formatDouble(avgReadSpeedMBps) + " Mbps");
|
||||
Iris.info("- Highest Write Speed: " + formatDouble(highestWriteSpeedMBps) + " Mbps");
|
||||
Iris.info("- Highest Read Speed: " + formatDouble(highestReadSpeedMBps) + " Mbps");
|
||||
Iris.info("- Lowest Write Speed: " + formatDouble(lowestWriteSpeedMBps) + " Mbps");
|
||||
Iris.info("- Lowest Read Speed: " + formatDouble(lowestReadSpeedMBps) + " Mbps");
|
||||
}
|
||||
Iris.info("Ram Usage: ");
|
||||
Iris.info("- Total Ram: " + totalMemoryMB + " MB");
|
||||
Iris.info("- Used Ram: " + usedMemoryMB + " MB");
|
||||
Iris.info("- Total Process Ram: " + C.BLUE + getMaxMemoryUsage() + " MB");
|
||||
Iris.info("- Total Paging Size: " + totalPageSize + " MB");
|
||||
if (Winsat) {
|
||||
Iris.info(C.BLUE + "Windows System Assessment Tool: ");
|
||||
Iris.info("- CPU LZW Compression:" + C.BLUE + formatDouble(WindowsCPUCompression) + " MB/s");
|
||||
Iris.info("- CPU AES256 Encryption: " + C.BLUE + formatDouble(WindowsCPUEncryption) + " MB/s");
|
||||
Iris.info("- CPU SHA1 Hash: " + C.BLUE + formatDouble(WindowsCPUCSHA1) + " MB/s");
|
||||
Iris.info("Duration: " + roundToTwoDecimalPlaces(elapsedTimeNs) + " Seconds");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static long getMaxMemoryUsage() {
|
||||
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
|
||||
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
|
||||
MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
|
||||
long maxHeapMemory = heapMemoryUsage.getMax();
|
||||
long maxNonHeapMemory = nonHeapMemoryUsage.getMax();
|
||||
long maxMemoryUsageMB = (maxHeapMemory + maxNonHeapMemory) / (1024 * 1024);
|
||||
return maxMemoryUsageMB;
|
||||
}
|
||||
|
||||
public static void getServerOS() {
|
||||
SystemInfo systemInfo = new SystemInfo();
|
||||
OperatingSystem os = systemInfo.getOperatingSystem();
|
||||
ServerOS = os.toString();
|
||||
}
|
||||
|
||||
public static boolean isRunningAsAdmin() {
|
||||
if (ServerOS.contains("Windows")) {
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("winsat disk");
|
||||
process.waitFor();
|
||||
return process.exitValue() == 0;
|
||||
} catch (IOException | InterruptedException e) {
|
||||
// Hmm
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void warningFallback() {
|
||||
Iris.info(C.RED + "Using the " + C.DARK_RED + "FALLBACK" + C.RED + " method due to compatibility issues. ");
|
||||
Iris.info(C.RED + "Please note that this may result in less accurate results.");
|
||||
}
|
||||
|
||||
private static String formatDouble(double value) {
|
||||
return String.format("%.2f", value);
|
||||
}
|
||||
|
||||
private static void startBenchmarkTimer() {
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
|
||||
private static double stopBenchmarkTimer() {
|
||||
long endTime = System.nanoTime();
|
||||
return (endTime - startTime) / 1_000_000_000.0;
|
||||
}
|
||||
|
||||
private static double calculateIntegerMath() {
|
||||
final int numIterations = 1_000_000_000;
|
||||
final int numRuns = 30;
|
||||
double totalMopsPerSec = 0;
|
||||
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
long startTime = System.nanoTime();
|
||||
int result = 0;
|
||||
|
||||
for (int i = 0; i < numIterations; i++) {
|
||||
result += i * 2;
|
||||
result -= i / 2;
|
||||
result ^= i;
|
||||
result <<= 1;
|
||||
result >>= 1;
|
||||
}
|
||||
|
||||
long endTime = System.nanoTime();
|
||||
double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
|
||||
double mopsPerSec = (numIterations / elapsedSeconds) / 1_000_000.0;
|
||||
|
||||
totalMopsPerSec += mopsPerSec;
|
||||
}
|
||||
|
||||
double averageMopsPerSec = totalMopsPerSec / numRuns;
|
||||
return averageMopsPerSec;
|
||||
}
|
||||
|
||||
private static double calculateFloatingPoint() {
|
||||
long numIterations = 85_000_000;
|
||||
int numRuns = 30;
|
||||
double totalMopsPerSec = 0;
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
double result = 0;
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
for (int i = 0; i < numIterations; i++) {
|
||||
result += Math.sqrt(i) * Math.sin(i) / (i + 1);
|
||||
}
|
||||
|
||||
long endTime = System.nanoTime();
|
||||
double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
|
||||
double mopsPerSec = (numIterations / elapsedSeconds) / 1_000_000.0;
|
||||
|
||||
totalMopsPerSec += mopsPerSec;
|
||||
}
|
||||
|
||||
double averageMopsPerSec = totalMopsPerSec / numRuns;
|
||||
return averageMopsPerSec;
|
||||
}
|
||||
|
||||
private static double calculatePrimeNumbers() {
|
||||
int primeCount;
|
||||
long numIterations = 1_000_000;
|
||||
int numRuns = 30;
|
||||
double totalMopsPerSec = 0;
|
||||
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
primeCount = 0;
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
for (int num = 2; primeCount < numIterations; num++) {
|
||||
if (isPrime(num)) {
|
||||
primeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
long endTime = System.nanoTime();
|
||||
double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
|
||||
double mopsPerSec = (primeCount / elapsedSeconds) / 1_000_000.0;
|
||||
|
||||
totalMopsPerSec += mopsPerSec;
|
||||
}
|
||||
|
||||
double averageMopsPerSec = totalMopsPerSec / numRuns;
|
||||
return averageMopsPerSec;
|
||||
}
|
||||
|
||||
private static double calculateStringSorting() {
|
||||
int stringCount = 1_000_000;
|
||||
int stringLength = 100;
|
||||
int numRuns = 30;
|
||||
double totalMopsPerSec = 0;
|
||||
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
List<String> randomStrings = generateRandomStrings(stringCount, stringLength);
|
||||
long startTime = System.nanoTime();
|
||||
randomStrings.sort(String::compareTo);
|
||||
long endTime = System.nanoTime();
|
||||
|
||||
double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
|
||||
double mopsPerSec = (stringCount / elapsedSeconds) / 1_000.0;
|
||||
|
||||
totalMopsPerSec += mopsPerSec;
|
||||
}
|
||||
|
||||
double averageMopsPerSec = totalMopsPerSec / numRuns;
|
||||
return averageMopsPerSec;
|
||||
}
|
||||
|
||||
public static double calculateDataEncryption() {
|
||||
int dataSizeMB = 100;
|
||||
byte[] dataToEncrypt = generateRandomData(dataSizeMB * 1024 * 1024);
|
||||
int numRuns = 20;
|
||||
double totalMBytesPerSec = 0;
|
||||
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
long startTime = System.nanoTime();
|
||||
byte[] encryptedData = performEncryption(dataToEncrypt, 1);
|
||||
|
||||
long endTime = System.nanoTime();
|
||||
double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
|
||||
double mbytesPerSec = (dataToEncrypt.length / (1024 * 1024.0)) / elapsedSeconds;
|
||||
|
||||
totalMBytesPerSec += mbytesPerSec;
|
||||
}
|
||||
|
||||
double averageMBytesPerSec = totalMBytesPerSec / numRuns;
|
||||
return averageMBytesPerSec;
|
||||
}
|
||||
|
||||
private static byte[] performEncryption(byte[] data, int numRuns) {
|
||||
byte[] key = "MyEncryptionKey".getBytes();
|
||||
byte[] result = Arrays.copyOf(data, data.length);
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] ^= key[i % key.length];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double calculateDataCompression() {
|
||||
int dataSizeMB = 500;
|
||||
byte[] dataToCompress = generateRandomData(dataSizeMB * 1024 * 1024);
|
||||
long startTime = System.nanoTime();
|
||||
byte[] compressedData = performCompression(dataToCompress);
|
||||
long endTime = System.nanoTime();
|
||||
|
||||
double elapsedSeconds = (endTime - startTime) / 1e9;
|
||||
double mbytesPerSec = (compressedData.length / (1024.0 * 1024.0)) / elapsedSeconds;
|
||||
|
||||
return mbytesPerSec;
|
||||
}
|
||||
|
||||
private static byte[] performCompression(byte[] data) {
|
||||
Deflater deflater = new Deflater();
|
||||
deflater.setInput(data);
|
||||
deflater.finish();
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
while (!deflater.finished()) {
|
||||
int count = deflater.deflate(buffer);
|
||||
outputStream.write(buffer, 0, count);
|
||||
}
|
||||
|
||||
deflater.end();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
private static List<String> generateRandomStrings(int count, int length) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
List<String> randomStrings = new ArrayList<>();
|
||||
|
||||
IntStream.range(0, count).forEach(i -> {
|
||||
byte[] bytes = new byte[length];
|
||||
random.nextBytes(bytes);
|
||||
randomStrings.add(Base64.getEncoder().encodeToString(bytes));
|
||||
});
|
||||
return randomStrings;
|
||||
}
|
||||
|
||||
private static byte[] generateRandomData(int size) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] data = new byte[size];
|
||||
random.nextBytes(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
private static double roundToTwoDecimalPlaces(double value) {
|
||||
return Double.parseDouble(String.format("%.2f", value));
|
||||
}
|
||||
|
||||
private static double calculateCPUScore(long elapsedTimeNs) {
|
||||
return 1.0 / (elapsedTimeNs / 1_000_000.0);
|
||||
}
|
||||
|
||||
public static double calculateDiskSpeed() {
|
||||
int numRuns = 10;
|
||||
int fileSizeMB = 1000;
|
||||
|
||||
double[] writeSpeeds = new double[numRuns];
|
||||
double[] readSpeeds = new double[numRuns];
|
||||
|
||||
for (int run = 0; run < numRuns; run++) {
|
||||
long writeStartTime = System.nanoTime();
|
||||
deleteTestFile(filePath);
|
||||
createTestFile(filePath, fileSizeMB);
|
||||
long writeEndTime = System.nanoTime();
|
||||
|
||||
long readStartTime = System.nanoTime();
|
||||
readTestFile(filePath);
|
||||
long readEndTime = System.nanoTime();
|
||||
|
||||
double writeSpeed = calculateDiskSpeedMBps(fileSizeMB, writeStartTime, writeEndTime);
|
||||
double readSpeed = calculateDiskSpeedMBps(fileSizeMB, readStartTime, readEndTime);
|
||||
|
||||
writeSpeeds[run] = writeSpeed;
|
||||
readSpeeds[run] = readSpeed;
|
||||
|
||||
if (run == 0) {
|
||||
lowestWriteSpeedMBps = writeSpeed;
|
||||
highestWriteSpeedMBps = writeSpeed;
|
||||
lowestReadSpeedMBps = readSpeed;
|
||||
highestReadSpeedMBps = readSpeed;
|
||||
} else {
|
||||
if (writeSpeed < lowestWriteSpeedMBps) {
|
||||
lowestWriteSpeedMBps = writeSpeed;
|
||||
}
|
||||
if (writeSpeed > highestWriteSpeedMBps) {
|
||||
highestWriteSpeedMBps = writeSpeed;
|
||||
}
|
||||
if (readSpeed < lowestReadSpeedMBps) {
|
||||
lowestReadSpeedMBps = readSpeed;
|
||||
}
|
||||
if (readSpeed > highestReadSpeedMBps) {
|
||||
highestReadSpeedMBps = readSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
avgWriteSpeedMBps = calculateAverage(writeSpeeds);
|
||||
avgReadSpeedMBps = calculateAverage(readSpeeds);
|
||||
return 2;
|
||||
}
|
||||
|
||||
public static void createTestFile(String filePath, int fileSizeMB) {
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
byte[] data = new byte[1024 * 1024];
|
||||
Arrays.fill(data, (byte) 0);
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
for (int i = 0; i < fileSizeMB; i++) {
|
||||
fos.write(data);
|
||||
}
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void readTestFile(String filePath) {
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[1024];
|
||||
while (fis.read(buffer) != -1) {
|
||||
}
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteTestFile(String filePath) {
|
||||
File file = new File(filePath);
|
||||
file.delete();
|
||||
}
|
||||
|
||||
public static double calculateDiskSpeedMBps(int fileSizeMB, long startTime, long endTime) {
|
||||
double elapsedSeconds = (endTime - startTime) / 1_000_000_000.0;
|
||||
double writeSpeed = (fileSizeMB / elapsedSeconds);
|
||||
return writeSpeed;
|
||||
}
|
||||
|
||||
public static double calculateAverage(double[] values) {
|
||||
double sum = 0;
|
||||
for (double value : values) {
|
||||
sum += value;
|
||||
}
|
||||
return sum / values.length;
|
||||
}
|
||||
|
||||
public static void WindowsDiskSpeedTest() {
|
||||
try {
|
||||
String command = "winsat disk";
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
Iris.debug(line);
|
||||
|
||||
if (line.contains("Disk Sequential 64.0 Read")) {
|
||||
avgReadSpeedMBps = extractSpeed(line);
|
||||
} else if (line.contains("Disk Sequential 64.0 Write")) {
|
||||
avgWriteSpeedMBps = extractSpeed(line);
|
||||
}
|
||||
}
|
||||
|
||||
process.waitFor();
|
||||
process.destroy();
|
||||
|
||||
Iris.debug("Sequential Read Speed: " + avgReadSpeedMBps + " MB/s");
|
||||
Iris.debug("Sequential Write Speed: " + avgWriteSpeedMBps + " MB/s");
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static double extractSpeed(String line) {
|
||||
String[] tokens = line.split("\\s+");
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].endsWith("MB/s") && i > 0) {
|
||||
try {
|
||||
return Double.parseDouble(tokens[i - 1]);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static void WindowsCpuSpeedTest() {
|
||||
try {
|
||||
String command = "winsat cpuformal";
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
Iris.debug(line);
|
||||
|
||||
if (line.contains("CPU AES256 Encryption")) {
|
||||
WindowsCPUEncryption = extractCpuInfo(line);
|
||||
}
|
||||
if (line.contains("CPU LZW Compression")) {
|
||||
WindowsCPUCompression = extractCpuInfo(line);
|
||||
}
|
||||
if (line.contains("CPU SHA1 Hash")) {
|
||||
WindowsCPUCSHA1 = extractCpuInfo(line);
|
||||
}
|
||||
}
|
||||
process.waitFor();
|
||||
process.destroy();
|
||||
|
||||
Iris.debug("Winsat Encryption: " + WindowsCPUEncryption + " MB/s");
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static double extractCpuInfo(String line) {
|
||||
String[] tokens = line.split("\\s+");
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].endsWith("MB/s") && i > 0) {
|
||||
try {
|
||||
return Double.parseDouble(tokens[i - 1]);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
395
core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java
Normal file
395
core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java
Normal file
@@ -0,0 +1,395 @@
|
||||
package com.volmit.iris.core.tools;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.object.*;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.nbt.io.NBTUtil;
|
||||
import com.volmit.iris.util.nbt.io.NamedTag;
|
||||
import com.volmit.iris.util.nbt.tag.*;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.reflect.V;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class IrisConverter {
|
||||
public static void convertSchematics(VolmitSender sender) {
|
||||
File folder = Iris.instance.getDataFolder("convert");
|
||||
|
||||
FilenameFilter filter = (dir, name) -> name.endsWith(".schem");
|
||||
File[] fileList = folder.listFiles(filter);
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||
executorService.submit(() -> {
|
||||
for (File schem : fileList) {
|
||||
try {
|
||||
PrecisionStopwatch p = new PrecisionStopwatch();
|
||||
boolean largeObject = false;
|
||||
NamedTag tag = null;
|
||||
try {
|
||||
tag = NBTUtil.read(schem);
|
||||
} catch (IOException e) {
|
||||
Iris.info(C.RED + "Failed to read: " + schem.getName());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
CompoundTag compound = (CompoundTag) tag.getTag();
|
||||
|
||||
if (compound.containsKey("Palette") && compound.containsKey("Width") && compound.containsKey("Height") && compound.containsKey("Length")) {
|
||||
int objW = ((ShortTag) compound.get("Width")).getValue();
|
||||
int objH = ((ShortTag) compound.get("Height")).getValue();
|
||||
int objD = ((ShortTag) compound.get("Length")).getValue();
|
||||
int mv = objW * objH * objD;
|
||||
AtomicInteger v = new AtomicInteger(0);
|
||||
AtomicInteger fv = new AtomicInteger(0);
|
||||
if (mv > 500_000) {
|
||||
largeObject = true;
|
||||
Iris.info(C.GRAY + "Converting.. "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
Iris.info(C.GRAY + "- It may take a while");
|
||||
if (sender.isPlayer()) {
|
||||
J.a(() -> {
|
||||
// while (v.get() != mv) {
|
||||
// double pr = ((double) v.get() / (double ) mv);
|
||||
// sender.sendProgress(pr, "Converting");
|
||||
// J.sleep(16);
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CompoundTag paletteTag = (CompoundTag) compound.get("Palette");
|
||||
Map<Integer, BlockData> blockmap = new HashMap<>(paletteTag.size(), 0.9f);
|
||||
for (Map.Entry<String, Tag<?>> entry : paletteTag.getValue().entrySet()) {
|
||||
String blockName = entry.getKey();
|
||||
BlockData bd = Bukkit.createBlockData(blockName);
|
||||
Tag<?> blockTag = entry.getValue();
|
||||
int blockId = ((IntTag) blockTag).getValue();
|
||||
blockmap.put(blockId, bd);
|
||||
}
|
||||
|
||||
ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData");
|
||||
byte[] originalBlockArray = byteArray.getValue();
|
||||
int b = 0;
|
||||
int a = 0;
|
||||
Map<Integer, Byte> y = new HashMap<>();
|
||||
Map<Integer, Byte> x = new HashMap<>();
|
||||
Map<Integer, Byte> z = new HashMap<>();
|
||||
|
||||
// Height adjustments
|
||||
for (int h = 0; h < objH; h++) {
|
||||
if (b == 0) {
|
||||
y.put(h, (byte) 0);
|
||||
}
|
||||
if (b > 0) {
|
||||
y.put(h, (byte) 1);
|
||||
}
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (int d = 0; d < objD; d++) {
|
||||
for (int w = 0; w < objW; w++) {
|
||||
BlockData db = blockmap.get((int) originalBlockArray[fv.get()]);
|
||||
if(db.getAsString().contains("minecraft:air")) {
|
||||
a++;
|
||||
} else {
|
||||
b++;
|
||||
}
|
||||
fv.getAndAdd(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fv.set(0);
|
||||
|
||||
// Width adjustments
|
||||
for (int w = 0; w < objW; w++) {
|
||||
if (b == 0) {
|
||||
x.put(w, (byte) 0);
|
||||
}
|
||||
if (b > 0) {
|
||||
x.put(w, (byte) 1);
|
||||
}
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (int h = 0; h < objH; h++) {
|
||||
for (int d = 0; d < objD; d++) {
|
||||
BlockData db = blockmap.get((int) originalBlockArray[fv.get()]);
|
||||
if(db.getAsString().contains("minecraft:air")) {
|
||||
a++;
|
||||
} else {
|
||||
b++;
|
||||
}
|
||||
fv.getAndAdd(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fv.set(0);
|
||||
|
||||
// Depth adjustments
|
||||
for (int d = 0; d < objD; d++) {
|
||||
if (b == 0) {
|
||||
z.put(d, (byte) 0);
|
||||
}
|
||||
if (b > 0) {
|
||||
z.put(d, (byte) 1);
|
||||
}
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (int h = 0; h < objH; h++) {
|
||||
for (int w = 0; w < objW; w++) {
|
||||
BlockData db = blockmap.get((int) originalBlockArray[fv.get()]);
|
||||
if(db.getAsString().contains("minecraft:air")) {
|
||||
a++;
|
||||
} else {
|
||||
b++;
|
||||
}
|
||||
fv.getAndAdd(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fv.set(0);
|
||||
int CorrectObjH = getCorrectY(y, objH);
|
||||
int CorrectObjW = getCorrectX(x, objW);
|
||||
int CorrectObjD = getCorrectZ(z, objD);
|
||||
|
||||
//IrisObject object = new IrisObject(CorrectObjW, CorrectObjH, CorrectObjH);
|
||||
IrisObject object = new IrisObject(objW, objH, objD);
|
||||
Vector originalVector = new Vector(objW,objH,objD);
|
||||
|
||||
|
||||
int[] yc = null;
|
||||
int[] xc = null;
|
||||
int[] zc = null;
|
||||
|
||||
|
||||
int fo = 0;
|
||||
int so = 0;
|
||||
int o = 0;
|
||||
int c = 0;
|
||||
for (Integer i : y.keySet()) {
|
||||
if (y.get(i) == 0) {
|
||||
o++;
|
||||
}
|
||||
if (y.get(i) == 1) {
|
||||
c++;
|
||||
if (c == 1) {
|
||||
fo = o;
|
||||
}
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
so = o;
|
||||
yc = new int[]{fo, so};
|
||||
|
||||
fo = 0;
|
||||
so = 0;
|
||||
o = 0;
|
||||
c = 0;
|
||||
for (Integer i : x.keySet()) {
|
||||
if (x.get(i) == 0) {
|
||||
o++;
|
||||
}
|
||||
if (x.get(i) == 1) {
|
||||
c++;
|
||||
if (c == 1) {
|
||||
fo = o;
|
||||
}
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
so = o;
|
||||
xc = new int[]{fo, so};
|
||||
|
||||
fo = 0;
|
||||
so = 0;
|
||||
o = 0;
|
||||
c = 0;
|
||||
for (Integer i : z.keySet()) {
|
||||
if (z.get(i) == 0) {
|
||||
o++;
|
||||
}
|
||||
if (z.get(i) == 1) {
|
||||
c++;
|
||||
if (c == 1) {
|
||||
fo = o;
|
||||
}
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
so = o;
|
||||
zc = new int[]{fo, so};
|
||||
|
||||
int h1, h2, w1, w2, v1 = 0, volume = objW * objH * objD;
|
||||
Map<Integer, Integer> blockLocationMap = new LinkedHashMap<>();
|
||||
boolean hasAir = false;
|
||||
int pos = 0;
|
||||
for (int i : originalBlockArray) {
|
||||
blockLocationMap.put(pos, i);
|
||||
pos++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int h = 0; h < objH; h++) {
|
||||
for (int d = 0; d < objD; d++) {
|
||||
for (int w = 0; w < objW; w++) {
|
||||
BlockData bd = blockmap.get((int) originalBlockArray[v.get()]);
|
||||
if (!bd.getMaterial().isAir()) {
|
||||
object.setUnsigned(w, h, d, bd);
|
||||
}
|
||||
v.getAndAdd(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));
|
||||
} catch (IOException e) {
|
||||
Iris.info(C.RED + "Failed to save: " + schem.getName());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (sender.isPlayer()) {
|
||||
if (largeObject) {
|
||||
sender.sendMessage(C.IRIS + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||
} else {
|
||||
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
}
|
||||
}
|
||||
if (largeObject) {
|
||||
Iris.info(C.GRAY + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||
} else {
|
||||
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||
}
|
||||
// schem.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Iris.info(C.RED + "Failed to convert: " + schem.getName());
|
||||
if (sender.isPlayer()) {
|
||||
sender.sendMessage(C.RED + "Failed to convert: " + schem.getName());
|
||||
}
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isNewPointFurther(int[] originalPoint, int[] oldPoint, int[] newPoint) {
|
||||
int oX = oldPoint[1];
|
||||
int oY = oldPoint[2];
|
||||
int oZ = oldPoint[3];
|
||||
|
||||
int nX = newPoint[1];
|
||||
int nY = newPoint[2];
|
||||
int nZ = newPoint[3];
|
||||
|
||||
int orX = originalPoint[1];
|
||||
int orY = originalPoint[2];
|
||||
int orZ = originalPoint[3];
|
||||
|
||||
double oldDistance = Math.sqrt(Math.pow(oX - orX, 2) + Math.pow(oY - orY, 2) + Math.pow(oZ - orZ, 2));
|
||||
double newDistance = Math.sqrt(Math.pow(nX - orX, 2) + Math.pow(nY - orY, 2) + Math.pow(nZ - orZ, 2));
|
||||
|
||||
if (newDistance > oldDistance) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int[] getCoordinates(int pos, int obX, int obY, int obZ) {
|
||||
int z = 0;
|
||||
int[] coords = new int[4];
|
||||
for (int h = 0; h < obY; h++) {
|
||||
for (int d = 0; d < obZ; d++) {
|
||||
for (int w = 0; w < obX; w++) {
|
||||
if (z == pos) {
|
||||
coords[1] = w;
|
||||
coords[2] = h;
|
||||
coords[3] = d;
|
||||
return coords;
|
||||
}
|
||||
z++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getCorrectY(Map<Integer, Byte> y, int H) {
|
||||
int fo = 0;
|
||||
int so = 0;
|
||||
int o = 0;
|
||||
int c = 0;
|
||||
for (Integer i : y.keySet()) {
|
||||
if (y.get(i) == 0) {
|
||||
o++;
|
||||
}
|
||||
if (y.get(i) == 1) {
|
||||
c++;
|
||||
if(c == 1){
|
||||
fo = o;
|
||||
}
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
so = o;
|
||||
return H = H - (fo + so);
|
||||
}
|
||||
|
||||
public static int getCorrectX(Map<Integer, Byte> x, int W) {
|
||||
int fo = 0;
|
||||
int so = 0;
|
||||
int o = 0;
|
||||
int c = 0;
|
||||
for (Integer i : x.keySet()) {
|
||||
if (x.get(i) == 0) {
|
||||
o++;
|
||||
}
|
||||
if (x.get(i) == 1) {
|
||||
c++;
|
||||
if(c == 1){
|
||||
fo = o;
|
||||
}
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
so = o;
|
||||
return W = W - (fo + so);
|
||||
}
|
||||
|
||||
public static int getCorrectZ(Map<Integer, Byte> z, int D) {
|
||||
int fo = 0;
|
||||
int so = 0;
|
||||
int o = 0;
|
||||
int c = 0;
|
||||
for (Integer i : z.keySet()) {
|
||||
if (z.get(i) == 0) {
|
||||
o++;
|
||||
}
|
||||
if (z.get(i) == 1) {
|
||||
c++;
|
||||
if(c == 1){
|
||||
fo = o;
|
||||
}
|
||||
o = 0;
|
||||
}
|
||||
}
|
||||
so = o;
|
||||
return D = D - (fo + so);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,8 +24,10 @@ import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.ServerConfigurator;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||
import com.volmit.iris.core.safeguard.UtilsSFG;
|
||||
import com.volmit.iris.util.exceptions.IrisException;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
@@ -44,6 +46,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode;
|
||||
|
||||
/**
|
||||
* Makes it a lot easier to setup an engine, world, studio or whatever
|
||||
@@ -51,7 +54,7 @@ import java.util.function.Supplier;
|
||||
@Data
|
||||
@Accessors(fluent = true, chain = true)
|
||||
public class IrisCreator {
|
||||
private static final File BUKKIT_YML = new File(Bukkit.getServer().getWorldContainer(), "bukkit.yml");
|
||||
private static final File BUKKIT_YML = new File("bukkit.yml");
|
||||
/**
|
||||
* Specify an area to pregenerate during creation
|
||||
*/
|
||||
@@ -79,6 +82,10 @@ public class IrisCreator {
|
||||
* the world itself. Studio worlds are deleted when they are unloaded.
|
||||
*/
|
||||
private boolean studio = false;
|
||||
/**
|
||||
* Benchmark mode
|
||||
*/
|
||||
private boolean benchmark = false;
|
||||
|
||||
public static boolean removeFromBukkitYml(String name) throws IOException {
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
|
||||
@@ -93,6 +100,9 @@ public class IrisCreator {
|
||||
yml.save(BUKKIT_YML);
|
||||
return true;
|
||||
}
|
||||
public static boolean worldLoaded(){
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the IrisAccess (contains the world)
|
||||
@@ -100,7 +110,15 @@ public class IrisCreator {
|
||||
* @return the IrisAccess
|
||||
* @throws IrisException shit happens
|
||||
*/
|
||||
|
||||
public World create() throws IrisException {
|
||||
if (unstablemode){
|
||||
Iris.info(C.RED + "Your server is experiencing an incompatibility with the Iris plugin. Please rectify this problem to avoid further complications.");
|
||||
Iris.info(C.RED + "----------------------------------------------------------------");
|
||||
Iris.info(C.RED + "Operation ran: Loading Iris World..");
|
||||
UtilsSFG.printIncompatibleWarnings();
|
||||
Iris.info(C.RED + "----------------------------------------------------------------");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IrisException("You cannot invoke create() on the main thread.");
|
||||
}
|
||||
@@ -115,7 +133,10 @@ public class IrisCreator {
|
||||
sender = Iris.getSender();
|
||||
|
||||
if (!studio()) {
|
||||
Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(name()));
|
||||
Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name()));
|
||||
}
|
||||
if (benchmark) {
|
||||
Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name()));
|
||||
}
|
||||
|
||||
PlatformChunkGenerator access = null;
|
||||
@@ -143,15 +164,16 @@ public class IrisCreator {
|
||||
}
|
||||
return finalAccess1.getEngine().getGenerated();
|
||||
};
|
||||
while (g.get() < req) {
|
||||
double v = (double) g.get() / (double) req;
|
||||
|
||||
if (sender.isPlayer()) {
|
||||
sender.sendProgress(v, "Generating");
|
||||
J.sleep(16);
|
||||
} else {
|
||||
sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - g.get()) + " Left)")));
|
||||
J.sleep(1000);
|
||||
if(!benchmark) {
|
||||
while (g.get() < req) {
|
||||
double v = (double) g.get() / (double) req;
|
||||
if (sender.isPlayer()) {
|
||||
sender.sendProgress(v, "Generating");
|
||||
J.sleep(16);
|
||||
} else {
|
||||
sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - g.get()) + " Left)")));
|
||||
J.sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -171,13 +193,13 @@ public class IrisCreator {
|
||||
|
||||
done.set(true);
|
||||
|
||||
if (sender.isPlayer()) {
|
||||
if (sender.isPlayer() && !benchmark) {
|
||||
J.s(() -> {
|
||||
sender.player().teleport(new Location(world.get(), 0, world.get().getHighestBlockYAt(0, 0), 0));
|
||||
});
|
||||
}
|
||||
|
||||
if (studio) {
|
||||
if (studio || benchmark) {
|
||||
J.s(() -> {
|
||||
Iris.linkMultiverseCore.removeFromConfig(world.get());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user