forked from SteamWar/SteamWar
Compare commits
388
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b42f0d13c | ||
|
|
4306fe7bc9 | ||
|
|
58df6087f0 | ||
|
|
b9b7869124 | ||
|
|
1e85b14667 | ||
|
|
35c27923aa | ||
|
|
c3b3e3e60f | ||
|
|
3aa1bf7ffd | ||
|
|
5a02a58437 | ||
|
|
6209b86149 | ||
|
|
6f1403df9c | ||
|
|
0113788da2 | ||
|
|
8a7f65e000 | ||
|
|
8401f67b24 | ||
|
|
362468e756 | ||
|
|
ece12df0bc | ||
|
|
f35c07ab5b | ||
|
|
549f7e555c | ||
|
|
859238d7fa | ||
|
|
a79b00f78f | ||
|
|
105eda32e6 | ||
|
|
b4487b8079 | ||
|
|
ea3aad3bd2 | ||
|
|
d307f890e2 | ||
|
|
97c1da1b2a | ||
|
|
8a53aecfac | ||
|
|
5236afba17 | ||
|
|
d3c8b6e1c6 | ||
|
|
00ea792eee | ||
|
|
38e845b0e4 | ||
|
|
c60a8caed8 | ||
|
|
2e390286b2 | ||
|
|
6476125a3f | ||
|
|
311437d451 | ||
|
|
5a52771ec1 | ||
|
|
72b70a62e1 | ||
|
|
8575dcac33 | ||
|
|
cb744f6aa0 | ||
|
|
227f63c9ff | ||
|
|
397b10c319 | ||
|
|
32569f19d9 | ||
|
|
f19e4158e7 | ||
|
|
6c46b5b2a2 | ||
|
|
58516448d9 | ||
|
|
683236bb59 | ||
|
|
8dc101639d | ||
|
|
792620804a | ||
|
|
4aa7c99a6e | ||
|
|
cce18124f2 | ||
|
|
18ad0ad90c | ||
|
|
a58de898bb | ||
|
|
507b7c2569 | ||
|
|
a18098b8f4 | ||
|
|
97773f292d | ||
|
|
5fdfc03587 | ||
|
|
493e66cc98 | ||
|
|
2be3a136ae | ||
|
|
c62a566447 | ||
|
|
0684765a76 | ||
|
|
c40f29c3c1 | ||
|
|
72dc4eee9e | ||
|
|
c7a949322e | ||
|
|
9d5b7893f1 | ||
|
|
ae898e14c2 | ||
|
|
726f73cc45 | ||
|
|
badff1c70f | ||
|
|
1d2ac4f705 | ||
|
|
b48c75ef74 | ||
|
|
8b6ea12a08 | ||
|
|
801678ddd3 | ||
|
|
e5cc874834 | ||
|
|
95119fc93f | ||
|
|
d84ca3547a | ||
|
|
25ab79abc0 | ||
|
|
582d6a62e3 | ||
|
|
5eec792aff
|
||
|
|
e0f26c3e8d
|
||
|
|
a59e9b4343 | ||
|
|
64e627514d | ||
|
|
a8c68864d8 | ||
|
|
c0668723d7 | ||
|
|
5bc2daf37a | ||
|
|
e6d39da36b | ||
|
|
390d388692 | ||
|
|
9a60ac228c | ||
|
|
dab443b989 | ||
|
|
bf3c65c630 | ||
|
|
b488c4ed7c | ||
|
|
2e795aaf8e | ||
|
|
7a601235f5 | ||
|
|
3a247de43d
|
||
|
|
62e855ec1b
|
||
|
|
9e7311934f | ||
|
|
6fd3e6f690
|
||
|
|
7acd51fd61
|
||
|
|
b278ca15f3
|
||
|
|
029249c2b0
|
||
|
|
1ceb10439b
|
||
|
|
a5dfe6ab7e
|
||
|
|
c8a5f567eb | ||
|
|
47fb4da85b
|
||
|
|
0eef22aab0 | ||
|
|
013d18614f | ||
|
|
c7c1ab64e0 | ||
|
|
b68a27fbb6 | ||
|
|
7038dc2aa5
|
||
|
|
7af586ec16
|
||
|
|
b04e99ce54 | ||
|
|
524702fbb9 | ||
|
|
e07298e748 | ||
|
|
e1df793e9f | ||
|
|
806a1affea | ||
|
|
c538cdbbd2 | ||
|
|
d7ba19049a | ||
|
|
47909b6f07 | ||
|
|
48846a698f | ||
|
|
b771c95b99 | ||
|
|
d0aada2b00 | ||
|
|
6522fc77f2 | ||
|
|
27e01a56ae | ||
|
|
ed89770c0f | ||
|
|
3ec3c90f04 | ||
|
|
73d4ed26c8 | ||
|
|
256bcfb1bf | ||
|
|
28ce288815 | ||
|
|
6599dd026a | ||
|
|
03052b677f | ||
|
|
f76a6fa79d | ||
|
|
7fb7f46ca7 | ||
|
|
1269b7f00a | ||
|
|
91a0685724 | ||
|
|
72dd2ef59a | ||
|
|
54a1549973 | ||
|
|
fd5f5b92b4 | ||
|
|
60dc5e4442 | ||
|
|
4cdaf759af | ||
|
|
6e919d9148 | ||
|
|
a20ec8c93d | ||
|
|
18b65a2984 | ||
|
|
669235709e | ||
|
|
796e154c1c | ||
|
|
9efe35fe0d | ||
|
|
e0aaacd66a | ||
|
|
7adb1e8b4a | ||
|
|
b88e592e79 | ||
|
|
914134600e | ||
|
|
27877938bc
|
||
|
|
701964c2f2 | ||
|
|
70c8678c60
|
||
|
|
6cbfc94e6d | ||
|
|
c0ff123279 | ||
|
|
5511a1f08e | ||
|
|
8c8da355bb | ||
|
|
7326ed4aa0 | ||
|
|
2d59eb81c7 | ||
|
|
711920464a | ||
|
|
117dbd08ae | ||
|
|
b36464e69e | ||
|
|
f5ac006c0c | ||
|
|
414bfbfe3c | ||
|
|
c362a3e1f0 | ||
|
|
2b43af8851 | ||
|
|
1590f8f0ee | ||
|
|
932732737d | ||
|
|
2bc164c1b0 | ||
|
|
aa66b3dc83 | ||
|
|
f5d9c6e175 | ||
|
|
36b31fac77 | ||
|
|
641cefad01 | ||
|
|
eb866125ea | ||
|
|
961331f029 | ||
|
|
786257ad0e | ||
|
|
997292d58e | ||
|
|
8050f51424
|
||
|
|
e176b3bca8 | ||
|
|
a6681ffaf6
|
||
|
|
a23530074c
|
||
|
|
e88a4c624b
|
||
|
|
105beaf7a6 | ||
|
|
5f7ab3cd7b
|
||
|
|
f81f05c3d0 | ||
|
|
0afb6ce06a | ||
|
|
5ce69e6b7a
|
||
|
|
a938abde3f | ||
|
|
ec9b0387c5 | ||
|
|
03c3d49659 | ||
|
|
8d9a77ab67 | ||
|
|
fc2997e011 | ||
|
|
8eb5f5ddf2 | ||
|
|
aa807060f4 | ||
|
|
9bbbab9d4b | ||
|
|
7cca4ada10 | ||
|
|
725e6df047 | ||
|
|
f3ce124a23 | ||
|
|
e83f72a53e | ||
|
|
def0c19e43 | ||
|
|
3810ccd63d | ||
|
|
9e43d5cd1b | ||
|
|
2ad9ae3c7f | ||
|
|
847eb3fe5d | ||
|
|
8fa9f7b0d3 | ||
|
|
559cae2b6d | ||
|
|
5dbf3638d0 | ||
|
|
a018af1c8a | ||
|
|
fd8f942014 | ||
|
|
eab8826583 | ||
|
|
bc0177df43 | ||
|
|
1dc78b8eb8 | ||
|
|
a9fb982143 | ||
|
|
5b8d881e01 | ||
|
|
eb55f4b395 | ||
|
|
273db91d06 | ||
|
|
983ad544c1 | ||
|
|
a6a34b2221 | ||
|
|
6c6bd19038 | ||
|
|
89e05cd109 | ||
|
|
ea9d7ac584 | ||
|
|
17e1cf53b0 | ||
|
|
f64f337f17 | ||
|
|
c5f5be7d58 | ||
|
|
9f18644763 | ||
|
|
1de17d27f4 | ||
|
|
3cd0db9bdf | ||
|
|
9711b48f2f | ||
|
|
9934b8bbb2
|
||
|
|
6447265b90 | ||
|
|
71258318db | ||
|
|
52e95e2649 | ||
|
|
de6ac2cf20 | ||
|
|
628001e693 | ||
|
|
47c148d64a | ||
|
|
78617d5a98 | ||
|
|
69b924ded6 | ||
|
|
002f7e5542 | ||
|
|
5d70f75ac9 | ||
|
|
7f21a31ec9 | ||
|
|
23b5ab3e82 | ||
|
|
4f9fe07951 | ||
|
|
3bcff4c5ce | ||
|
|
1810cb7546 | ||
|
|
e55ca911c4 | ||
|
|
793f2de6c3 | ||
|
|
54fa47bd99 | ||
|
|
14a770b207 | ||
|
|
7b3a04f4eb | ||
|
|
f2a06057a8 | ||
|
|
e11f3f7cbc | ||
|
|
ebc10c1ce4 | ||
|
|
d682e35159 | ||
|
|
7d74eb0c09 | ||
|
|
7e18207b87 | ||
|
|
72b23ad116 | ||
|
|
c508627d92 | ||
|
|
93ff982649 | ||
|
|
21f6394359 | ||
|
|
29d0c8978c | ||
|
|
7366f83b15 | ||
|
|
9240bcfd5f | ||
|
|
bede8caa82 | ||
|
|
108aa2af9a | ||
|
|
d07a86c13f | ||
|
|
29106d5bb5 | ||
|
|
32fd4b4630 | ||
|
|
c241aef932 | ||
|
|
2db24ef2eb | ||
|
|
a2caa79f99 | ||
|
|
e49cfa9495 | ||
|
|
1f44b3169e | ||
|
|
49fafa5955 | ||
|
|
c81e6b15e5 | ||
|
|
dc0365834a | ||
|
|
13334e03a4 | ||
|
|
b35b2c0138 | ||
|
|
6ef311ce68 | ||
|
|
68d9c55525 | ||
|
|
dcd70c5ced | ||
|
|
a1d22b7d77 | ||
|
|
3b6fdbeec3 | ||
|
|
714f86a55b | ||
|
|
a177cc4faf | ||
|
|
09aa2ee22c | ||
|
|
b8499a7a8a | ||
|
|
e50bff3d38 | ||
|
|
8424f842c3 | ||
|
|
8f23f57415 | ||
|
|
3b65b93e73 | ||
|
|
4a458f0e92 | ||
|
|
5f5a98bcd6 | ||
|
|
72df919312 | ||
|
|
7ed36fe56e | ||
|
|
a7a8c4d051 | ||
|
|
5da3767378 | ||
|
|
53f98d4cd7 | ||
|
|
48fb6b5ed7 | ||
|
|
24d8ec7301 | ||
|
|
ba29e5cf23 | ||
|
|
a5992a9e4e | ||
|
|
e94eac9b9d
|
||
|
|
a000beee20 | ||
|
|
2fd6c40b15 | ||
|
|
32a2cbb4dd | ||
|
|
cf7a1ee086 | ||
|
|
8da7956523 | ||
|
|
9b821ff08f | ||
|
|
ae6f279dcf | ||
|
|
deb56c0c02 | ||
|
|
aead25650e | ||
|
|
53ada2de83 | ||
|
|
496cc3121c | ||
|
|
e9c766dbbb | ||
|
|
706f6ed743 | ||
|
|
270d82eb71 | ||
|
|
6da180136e | ||
|
|
463d8336a7 | ||
|
|
c241b9c264 | ||
|
|
b98273a7b2
|
||
|
|
bd28b133a2
|
||
|
|
5c618d03e8 | ||
|
|
89b8a3ea42 | ||
|
|
4198a08cda | ||
|
|
9f319128cc | ||
|
|
088d548d61 | ||
|
|
e435154c12 | ||
|
|
eceb58b28c | ||
|
|
5125453406 | ||
|
|
d110df924e | ||
|
|
81dd8045f2 | ||
|
|
245072f02c | ||
|
|
00147f2a74 | ||
|
|
fcc370c353 | ||
|
|
3bd1cf7167 | ||
|
|
cfa650bcf4 | ||
|
|
ba4ee08489 | ||
|
|
723a7dc0ca | ||
|
|
88de28ed68 | ||
|
|
6f1a3fe70c | ||
|
|
4a43e09a8b | ||
|
|
6fb018b86b | ||
|
|
ec310dfee9 | ||
|
|
9de5a93997 | ||
|
|
ce88e88859 | ||
|
|
5589c6cd20
|
||
|
|
35dead9c74 | ||
|
|
f1fbe14e60 | ||
|
|
b146c9928f | ||
|
|
136b0f5b97
|
||
|
|
2d679028c0
|
||
|
|
ce1f947f4b | ||
|
|
5fb51b63c3
|
||
|
|
c04dc8fd86
|
||
|
|
ab3970981d | ||
|
|
9e4c9ce04a | ||
|
|
44e37467d6
|
||
|
|
7c74ca014d
|
||
|
|
e7454f6ce8 | ||
|
|
a100d2d798 | ||
|
|
3c48e7c02d | ||
|
|
2b3c79fcab | ||
|
|
7ff778b60a | ||
|
|
b83476b451 | ||
|
|
58652cac5c | ||
|
|
b216438a47 | ||
|
|
604657a084 | ||
|
|
5a57b5f799 | ||
|
|
be233c65fe | ||
|
|
9f201f8191 | ||
|
|
55c1962294
|
||
|
|
441932b30a
|
||
|
|
bdecec304a | ||
|
|
75e3e77478 | ||
|
|
5c93ca6143
|
||
|
|
0452a9faa5 | ||
|
|
9a75f38226 | ||
|
|
6d24aa160f
|
||
|
|
105630bbd8
|
||
|
|
228ab5b2f2 | ||
|
|
42808f40c0 | ||
|
|
57c21122e6 | ||
|
|
42faba70d9 | ||
|
|
99e1f01869 | ||
|
|
13bddbe359 | ||
|
|
51ff0e1a9f | ||
|
|
6766862a00 | ||
|
|
c30aad179b | ||
|
|
d3aad6a198 | ||
|
|
744dc67ca9 | ||
|
|
164a7f5826 | ||
|
|
210cfcf3a6 |
@@ -1,6 +1,6 @@
|
|||||||
name: Feature Idee
|
name: Feature Idee
|
||||||
about: Du hast eine Idee für ein neues Feature, welches SteamWar nicht hat? Stelle sie hier vor.
|
about: Du hast eine Idee für ein neues Feature, welches SteamWar nicht hat? Stelle sie hier vor.
|
||||||
labels: ["typ/idee"]
|
labels: [ "typ/idee" ]
|
||||||
body:
|
body:
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: description
|
id: description
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "$SW_MAVEN_CREDENTIALS" > steamwar.properties
|
echo "$SW_MAVEN_CREDENTIALS" > steamwar.properties
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew build --no-daemon
|
run: ./gradlew clean build --no-daemon --no-build-cache --refresh-dependencies
|
||||||
|
|
||||||
- name: Stage deploy artifacts
|
- name: Stage deploy artifacts
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -51,8 +51,8 @@ jobs:
|
|||||||
rm -rf deploy
|
rm -rf deploy
|
||||||
mkdir -p deploy
|
mkdir -p deploy
|
||||||
|
|
||||||
|
cp "AccessWidener/build/libs/AccessWidener-all.jar" "deploy/AccessWidener.jar"
|
||||||
cp "BauSystem/build/libs/BauSystem-all.jar" "deploy/BauSystem.jar"
|
cp "BauSystem/build/libs/BauSystem-all.jar" "deploy/BauSystem.jar"
|
||||||
cp "LegacyBauSystem/build/libs/LegacyBauSystem.jar" "deploy/BauSystem-1.12.jar"
|
|
||||||
cp "FightSystem/build/libs/FightSystem-all.jar" "deploy/FightSystem.jar"
|
cp "FightSystem/build/libs/FightSystem-all.jar" "deploy/FightSystem.jar"
|
||||||
cp "KotlinCore/build/libs/KotlinCore-all.jar" "deploy/KotlinCore.jar"
|
cp "KotlinCore/build/libs/KotlinCore-all.jar" "deploy/KotlinCore.jar"
|
||||||
cp "TNTLeague/build/libs/TNTLeague.jar" "deploy/TNTLeague.jar"
|
cp "TNTLeague/build/libs/TNTLeague.jar" "deploy/TNTLeague.jar"
|
||||||
@@ -130,7 +130,12 @@ jobs:
|
|||||||
ssh-keyscan -p "$port" "$DEPLOY_HOST" >> ~/.ssh/known_hosts
|
ssh-keyscan -p "$port" "$DEPLOY_HOST" >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH'"
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH'"
|
||||||
scp -i ~/.ssh/deploy_key -P "$port" deploy/* "${DEPLOY_USER}@${DEPLOY_HOST}:$DEPLOY_PATH/"
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH/upload'"
|
||||||
|
scp -i ~/.ssh/deploy_key -P "$port" deploy/* "${DEPLOY_USER}@${DEPLOY_HOST}:$DEPLOY_PATH/upload"
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -f '$DEPLOY_PATH'/*.jar '$DEPLOY_PATH'/*.zip"
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mv '$DEPLOY_PATH'/upload/* '$DEPLOY_PATH'"
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -r '$DEPLOY_PATH/upload'"
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "chmod o-w '$DEPLOY_PATH'/*"
|
||||||
- name: Restart Services
|
- name: Restart Services
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ bin/
|
|||||||
.vscode
|
.vscode
|
||||||
.settings
|
.settings
|
||||||
|
|
||||||
|
# Language Server
|
||||||
|
**/.project
|
||||||
|
**/.factorypath
|
||||||
|
**/.classpath
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
lib
|
lib
|
||||||
/WebsiteBackend/data
|
/WebsiteBackend/data
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Remote JVM Debugger" type="Remote">
|
||||||
|
<option name="USE_SOCKET_TRANSPORT" value="true" />
|
||||||
|
<option name="SERVER_MODE" value="false" />
|
||||||
|
<option name="SHMEM_ADDRESS" />
|
||||||
|
<option name="HOST" value="localhost" />
|
||||||
|
<option name="PORT" value="5005" />
|
||||||
|
<option name="AUTO_RESTART" value="false" />
|
||||||
|
<RunnerSettings RunnerId="Debug">
|
||||||
|
<option name="DEBUG_PORT" value="5005" />
|
||||||
|
<option name="LOCAL" value="false" />
|
||||||
|
</RunnerSettings>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
alias(libs.plugins.shadow)
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.ow2.asm:asm:9.7")
|
||||||
|
implementation("org.ow2.asm:asm-commons:9.7")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.shadowJar {
|
||||||
|
manifest {
|
||||||
|
attributes(
|
||||||
|
"Manifest-Version" to "1.0",
|
||||||
|
"Build-Jdk-Spec" to "21",
|
||||||
|
"Main-Class" to "de.steamwar.Main",
|
||||||
|
"Premain-Class" to "de.steamwar.Agent",
|
||||||
|
"Can-Retransform-Classes" to "true",
|
||||||
|
"Can-Redefine-Classes" to "true",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.build {
|
||||||
|
dependsOn(tasks.shadowJar)
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single parsed line from a .accesswidener file.
|
||||||
|
* <p>
|
||||||
|
* Examples:
|
||||||
|
* accessible class net/minecraft/server/level/ServerPlayer
|
||||||
|
* accessible method net/minecraft/server/level/ServerPlayer getStats ()V
|
||||||
|
* mutable field net/minecraft/world/entity/Entity id I
|
||||||
|
* extendable class net/minecraft/world/level/chunk/LevelChunk
|
||||||
|
*/
|
||||||
|
public record AccessWidenerEntry(
|
||||||
|
/** accessible | mutable | extendable (may have "transitive-" prefix) */
|
||||||
|
String directive,
|
||||||
|
/** class | method | field */
|
||||||
|
String memberType,
|
||||||
|
/** Internal class name, e.g. net/minecraft/server/level/ServerPlayer */
|
||||||
|
String target,
|
||||||
|
/** Method/field name, null for class entries */
|
||||||
|
String name,
|
||||||
|
/** Descriptor, null for class entries */
|
||||||
|
String descriptor) {
|
||||||
|
/**
|
||||||
|
* Returns true if this entry targets the class with the given internal name.
|
||||||
|
*/
|
||||||
|
public boolean targets(String internalName) {
|
||||||
|
return target.equals(internalName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses Fabric-compatible .accesswidener files.
|
||||||
|
* <p>
|
||||||
|
* Supported format:
|
||||||
|
* <pre>
|
||||||
|
* accessWidener v2 named
|
||||||
|
*
|
||||||
|
* # comments are supported
|
||||||
|
* accessible class net/minecraft/Foo
|
||||||
|
* accessible method net/minecraft/Foo someMethod ()V
|
||||||
|
* accessible field net/minecraft/Foo someField I
|
||||||
|
* mutable field net/minecraft/Foo someField I
|
||||||
|
* extendable class net/minecraft/Foo
|
||||||
|
* extendable method net/minecraft/Foo someMethod ()V
|
||||||
|
*
|
||||||
|
* # transitive variants (expose widening to dependents)
|
||||||
|
* transitive-accessible class net/minecraft/Foo
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public final class AccessWidenerParser {
|
||||||
|
|
||||||
|
private AccessWidenerParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AccessWidenerEntry> parse(InputStream in) throws IOException {
|
||||||
|
List<AccessWidenerEntry> entries = new ArrayList<>();
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
|
||||||
|
|
||||||
|
String line;
|
||||||
|
boolean headerSeen = false;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
// Strip inline comments
|
||||||
|
int commentIdx = line.indexOf('#');
|
||||||
|
if (commentIdx >= 0) line = line.substring(0, commentIdx);
|
||||||
|
line = line.strip();
|
||||||
|
|
||||||
|
if (line.isEmpty()) continue;
|
||||||
|
|
||||||
|
if (!headerSeen) {
|
||||||
|
// First non-blank, non-comment line must be the header
|
||||||
|
if (!line.startsWith("accessWidener")) {
|
||||||
|
throw new IOException("Missing accessWidener header, got: " + line);
|
||||||
|
}
|
||||||
|
headerSeen = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessWidenerEntry entry = parseLine(line);
|
||||||
|
if (entry != null) entries.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AccessWidenerEntry parseLine(String line) {
|
||||||
|
String[] parts = line.split("\\s+");
|
||||||
|
if (parts.length < 3) return null;
|
||||||
|
|
||||||
|
String directive = parts[0]; // accessible / mutable / extendable / transitive-*
|
||||||
|
String memberType = parts[1]; // class / method / field
|
||||||
|
String target = parts[2]; // internal class name
|
||||||
|
|
||||||
|
return switch (memberType) {
|
||||||
|
case "class" -> new AccessWidenerEntry(directive, "class", target, null, null);
|
||||||
|
case "method", "field" -> {
|
||||||
|
if (parts.length < 5) yield null;
|
||||||
|
yield new AccessWidenerEntry(directive, memberType, target, parts[3], parts[4]);
|
||||||
|
}
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.instrument.Instrumentation;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java agent entry point.
|
||||||
|
* <p>
|
||||||
|
* At JVM startup: java -javaagent:paper-access-widener-agent.jar -jar server.jar
|
||||||
|
* <p>
|
||||||
|
* On attach the agent:
|
||||||
|
* <ol>
|
||||||
|
* <li>Find all .jar files inside the plugins folder</li>
|
||||||
|
* <li>Scan all found jars for *.accesswidener resources</li>
|
||||||
|
* <li>Transform any class during loading</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
public class Agent {
|
||||||
|
private Agent() {
|
||||||
|
throw new IllegalStateException("Utility class");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger("AccessWidenerAgent");
|
||||||
|
|
||||||
|
// -javaagent: startup
|
||||||
|
public static void premain(String args, Instrumentation inst) {
|
||||||
|
init(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void init(Instrumentation inst) {
|
||||||
|
LOG.info("[AccessWidener] Agent initialising.");
|
||||||
|
|
||||||
|
List<AccessWidenerEntry> entries = new ArrayList<>();
|
||||||
|
File file = new File(new File(".").getAbsoluteFile(), "plugins/");
|
||||||
|
File[] files = file.listFiles();
|
||||||
|
if (files == null) files = new File[0];
|
||||||
|
for (File jarFile : files) {
|
||||||
|
if (!jarFile.isFile()) continue;
|
||||||
|
if (!jarFile.getName().endsWith(".jar")) continue;
|
||||||
|
try {
|
||||||
|
entries.addAll(Utils.findAndParseAccessWideners(jarFile.toPath()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warning("Failed to parse access wideners from " + jarFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG.info("[AccessWidener] Loaded " + entries.size() + " access wideners.");
|
||||||
|
|
||||||
|
inst.addTransformer(new WideningTransformer(entries), false);
|
||||||
|
LOG.info("[AccessWidener] Agent ready.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses ASM to patch class bytecode according to a list of access widener entries.
|
||||||
|
*
|
||||||
|
* Returns {@code null} if the class is not targeted by any entry (no-op signal
|
||||||
|
* to the caller so it can skip the write).
|
||||||
|
*/
|
||||||
|
public class ClassPatcher {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger("ClassPatcher");
|
||||||
|
|
||||||
|
private final List<AccessWidenerEntry> entries;
|
||||||
|
|
||||||
|
/** Pre-computed set of targeted internal names for fast filtering. */
|
||||||
|
private final Set<String> targets;
|
||||||
|
|
||||||
|
private final Set<String> targetsPublicConstructor;
|
||||||
|
|
||||||
|
public ClassPatcher(List<AccessWidenerEntry> entries) {
|
||||||
|
this.entries = entries;
|
||||||
|
this.targets = entries.stream()
|
||||||
|
.map(AccessWidenerEntry::target)
|
||||||
|
.flatMap(s -> {
|
||||||
|
if (!s.contains("$")) return Stream.of(s);
|
||||||
|
int index = s.lastIndexOf('$');
|
||||||
|
return Stream.of(s, s.substring(0, index));
|
||||||
|
})
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
this.targetsPublicConstructor = entries.stream()
|
||||||
|
.filter(entry -> entry.directive().equals("transitive-extendable"))
|
||||||
|
.map(AccessWidenerEntry::target)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patches {@code classBytes} if {@code className} is targeted.
|
||||||
|
*
|
||||||
|
* @return patched bytes, or {@code null} if no changes were needed
|
||||||
|
*/
|
||||||
|
public byte[] patch(String className, byte[] classBytes) {
|
||||||
|
if (!targets.contains(className)) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ClassReader cr = new ClassReader(classBytes);
|
||||||
|
ClassWriter cw = new ClassWriter(cr, 0);
|
||||||
|
cr.accept(new ClassTransformer(cw, className, entries, targetsPublicConstructor.contains(className)), ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||||
|
return cw.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warning("[AccessWidener] Failed to transform " + className + ": " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.FieldVisitor;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ClassTransformer extends ClassVisitor {
|
||||||
|
|
||||||
|
private final String internalName;
|
||||||
|
private final List<AccessWidenerEntry> entries;
|
||||||
|
private final boolean appendPublicConstructor;
|
||||||
|
|
||||||
|
public ClassTransformer(ClassVisitor cv, String internalName, List<AccessWidenerEntry> entries, boolean appendPublicConstructor) {
|
||||||
|
super(Opcodes.ASM9, cv);
|
||||||
|
this.internalName = internalName;
|
||||||
|
this.entries = entries;
|
||||||
|
this.appendPublicConstructor = appendPublicConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
int newAccess = access;
|
||||||
|
for (AccessWidenerEntry e : entries) {
|
||||||
|
if (!e.targets(internalName) || !"class".equals(e.memberType())) continue;
|
||||||
|
newAccess = applyDirective(e.directive(), newAccess, false);
|
||||||
|
}
|
||||||
|
if (appendPublicConstructor) {
|
||||||
|
MethodVisitor methodVisitor = visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
|
||||||
|
methodVisitor.visitCode();
|
||||||
|
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
|
methodVisitor.visitMethodInsn(
|
||||||
|
Opcodes.INVOKESPECIAL,
|
||||||
|
"java/lang/Object",
|
||||||
|
"<init>",
|
||||||
|
"()V",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
methodVisitor.visitInsn(Opcodes.RETURN);
|
||||||
|
methodVisitor.visitMaxs(1, 1);
|
||||||
|
methodVisitor.visitEnd();
|
||||||
|
}
|
||||||
|
super.visit(version, newAccess, name, signature, superName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInnerClass(String name, String outerName, String innerName, int access) {
|
||||||
|
int newAccess = access;
|
||||||
|
for (AccessWidenerEntry e : entries) {
|
||||||
|
if (!e.target().equals(name) || !"class".equals(e.memberType())) continue;
|
||||||
|
newAccess = applyDirective(e.directive(), newAccess, false);
|
||||||
|
}
|
||||||
|
super.visitInnerClass(name, outerName, innerName, newAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||||
|
int newAccess = access;
|
||||||
|
for (AccessWidenerEntry e : entries) {
|
||||||
|
if (!e.targets(internalName) || !"method".equals(e.memberType())) continue;
|
||||||
|
if (!name.equals(e.name()) || !descriptor.equals(e.descriptor())) continue;
|
||||||
|
newAccess = applyDirective(e.directive(), newAccess, false);
|
||||||
|
}
|
||||||
|
return super.visitMethod(newAccess, name, descriptor, signature, exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
|
||||||
|
int newAccess = access;
|
||||||
|
for (AccessWidenerEntry e : entries) {
|
||||||
|
if (!e.targets(internalName) || !"field".equals(e.memberType())) continue;
|
||||||
|
if (!name.equals(e.name())) continue;
|
||||||
|
newAccess = applyDirective(e.directive(), newAccess, true);
|
||||||
|
}
|
||||||
|
return super.visitField(newAccess, name, descriptor, signature, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a directive to an access bitmask.
|
||||||
|
*
|
||||||
|
* @param directive accessible / mutable / extendable (with optional "transitive-" prefix)
|
||||||
|
* @param access current access flags
|
||||||
|
* @param isField true when processing a field (mutable removes final)
|
||||||
|
*/
|
||||||
|
private static int applyDirective(String directive, int access, boolean isField) {
|
||||||
|
// Strip transitive- prefix — the widening itself is the same
|
||||||
|
String effective = directive.startsWith("transitive-") ? directive.substring("transitive-".length()) : directive;
|
||||||
|
|
||||||
|
return switch (effective) {
|
||||||
|
case "accessible" -> makePublic(access);
|
||||||
|
case "extendable" -> makePublic(removeFinal(access));
|
||||||
|
case "mutable" -> isField ? removeFinal(access) : access;
|
||||||
|
default -> access;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int makePublic(int access) {
|
||||||
|
return (access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) | Opcodes.ACC_PUBLIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int removeFinal(int access) {
|
||||||
|
return access & ~Opcodes.ACC_FINAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command-line tool that produces a widened copy of a JAR for use as a
|
||||||
|
* compile-time stub in IntelliJ / Gradle.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* java -jar jar-widener.jar <input.jar> <output.jar> [file.accesswidener ...]
|
||||||
|
*
|
||||||
|
* The output JAR is identical to the input JAR except that every class
|
||||||
|
* targeted by the access widener entries has its access flags patched:
|
||||||
|
* accessible → public
|
||||||
|
* extendable → public + non-final
|
||||||
|
* mutable → non-final field
|
||||||
|
*
|
||||||
|
* Intended for use as a Gradle task so IntelliJ sees the already-widened
|
||||||
|
* class when you Ctrl+click NMS code, and javac compiles without complaints.
|
||||||
|
*/
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
if (args.length < 2) {
|
||||||
|
System.err.println("Usage: jar-widener <input.jar> <output.jar> [*.accesswidener ...]");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path inputJar = Path.of(args[0]);
|
||||||
|
Path outputJar = Path.of(args[1]);
|
||||||
|
|
||||||
|
if (!Files.exists(inputJar)) {
|
||||||
|
System.err.println("Input JAR not found: " + inputJar);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Collect all access widener entries ---
|
||||||
|
List<AccessWidenerEntry> entries = new ArrayList<>();
|
||||||
|
|
||||||
|
if (args.length > 2) {
|
||||||
|
for (int i = 2; i < args.length; i++) {
|
||||||
|
Path awFile = Path.of(args[i]);
|
||||||
|
if (!Files.exists(awFile)) {
|
||||||
|
System.err.println("Warning: access widener file not found, skipping: " + awFile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try (InputStream in = Files.newInputStream(awFile)) {
|
||||||
|
List<AccessWidenerEntry> parsed = AccessWidenerParser.parse(in);
|
||||||
|
System.out.println("Loaded " + parsed.size() + " entries from " + awFile.getFileName());
|
||||||
|
entries.addAll(parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entries.isEmpty()) {
|
||||||
|
System.out.println("No access widener entries found — copying JAR unchanged.");
|
||||||
|
Files.createDirectories(outputJar.getParent());
|
||||||
|
Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Widening " + inputJar.getFileName()
|
||||||
|
+ " with " + entries.size() + " total entr"
|
||||||
|
+ (entries.size() == 1 ? "y" : "ies") + "...");
|
||||||
|
|
||||||
|
// --- Copy input → output, transforming .class files in place ---
|
||||||
|
Files.createDirectories(outputJar.getParent());
|
||||||
|
Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
ClassPatcher patcher = new ClassPatcher(entries);
|
||||||
|
|
||||||
|
try (FileSystem fs = FileSystems.newFileSystem(outputJar)) {
|
||||||
|
// Walk every .class entry in the JAR
|
||||||
|
try (var stream = Files.walk(fs.getPath("/"))) {
|
||||||
|
stream.filter(p -> p.toString().endsWith(".class"))
|
||||||
|
.forEach(classPath -> patchClass(fs, classPath, patcher));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Done. Widened JAR written to " + outputJar);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void patchClass(FileSystem fs, Path classPath, ClassPatcher patcher) {
|
||||||
|
// Derive internal class name from path e.g. /net/minecraft/Foo.class → net/minecraft/Foo
|
||||||
|
String internalName = classPath.toString()
|
||||||
|
.replaceFirst("^/", "")
|
||||||
|
.replace(".class", "");
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] original = Files.readAllBytes(classPath);
|
||||||
|
byte[] patched = patcher.patch(internalName, original);
|
||||||
|
|
||||||
|
if (patched != null) {
|
||||||
|
Files.write(classPath, patched);
|
||||||
|
System.out.println(" Widened: " + internalName);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(" Warning: failed to patch " + internalName + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger("AccessWidenerAgent");
|
||||||
|
|
||||||
|
private Utils() {
|
||||||
|
throw new IllegalStateException("Utility class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AccessWidenerEntry> findAndParseAccessWideners(Path jarPath) throws IOException {
|
||||||
|
List<AccessWidenerEntry> results = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ZipFile zip = new ZipFile(jarPath.toFile())) {
|
||||||
|
Enumeration<? extends ZipEntry> entries = zip.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry entry = entries.nextElement();
|
||||||
|
if (entry.isDirectory() || !entry.getName().endsWith(".accesswidener")) continue;
|
||||||
|
|
||||||
|
try (InputStream in = zip.getInputStream(entry)) {
|
||||||
|
results.addAll(AccessWidenerParser.parse(in));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warning("[AccessWidener] Failed to parse " + entry.getName()
|
||||||
|
+ " in " + jarPath.getFileName() + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar;
|
||||||
|
|
||||||
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms class bytecode to apply access widening rules.
|
||||||
|
* <p>
|
||||||
|
* Also monitors for new plugin ClassLoaders appearing (when plugins load after
|
||||||
|
* the agent attaches) and automatically picks up their .accesswidener files.
|
||||||
|
*/
|
||||||
|
public class WideningTransformer implements ClassFileTransformer {
|
||||||
|
|
||||||
|
private final ClassPatcher patcher;
|
||||||
|
|
||||||
|
public WideningTransformer(List<AccessWidenerEntry> entries) {
|
||||||
|
patcher = new ClassPatcher(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
|
||||||
|
return patcher.patch(className, classfileBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
steamwar.java
|
steamwar.java
|
||||||
|
widener
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.compileJava {
|
tasks.compileJava {
|
||||||
@@ -34,15 +35,21 @@ dependencies {
|
|||||||
compileOnly(libs.classindex)
|
compileOnly(libs.classindex)
|
||||||
annotationProcessor(libs.classindex)
|
annotationProcessor(libs.classindex)
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
compileOnly(project(":SpigotCore", "default"))
|
||||||
|
compileOnly(project(":KotlinCore", "default"))
|
||||||
|
|
||||||
compileOnly(libs.axiom)
|
compileOnly(libs.axiom)
|
||||||
compileOnly(libs.authlib)
|
compileOnly(libs.authlib)
|
||||||
|
|
||||||
compileOnly(libs.paperapi21)
|
compileOnly(libs.paperapi)
|
||||||
compileOnly(libs.nms21)
|
compileOnly(libs.nms)
|
||||||
|
|
||||||
compileOnly(libs.fawe18)
|
compileOnly(libs.fawe)
|
||||||
|
compileOnly(libs.netty)
|
||||||
|
|
||||||
implementation(libs.luaj)
|
implementation(libs.luaj)
|
||||||
implementation(files("$projectDir/../libs/YAPION-SNAPSHOT.jar"))
|
// implementation(files("$projectDir/../libs/YAPION-SNAPSHOT.jar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
widener {
|
||||||
|
fromCatalog(libs.nms)
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
|||||||
|
accessWidener v2 named
|
||||||
|
|
||||||
|
# For NoClipCommand
|
||||||
|
accessible field net/minecraft/server/level/ServerPlayerGameMode gameModeForPlayer Lnet/minecraft/world/level/GameType;
|
||||||
|
|
||||||
|
# For PlaceItemUtils
|
||||||
|
accessible field org/bukkit/craftbukkit/block/CraftBlockState position Lnet/minecraft/core/BlockPos;
|
||||||
|
mutable field org/bukkit/craftbukkit/block/CraftBlockState position Lnet/minecraft/core/BlockPos;
|
||||||
|
accessible field org/bukkit/craftbukkit/block/CraftBlockState world Lorg/bukkit/craftbukkit/CraftWorld;
|
||||||
|
mutable field org/bukkit/craftbukkit/block/CraftBlockState world Lorg/bukkit/craftbukkit/CraftWorld;
|
||||||
|
|
||||||
|
# For TickManager
|
||||||
|
accessible field net/minecraft/server/ServerTickRateManager remainingSprintTicks J
|
||||||
@@ -20,8 +20,7 @@
|
|||||||
package de.steamwar.bausystem;
|
package de.steamwar.bausystem;
|
||||||
|
|
||||||
import de.steamwar.bausystem.config.BauServer;
|
import de.steamwar.bausystem.config.BauServer;
|
||||||
import de.steamwar.bausystem.configplayer.Config;
|
import de.steamwar.bausystem.config.ConfigStore;
|
||||||
import de.steamwar.bausystem.configplayer.ConfigConverter;
|
|
||||||
import de.steamwar.bausystem.features.gui.BauGUI;
|
import de.steamwar.bausystem.features.gui.BauGUI;
|
||||||
import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
|
import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
|
||||||
import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
|
import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
|
||||||
@@ -32,16 +31,17 @@ import de.steamwar.bausystem.features.tracer.TraceManager;
|
|||||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||||
import de.steamwar.bausystem.features.world.BauScoreboard;
|
import de.steamwar.bausystem.features.world.BauScoreboard;
|
||||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.region.RegionSystem;
|
import de.steamwar.bausystem.region.RegionSystem;
|
||||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
import de.steamwar.bausystem.utils.TickManager;
|
import de.steamwar.bausystem.utils.TickManager;
|
||||||
import de.steamwar.bausystem.worlddata.WorldData;
|
|
||||||
import de.steamwar.command.AbstractValidator;
|
import de.steamwar.command.AbstractValidator;
|
||||||
import de.steamwar.command.SWCommandUtils;
|
import de.steamwar.command.SWCommandUtils;
|
||||||
import de.steamwar.core.CRIUSleepEvent;
|
import de.steamwar.core.CRIUSleepEvent;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.core.WorldEditRendererCUIEditor;
|
|
||||||
import de.steamwar.core.WorldIdentifier;
|
import de.steamwar.core.WorldIdentifier;
|
||||||
|
import de.steamwar.core.worldedit.SteamEdit;
|
||||||
|
import de.steamwar.core.worldedit.WorldEditRendererCUIEditor;
|
||||||
import de.steamwar.linkage.AbstractLinker;
|
import de.steamwar.linkage.AbstractLinker;
|
||||||
import de.steamwar.linkage.SpigotLinker;
|
import de.steamwar.linkage.SpigotLinker;
|
||||||
import de.steamwar.message.Message;
|
import de.steamwar.message.Message;
|
||||||
@@ -49,6 +49,7 @@ import de.steamwar.providers.BauServerInfo;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameRule;
|
import org.bukkit.GameRule;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@@ -109,9 +110,6 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
if (any instanceof PanzernAlgorithm) {
|
if (any instanceof PanzernAlgorithm) {
|
||||||
Panzern.add((PanzernAlgorithm) any);
|
Panzern.add((PanzernAlgorithm) any);
|
||||||
}
|
}
|
||||||
if (any instanceof ConfigConverter) {
|
|
||||||
Config.addConfigConverter((ConfigConverter) any);
|
|
||||||
}
|
|
||||||
if (any instanceof BoundingBoxLoader) {
|
if (any instanceof BoundingBoxLoader) {
|
||||||
((BoundingBoxLoader) any).load();
|
((BoundingBoxLoader) any).load();
|
||||||
}
|
}
|
||||||
@@ -129,7 +127,19 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
TraceManager.instance.init();
|
TraceManager.instance.init();
|
||||||
TraceRecorder.instance.init();
|
TraceRecorder.instance.init();
|
||||||
|
|
||||||
new WorldEditRendererCUIEditor();
|
SteamEdit.init();
|
||||||
|
SteamEdit.ADJACENT_FILTERS = location -> {
|
||||||
|
Region region = Region.getRegion(location);
|
||||||
|
Region.Area area;
|
||||||
|
if (region.getBuildArea().inRegion(location, true)) {
|
||||||
|
area = region.getBuildArea();
|
||||||
|
} else if (region.getTestblockArea().inRegion(location, true)) {
|
||||||
|
area = region.getTestblockArea();
|
||||||
|
} else {
|
||||||
|
return SteamEdit.AdjacentFilter.ALWAYS;
|
||||||
|
}
|
||||||
|
return (x, y, z) -> area.inRegion(new Location(null, x, y, z), true);
|
||||||
|
};
|
||||||
|
|
||||||
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
|
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
|
||||||
|
|
||||||
@@ -145,9 +155,8 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
linker.unlink();
|
linker.unlink();
|
||||||
WorldData.write();
|
|
||||||
RegionSystem.INSTANCE.save();
|
RegionSystem.INSTANCE.save();
|
||||||
Config.getInstance().saveAll();
|
ConfigStore.saveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends CommandSender> AbstractValidator<T, ?> validator(Permission permission) {
|
private <T extends CommandSender> AbstractValidator<T, ?> validator(Permission permission) {
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a config of one version into the next version, e.g. ConfigV1 to
|
||||||
|
* ConfigV2. The converter for the second newest version converts into the
|
||||||
|
* current version. Converters are registered in the {@link ConfigStore}
|
||||||
|
* of the config.
|
||||||
|
*
|
||||||
|
* @param <F> the config version to convert from
|
||||||
|
* @param <T> the config version to convert to
|
||||||
|
*/
|
||||||
|
public interface ConfigConverter<F extends VersionedConfig, T extends VersionedConfig> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the version this converter converts from
|
||||||
|
*/
|
||||||
|
int version();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the config to the next version. If anything goes wrong do not
|
||||||
|
* silently exit this method, throw an Exception. The {@link ConfigStore}
|
||||||
|
* will deal with it.
|
||||||
|
*
|
||||||
|
* @param config the config to convert
|
||||||
|
* @return the converted config
|
||||||
|
*/
|
||||||
|
T convert(F config);
|
||||||
|
}
|
||||||
@@ -0,0 +1,364 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.config;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import de.steamwar.sql.UserConfig;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads, converts and saves a versioned config stored as JSON. Older versions
|
||||||
|
* are converted with the registered {@link ConfigConverter}s, legacy formats
|
||||||
|
* that are not JSON can be read with {@link #legacy(Predicate, Function)}.
|
||||||
|
* <p>
|
||||||
|
* A store can be bound to where the config is stored:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #userConfig(String)}: one config per player in the {@link UserConfig}, use {@link #get(Player)}</li>
|
||||||
|
* <li>{@link #file(File)}: one config in a file, use {@link #get()}</li>
|
||||||
|
* <li>unbound: use {@link #load(File)} and {@link #save(File, VersionedConfig)}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param <T> the current config version
|
||||||
|
*/
|
||||||
|
public class ConfigStore<T extends VersionedConfig> {
|
||||||
|
|
||||||
|
private static final List<ConfigStore<?>> STORES = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Class<T> type;
|
||||||
|
private final int version;
|
||||||
|
private final Supplier<T> defaultConfig;
|
||||||
|
|
||||||
|
private final Map<Integer, Class<? extends VersionedConfig>> jsonVersions = new HashMap<>();
|
||||||
|
private final Map<Integer, ConfigConverter<?, ?>> converters = new HashMap<>();
|
||||||
|
private final List<LegacyFormat> legacyFormats = new ArrayList<>();
|
||||||
|
private Gson gson = new Gson();
|
||||||
|
private Integer unversionedVersion = null;
|
||||||
|
|
||||||
|
private String userConfigKey = null;
|
||||||
|
private Predicate<T> removeIf = config -> false;
|
||||||
|
private final Map<UUID, T> playerConfigs = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private File file = null;
|
||||||
|
private File legacyFile = null;
|
||||||
|
private Function<String, ? extends VersionedConfig> legacyFileReader = null;
|
||||||
|
private T fileConfig = null;
|
||||||
|
|
||||||
|
private record LegacyFormat(Predicate<String> matches, Function<String, ? extends VersionedConfig> reader) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigStore(Class<T> type, int version, Supplier<T> defaultConfig) {
|
||||||
|
this.type = type;
|
||||||
|
this.version = version;
|
||||||
|
this.defaultConfig = defaultConfig;
|
||||||
|
jsonVersions.put(version, type);
|
||||||
|
STORES.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigStore<T> gson(Gson gson) {
|
||||||
|
this.gson = gson;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an older config version that is stored as JSON.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> jsonVersion(int version, Class<? extends VersionedConfig> type) {
|
||||||
|
jsonVersions.put(version, type);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigStore<T> converter(ConfigConverter<?, ?> converter) {
|
||||||
|
if (converters.putIfAbsent(converter.version(), converter) != null) {
|
||||||
|
throw new IllegalStateException("Duplicate converter for version " + converter.version() + " of " + type.getSimpleName());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a legacy format that is not JSON, stored strings matching the predicate are read by the reader.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> legacy(Predicate<String> matches, Function<String, ? extends VersionedConfig> reader) {
|
||||||
|
legacyFormats.add(new LegacyFormat(matches, reader));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version of stored JSON without a version field.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> unversioned(int version) {
|
||||||
|
this.unversionedVersion = version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds this store to the {@link UserConfig} with the given key, one config per player.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> userConfig(String key) {
|
||||||
|
this.userConfigKey = key;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the config from the {@link UserConfig} instead of saving it, if the predicate matches.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> removeIf(Predicate<T> removeIf) {
|
||||||
|
this.removeIf = removeIf;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds this store to a single file.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> file(File file) {
|
||||||
|
this.file = file;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legacy file to read, if the file of this store does not exist yet.
|
||||||
|
*/
|
||||||
|
public ConfigStore<T> legacyFile(File legacyFile, Function<String, ? extends VersionedConfig> reader) {
|
||||||
|
this.legacyFile = legacyFile;
|
||||||
|
this.legacyFileReader = reader;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a stored config and converts it to the current version.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException if the config could not be read or converted
|
||||||
|
*/
|
||||||
|
public T read(String stored) {
|
||||||
|
for (LegacyFormat legacyFormat : legacyFormats) {
|
||||||
|
if (legacyFormat.matches().test(stored)) {
|
||||||
|
return update(legacyFormat.reader().apply(stored));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject json = JsonParser.parseString(stored).getAsJsonObject();
|
||||||
|
int storedVersion;
|
||||||
|
if (json.has("version")) {
|
||||||
|
storedVersion = json.get("version").getAsInt();
|
||||||
|
} else if (unversionedVersion != null) {
|
||||||
|
storedVersion = unversionedVersion;
|
||||||
|
json.addProperty("version", storedVersion);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Missing version of " + type.getSimpleName());
|
||||||
|
}
|
||||||
|
Class<? extends VersionedConfig> storedType = jsonVersions.get(storedVersion);
|
||||||
|
if (storedType == null) {
|
||||||
|
throw new IllegalStateException("Unknown version " + storedVersion + " of " + type.getSimpleName());
|
||||||
|
}
|
||||||
|
return update(gson.fromJson(json, storedType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String write(T config) {
|
||||||
|
return gson.toJson(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a config to the current version.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public T update(VersionedConfig config) {
|
||||||
|
while (config.getVersion() < version) {
|
||||||
|
ConfigConverter converter = converters.get(config.getVersion());
|
||||||
|
if (converter == null) {
|
||||||
|
throw new IllegalStateException("No converter found for version " + config.getVersion() + " of " + type.getSimpleName());
|
||||||
|
}
|
||||||
|
VersionedConfig converted = converter.convert(config);
|
||||||
|
if (converted.getVersion() <= config.getVersion()) {
|
||||||
|
throw new IllegalStateException("Version did not increase after conversion of version " + config.getVersion() + " of " + type.getSimpleName());
|
||||||
|
}
|
||||||
|
config = converted;
|
||||||
|
}
|
||||||
|
if (!type.isInstance(config)) {
|
||||||
|
throw new IllegalStateException("Version " + config.getVersion() + " is not the current version of " + type.getSimpleName());
|
||||||
|
}
|
||||||
|
return type.cast(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the config stored in the file, or the default config if the file is missing or empty
|
||||||
|
* @throws RuntimeException if the config could not be read or converted
|
||||||
|
*/
|
||||||
|
public T load(File file) throws IOException {
|
||||||
|
if (file.length() == 0) {
|
||||||
|
return defaultConfig.get();
|
||||||
|
}
|
||||||
|
return read(Files.readString(file.toPath(), StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(File file, T config) throws IOException {
|
||||||
|
Files.writeString(file.toPath(), write(config), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the config of a player, loads it from the {@link UserConfig} and converts it if necessary.
|
||||||
|
*/
|
||||||
|
public T get(Player player) {
|
||||||
|
requireUserConfig();
|
||||||
|
return playerConfigs.computeIfAbsent(player.getUniqueId(), this::loadPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the config of a player, this does not unload the config.
|
||||||
|
*/
|
||||||
|
public void save(Player player) {
|
||||||
|
requireUserConfig();
|
||||||
|
T config = playerConfigs.get(player.getUniqueId());
|
||||||
|
if (config != null) {
|
||||||
|
savePlayer(player.getUniqueId(), config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save and unload the config of a player.
|
||||||
|
*/
|
||||||
|
public void unload(Player player) {
|
||||||
|
if (userConfigKey == null) return;
|
||||||
|
T config = playerConfigs.remove(player.getUniqueId());
|
||||||
|
if (config != null) {
|
||||||
|
savePlayer(player.getUniqueId(), config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T loadPlayer(UUID uuid) {
|
||||||
|
String stored = UserConfig.getConfig(uuid, userConfigKey);
|
||||||
|
if (stored == null) {
|
||||||
|
return defaultConfig.get();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return read(stored);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, "Could not load " + type.getSimpleName() + " of " + uuid, e);
|
||||||
|
return defaultConfig.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void savePlayer(UUID uuid, T config) {
|
||||||
|
if (removeIf.test(config)) {
|
||||||
|
UserConfig.removePlayerConfig(uuid, userConfigKey);
|
||||||
|
} else {
|
||||||
|
UserConfig.updatePlayerConfig(uuid, userConfigKey, write(config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requireUserConfig() {
|
||||||
|
if (userConfigKey == null) {
|
||||||
|
throw new IllegalStateException(type.getSimpleName() + " is not stored in the UserConfig");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the config of the file of this store, loads it and converts it if necessary.
|
||||||
|
*/
|
||||||
|
public T get() {
|
||||||
|
requireFile();
|
||||||
|
if (fileConfig == null) {
|
||||||
|
fileConfig = loadFile();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
return fileConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the config to the file of this store, if it was loaded.
|
||||||
|
*/
|
||||||
|
public void save() {
|
||||||
|
requireFile();
|
||||||
|
if (fileConfig == null) return;
|
||||||
|
try {
|
||||||
|
save(file, fileConfig);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, "Could not write " + file, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T loadFile() {
|
||||||
|
try {
|
||||||
|
if (file.length() != 0) {
|
||||||
|
return load(file);
|
||||||
|
}
|
||||||
|
if (legacyFile != null && legacyFile.length() != 0) {
|
||||||
|
return update(legacyFileReader.apply(Files.readString(legacyFile.toPath(), StandardCharsets.UTF_8)));
|
||||||
|
}
|
||||||
|
return defaultConfig.get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, "Could not load " + file + ", using default " + type.getSimpleName(), e);
|
||||||
|
backupBrokenFile();
|
||||||
|
return defaultConfig.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backupBrokenFile() {
|
||||||
|
if (file.length() == 0) return;
|
||||||
|
try {
|
||||||
|
Files.copy(file.toPath(), new File(file.getParentFile(), file.getName() + ".broken").toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, "Could not backup broken " + file, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requireFile() {
|
||||||
|
if (file == null) {
|
||||||
|
throw new IllegalStateException(type.getSimpleName() + " is not bound to a file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unloadAll(Player player) {
|
||||||
|
STORES.forEach(store -> store.unload(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves every loaded config and unloads the configs of the players.
|
||||||
|
*/
|
||||||
|
public static void saveAll() {
|
||||||
|
for (ConfigStore<?> store : STORES) {
|
||||||
|
if (store.userConfigKey != null) {
|
||||||
|
store.playerConfigs.forEach((uuid, config) -> saveUnchecked(store, uuid, config));
|
||||||
|
store.playerConfigs.clear();
|
||||||
|
}
|
||||||
|
if (store.file != null) {
|
||||||
|
store.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T extends VersionedConfig> void saveUnchecked(ConfigStore<T> store, UUID uuid, Object config) {
|
||||||
|
store.savePlayer(uuid, (T) config);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.config;
|
||||||
|
|
||||||
|
import de.steamwar.core.CRIUSleepEvent;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves and unloads the configs of the {@link ConfigStore}s bound to the UserConfig
|
||||||
|
* when a player quits, configs are loaded on first use.
|
||||||
|
*/
|
||||||
|
@Linked
|
||||||
|
public class ConfigStoreListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
ConfigStore.unloadAll(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onCRIUSleep(CRIUSleepEvent event) {
|
||||||
|
ConfigStore.saveAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-10
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of the SteamWar software.
|
* This file is a part of the SteamWar software.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@@ -17,15 +17,13 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.steamwar.linkage;
|
package de.steamwar.bausystem.config;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
/**
|
||||||
import java.lang.annotation.Retention;
|
* Common interface of every version of a config stored by a {@link ConfigStore},
|
||||||
import java.lang.annotation.RetentionPolicy;
|
* the current version (e.g. Config) and every older version (ConfigV1, ConfigV2, ...).
|
||||||
import java.lang.annotation.Target;
|
*/
|
||||||
|
public interface VersionedConfig {
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
int getVersion();
|
||||||
@Target({ElementType.TYPE})
|
|
||||||
public @interface MinVersion {
|
|
||||||
int value();
|
|
||||||
}
|
}
|
||||||
+95
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.config.legacy;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes {@link ItemStack}s that were serialized by YAPION, read with {@link YapionReader}.
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
@Deprecated
|
||||||
|
public class YapionItemDeserializer {
|
||||||
|
|
||||||
|
private static final String TYPE_IDENTIFIER = "@type";
|
||||||
|
|
||||||
|
public ItemStack deserializeItem(Object yapion) {
|
||||||
|
if (yapion == null) return null;
|
||||||
|
Object result = deserialize(yapion);
|
||||||
|
if (result instanceof ItemStack itemStack) return itemStack;
|
||||||
|
throw new IllegalArgumentException("Not an ItemStack: " + result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object deserialize(Object yapion) {
|
||||||
|
if (yapion instanceof List<?> list) {
|
||||||
|
List<Object> result = new ArrayList<>();
|
||||||
|
list.forEach(o -> result.add(deserialize(o)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (yapion instanceof YapionReader.YapionMap map) {
|
||||||
|
Map<Object, Object> result = new LinkedHashMap<>();
|
||||||
|
map.entries().forEach((key, value) -> result.put(deserialize(key), deserialize(value)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (yapion instanceof Map<?, ?> object) {
|
||||||
|
return deserializeObject(object);
|
||||||
|
}
|
||||||
|
return yapion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object deserializeObject(Map<?, ?> object) {
|
||||||
|
Map<String, Object> data = new LinkedHashMap<>();
|
||||||
|
object.forEach((key, value) -> {
|
||||||
|
if (!TYPE_IDENTIFIER.equals(key)) data.put((String) key, deserialize(value));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!(object.get(TYPE_IDENTIFIER) instanceof String type)) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> javaType = javaUtilClass(type);
|
||||||
|
if (javaType != null && Collection.class.isAssignableFrom(javaType)) {
|
||||||
|
return data.getOrDefault("values", new ArrayList<>());
|
||||||
|
}
|
||||||
|
if (javaType != null && Map.class.isAssignableFrom(javaType)) {
|
||||||
|
return data.containsKey("values") ? data.get("values") : data;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, type.equals("org.bukkit.inventory.meta.ItemMeta") ? "ItemMeta" : type);
|
||||||
|
return ConfigurationSerialization.deserializeObject(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<?> javaUtilClass(String type) {
|
||||||
|
if (!type.startsWith("java.util.")) return null;
|
||||||
|
try {
|
||||||
|
return Class.forName(type);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.config.legacy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal reader for the legacy YAPION format, only used to migrate old data.
|
||||||
|
* <p>
|
||||||
|
* The result is built from plain java objects:
|
||||||
|
* <ul>
|
||||||
|
* <li>YAPION objects {@code {key(value)}} become a {@link LinkedHashMap} of String to value</li>
|
||||||
|
* <li>YAPION arrays {@code [a,b]} become a {@link List}</li>
|
||||||
|
* <li>YAPION maps {@code <(a):(b)>} become a {@link YapionMap}</li>
|
||||||
|
* <li>YAPION values {@code (value)} become null, Boolean, Number or String</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class YapionReader {
|
||||||
|
|
||||||
|
private static final Pattern INTEGER = Pattern.compile("[-+]?\\d+");
|
||||||
|
private static final Pattern DECIMAL = Pattern.compile("[-+]?(\\d+\\.\\d*|\\.\\d+|\\d+)([eE][-+]?\\d+)?");
|
||||||
|
|
||||||
|
public record YapionMap(Map<Object, Object> entries) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> parse(String yapion) {
|
||||||
|
YapionReader reader = new YapionReader(yapion);
|
||||||
|
reader.skipWhitespace();
|
||||||
|
Map<String, Object> result = reader.readObject();
|
||||||
|
reader.skipWhitespace();
|
||||||
|
if (reader.index != yapion.length()) {
|
||||||
|
throw reader.error("Unexpected trailing content");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getDouble(Map<?, ?> object, String key, double defaultValue) {
|
||||||
|
return object.get(key) instanceof Number value ? value.doubleValue() : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getInt(Map<?, ?> object, String key, int defaultValue) {
|
||||||
|
return object.get(key) instanceof Number value ? value.intValue() : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getBoolean(Map<?, ?> object, String key, boolean defaultValue) {
|
||||||
|
return object.get(key) instanceof Boolean value ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getString(Map<?, ?> object, String key, String defaultValue) {
|
||||||
|
return object.get(key) instanceof String value ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the entries of the array that are YAPION objects
|
||||||
|
*/
|
||||||
|
public static List<Map<?, ?>> getObjects(Map<?, ?> object, String key) {
|
||||||
|
List<Map<?, ?>> objects = new ArrayList<>();
|
||||||
|
if (object.get(key) instanceof List<?> array) {
|
||||||
|
array.forEach(o -> {
|
||||||
|
if (o instanceof Map<?, ?> map) objects.add(map);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String input;
|
||||||
|
private int index = 0;
|
||||||
|
|
||||||
|
private YapionReader(String input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object readAny() {
|
||||||
|
return switch (peek()) {
|
||||||
|
case '{' -> readObject();
|
||||||
|
case '[' -> readArray();
|
||||||
|
case '<' -> readMap();
|
||||||
|
case '(' -> readValue();
|
||||||
|
default -> throw error("Expected '{', '[', '<' or '('");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> readObject() {
|
||||||
|
expect('{');
|
||||||
|
Map<String, Object> object = new LinkedHashMap<>();
|
||||||
|
while (true) {
|
||||||
|
skipWhitespace();
|
||||||
|
if (peek() == '}') {
|
||||||
|
index++;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
StringBuilder key = new StringBuilder();
|
||||||
|
while (true) {
|
||||||
|
char c = peek();
|
||||||
|
if (c == '(' || c == '{' || c == '[' || c == '<') break;
|
||||||
|
if (c == '}') throw error("Key without value");
|
||||||
|
key.append(readChar());
|
||||||
|
}
|
||||||
|
object.put(key.toString(), readAny());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Object> readArray() {
|
||||||
|
expect('[');
|
||||||
|
List<Object> array = new ArrayList<>();
|
||||||
|
skipWhitespace();
|
||||||
|
if (peek() == ']') {
|
||||||
|
index++;
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
int start = index;
|
||||||
|
skipWhitespace();
|
||||||
|
char c = peek();
|
||||||
|
if (c == '{' || c == '[' || c == '<' || c == '(') {
|
||||||
|
array.add(readAny());
|
||||||
|
skipWhitespace();
|
||||||
|
} else {
|
||||||
|
// Whitespace is part of plain values
|
||||||
|
index = start;
|
||||||
|
StringBuilder value = new StringBuilder();
|
||||||
|
while (peek() != ',' && peek() != ']') {
|
||||||
|
value.append(readChar());
|
||||||
|
}
|
||||||
|
array.add(typed(value.toString()));
|
||||||
|
}
|
||||||
|
char separator = input.charAt(index++);
|
||||||
|
if (separator == ']') return array;
|
||||||
|
if (separator != ',') throw error("Expected ',' or ']'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private YapionMap readMap() {
|
||||||
|
expect('<');
|
||||||
|
Map<Object, Object> map = new LinkedHashMap<>();
|
||||||
|
while (true) {
|
||||||
|
skipWhitespace();
|
||||||
|
if (peek() == '>') {
|
||||||
|
index++;
|
||||||
|
return new YapionMap(map);
|
||||||
|
}
|
||||||
|
Object key = readAny();
|
||||||
|
skipWhitespace();
|
||||||
|
expect(':');
|
||||||
|
skipWhitespace();
|
||||||
|
map.put(key, readAny());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YAPION does not escape parentheses in values, balanced parentheses are part of the value.
|
||||||
|
* A backslash only escapes a backslash, a unicode sequence or a control character, otherwise it is kept.
|
||||||
|
*/
|
||||||
|
private Object readValue() {
|
||||||
|
expect('(');
|
||||||
|
StringBuilder value = new StringBuilder();
|
||||||
|
int depth = 0;
|
||||||
|
while (true) {
|
||||||
|
char c = peek();
|
||||||
|
if (c == '\\') {
|
||||||
|
value.append(readValueEscape());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
if (c == '(') {
|
||||||
|
depth++;
|
||||||
|
} else if (c == ')') {
|
||||||
|
if (depth == 0) break;
|
||||||
|
depth--;
|
||||||
|
}
|
||||||
|
value.append(c);
|
||||||
|
}
|
||||||
|
return typed(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readValueEscape() {
|
||||||
|
index++;
|
||||||
|
if (index >= input.length()) return "\\";
|
||||||
|
char escaped = input.charAt(index);
|
||||||
|
switch (escaped) {
|
||||||
|
case '\\', '(', ')':
|
||||||
|
index++;
|
||||||
|
return String.valueOf(escaped);
|
||||||
|
case 'n':
|
||||||
|
index++;
|
||||||
|
return "\n";
|
||||||
|
case 't':
|
||||||
|
index++;
|
||||||
|
return "\t";
|
||||||
|
case 'r':
|
||||||
|
index++;
|
||||||
|
return "\r";
|
||||||
|
case 'u':
|
||||||
|
if (index + 5 <= input.length() && input.substring(index + 1, index + 5).matches("[0-9a-fA-F]{4}")) {
|
||||||
|
char unicode = (char) Integer.parseInt(input.substring(index + 1, index + 5), 16);
|
||||||
|
index += 5;
|
||||||
|
return String.valueOf(unicode);
|
||||||
|
}
|
||||||
|
return "\\";
|
||||||
|
default:
|
||||||
|
return "\\";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads one character of a key or plain array value, resolving backslash escapes.
|
||||||
|
* A backslash that does not escape anything is kept, as the old player config
|
||||||
|
* collapsed escaped backslashes into a single one.
|
||||||
|
*/
|
||||||
|
private char readChar() {
|
||||||
|
char c = input.charAt(index++);
|
||||||
|
if (c != '\\') return c;
|
||||||
|
if (index >= input.length()) throw error("Unterminated escape");
|
||||||
|
char escaped = input.charAt(index);
|
||||||
|
switch (escaped) {
|
||||||
|
case 'n':
|
||||||
|
index++;
|
||||||
|
return '\n';
|
||||||
|
case 't':
|
||||||
|
index++;
|
||||||
|
return '\t';
|
||||||
|
case 'r':
|
||||||
|
index++;
|
||||||
|
return '\r';
|
||||||
|
case 'u':
|
||||||
|
if (index + 5 <= input.length() && input.substring(index + 1, index + 5).matches("[0-9a-fA-F]{4}")) {
|
||||||
|
char unicode = (char) Integer.parseInt(input.substring(index + 1, index + 5), 16);
|
||||||
|
index += 5;
|
||||||
|
return unicode;
|
||||||
|
}
|
||||||
|
return '\\';
|
||||||
|
case '\\', ',', ' ', '(', ')', '{', '}', '[', ']', '<', '>', '"', ':', '@':
|
||||||
|
index++;
|
||||||
|
return escaped;
|
||||||
|
default:
|
||||||
|
return '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object typed(String value) {
|
||||||
|
if (value.equals("null")) return null;
|
||||||
|
if (value.equals("true")) return true;
|
||||||
|
if (value.equals("false")) return false;
|
||||||
|
if (value.length() >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
|
||||||
|
return value.substring(1, value.length() - 1);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (INTEGER.matcher(value).matches()) {
|
||||||
|
long l = Long.parseLong(value);
|
||||||
|
if (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE) return (int) l;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
if (value.length() > 1) {
|
||||||
|
String number = value.substring(0, value.length() - 1);
|
||||||
|
switch (value.charAt(value.length() - 1)) {
|
||||||
|
case 'L':
|
||||||
|
if (INTEGER.matcher(number).matches()) return Long.parseLong(number);
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
if (INTEGER.matcher(number).matches()) return Short.parseShort(number);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
if (INTEGER.matcher(number).matches()) return Byte.parseByte(number);
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
if (DECIMAL.matcher(number).matches()) return Float.parseFloat(number);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
if (DECIMAL.matcher(number).matches()) return Double.parseDouble(number);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DECIMAL.matcher(value).matches()) return Double.parseDouble(value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Not a number, fall through to String
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipWhitespace() {
|
||||||
|
while (index < input.length() && Character.isWhitespace(input.charAt(index))) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private char peek() {
|
||||||
|
if (index >= input.length()) throw error("Unexpected end of input");
|
||||||
|
return input.charAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expect(char c) {
|
||||||
|
if (peek() != c) throw error("Expected '" + c + "'");
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IllegalArgumentException error(String message) {
|
||||||
|
return new IllegalArgumentException(message + " at index " + index);
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.config.serializer;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores an {@link ItemStack} as Base64 of {@link ItemStack#serializeAsBytes()}, which
|
||||||
|
* contains the data version and gets upgraded on newer Minecraft versions.
|
||||||
|
* Empty items are stored as null, items that can't be read are deserialized as null.
|
||||||
|
*/
|
||||||
|
public class ItemStackTypeAdapter extends TypeAdapter<ItemStack> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, ItemStack itemStack) throws IOException {
|
||||||
|
if (itemStack == null || itemStack.isEmpty()) {
|
||||||
|
out.nullValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.value(Base64.getEncoder().encodeToString(itemStack.serializeAsBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack read(JsonReader in) throws IOException {
|
||||||
|
if (in.peek() == JsonToken.NULL) {
|
||||||
|
in.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String value = in.nextString();
|
||||||
|
try {
|
||||||
|
return ItemStack.deserializeBytes(Base64.getDecoder().decode(value));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Bukkit.getLogger().log(Level.WARNING, "Could not deserialize ItemStack", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of the SteamWar software.
|
* This file is a part of the SteamWar software.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@@ -19,129 +19,77 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.configplayer;
|
package de.steamwar.bausystem.configplayer;
|
||||||
|
|
||||||
import de.steamwar.bausystem.configplayer.serializer.ConfigurationSerializableSerializer;
|
import com.google.gson.GsonBuilder;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.bausystem.config.ConfigConverter;
|
||||||
import de.steamwar.sql.UserConfig;
|
import de.steamwar.bausystem.config.ConfigStore;
|
||||||
|
import de.steamwar.bausystem.config.VersionedConfig;
|
||||||
|
import de.steamwar.bausystem.config.serializer.ItemStackTypeAdapter;
|
||||||
|
import de.steamwar.bausystem.configplayer.converter.ConfigV1ToV2Converter;
|
||||||
|
import de.steamwar.bausystem.features.hotbar.DefaultHotbar;
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import lombok.Setter;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import yapion.hierarchy.output.StringOutput;
|
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
import yapion.parser.YAPIONParser;
|
|
||||||
import yapion.serializing.SerializeManager;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
@Linked
|
/**
|
||||||
public class Config implements Listener {
|
* The current player config. It is stored as JSON, fields missing in the
|
||||||
|
* stored JSON keep the default value of their initializer, so adding a new
|
||||||
|
* field does not need a new version.
|
||||||
|
* <p>
|
||||||
|
* When a field gets removed, renamed or its meaning changes, copy this class
|
||||||
|
* to ConfigV{@link #VERSION} (without the {@link #STORE}), increase {@link #VERSION},
|
||||||
|
* write a {@link ConfigConverter} from the copy to this class and register it in the {@link #STORE}.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Config implements VersionedConfig {
|
||||||
|
|
||||||
static {
|
public static final int VERSION = 2;
|
||||||
SerializeManager.add(new ConfigurationSerializableSerializer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
public static final ConfigStore<Config> STORE = new ConfigStore<>(Config.class, VERSION, Config::new)
|
||||||
private static Config instance;
|
.gson(new GsonBuilder().registerTypeHierarchyAdapter(ItemStack.class, new ItemStackTypeAdapter()).create())
|
||||||
|
.legacy(s -> s.startsWith("{@version(1)"), ConfigV1::parse)
|
||||||
|
.converter(new ConfigV1ToV2Converter())
|
||||||
|
.userConfig("bausystem");
|
||||||
|
|
||||||
{
|
@Setter(AccessLevel.NONE)
|
||||||
instance = this;
|
protected int version = VERSION;
|
||||||
}
|
|
||||||
|
|
||||||
private final Map<UUID, YAPIONObject> playerConfigurations = new HashMap<>();
|
|
||||||
|
|
||||||
private static final Map<Integer, ConfigConverter> CONFIG_CONVERTER_MAP = new HashMap<>();
|
|
||||||
|
|
||||||
public static void addConfigConverter(ConfigConverter configConverter) {
|
|
||||||
CONFIG_CONVERTER_MAP.putIfAbsent(configConverter.version(), configConverter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
|
||||||
get(event.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
|
||||||
save(event.getPlayer());
|
|
||||||
playerConfigurations.remove(event.getPlayer().getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a PlayerConfig, optionally loads it from the DataBase and migrates it if necessary.
|
* BauGui item id to inventory slot
|
||||||
*
|
|
||||||
* @param player the player from whom to get the config.
|
|
||||||
* @return the config object
|
|
||||||
*/
|
*/
|
||||||
public YAPIONObject get(Player player) {
|
protected Map<Integer, Integer> bauGui = defaultBauGui();
|
||||||
UUID uuid = player.getUniqueId();
|
protected int bauGuiSize = 45;
|
||||||
if (!playerConfigurations.containsKey(uuid)) {
|
|
||||||
String s = UserConfig.getConfig(uuid, "bausystem");
|
|
||||||
YAPIONObject yapionObject;
|
|
||||||
if (s == null) {
|
|
||||||
yapionObject = ConfigCreator.createDefaultConfig();
|
|
||||||
} else {
|
|
||||||
yapionObject = YAPIONParser.parse(s);
|
|
||||||
}
|
|
||||||
yapionObject = update(yapionObject);
|
|
||||||
playerConfigurations.put(uuid, yapionObject);
|
|
||||||
return yapionObject;
|
|
||||||
}
|
|
||||||
return playerConfigurations.get(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveAll() {
|
|
||||||
playerConfigurations.forEach((uuid, yapionObject) -> {
|
|
||||||
String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\+", "\\");
|
|
||||||
UserConfig.updatePlayerConfig(uuid, "bausystem", string);
|
|
||||||
});
|
|
||||||
playerConfigurations.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a PlayerConfig, this does not remove the key value mapping from the map.
|
* Slots 0-8 are the hotbar, slots 9-12 the armor contents
|
||||||
*
|
|
||||||
* @param player the player to save the config.
|
|
||||||
*/
|
*/
|
||||||
public void save(Player player) {
|
protected ItemStack[] hotbar = DefaultHotbar.defaultHotbar();
|
||||||
UUID uuid = player.getUniqueId();
|
|
||||||
if (playerConfigurations.containsKey(uuid)) {
|
|
||||||
YAPIONObject yapionObject = playerConfigurations.get(uuid);
|
|
||||||
String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\\\+", "\\\\");
|
|
||||||
UserConfig.updatePlayerConfig(uuid, "bausystem", string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private YAPIONObject update(YAPIONObject yapionObject) {
|
protected boolean nightVision = false;
|
||||||
int version = yapionObject.getPlainValue("@version");
|
protected boolean tntClickDetails = true;
|
||||||
while (version < ConfigCreator.currentVersion) {
|
protected boolean detonatorAutostart = false;
|
||||||
ConfigConverter configConverter = CONFIG_CONVERTER_MAP.getOrDefault(version, null);
|
protected boolean inventoryFill = false;
|
||||||
if (configConverter == null) {
|
protected boolean rayVisualizer = false;
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "No updater found for version " + version);
|
protected boolean smartPlace = false;
|
||||||
return ConfigCreator.createDefaultConfig();
|
protected boolean blockCounter = false;
|
||||||
}
|
protected boolean depthMessage = true;
|
||||||
try {
|
|
||||||
configConverter.update(yapionObject);
|
public static Map<Integer, Integer> defaultBauGui() {
|
||||||
} catch (Exception e) {
|
// 0: ? | 1: ? | 2: 10 | 3: 3 | 4: 7 | 5: 17 | 6: 15 | 7: ? | 8: ?
|
||||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
// 9: 5 | 10: ? | 11: ? | 12: ? | 13: ? | 14: ? | 15: ? | 16: ? | 17: 16
|
||||||
return ConfigCreator.createDefaultConfig();
|
// 18: 4 | 19: ? | 20: 19 | 21: 21 | 22: 9 | 23: 0 | 24: 1 | 25: ? | 26: 11
|
||||||
}
|
// 27: 6 | 28: ? | 29: ? | 30: ? | 31: ? | 32: ? | 33: ? | 34: ? | 35: 18
|
||||||
int newVersion = yapionObject.getPlainValue("@version");
|
// 36: ? | 37: 23 | 38: 20 | 39: 8 | 40: 22 | 41: 26 | 42: 12 | 43: 14 | 44: ?
|
||||||
if (version == newVersion) {
|
Map<Integer, Integer> bauGui = new HashMap<>();
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Version Tag was the same after conversion");
|
bauGui.put(10, 2); bauGui.put(3, 3); bauGui.put(7, 4); bauGui.put(17, 5); bauGui.put(15, 6);
|
||||||
return ConfigCreator.createDefaultConfig();
|
bauGui.put(5, 9); bauGui.put(4, 18); bauGui.put(6, 27);
|
||||||
}
|
bauGui.put(16, 17); bauGui.put(11, 26); bauGui.put(18, 35);
|
||||||
if (newVersion < version) {
|
bauGui.put(19, 20); bauGui.put(21, 21); bauGui.put(9, 22); bauGui.put(0, 23); bauGui.put(1, 24);
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Version Tag was earlier after conversion");
|
bauGui.put(23, 37); bauGui.put(20, 38); bauGui.put(8, 39); bauGui.put(22, 40); bauGui.put(26, 41); bauGui.put(12, 42); bauGui.put(14, 43);
|
||||||
return ConfigCreator.createDefaultConfig();
|
return bauGui;
|
||||||
}
|
|
||||||
version = newVersion;
|
|
||||||
}
|
|
||||||
return yapionObject;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.configplayer;
|
|
||||||
|
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A new {@link ConfigConverter} should be written when you remove anything
|
|
||||||
* from the Config or modify any mayor part. When you move anything from
|
|
||||||
* any key to any other key you should write a new {@link ConfigConverter}.
|
|
||||||
* For adding any new key you should be able to get the default without
|
|
||||||
* having it in the Config. Anything you need to change you should also
|
|
||||||
* change the {@link ConfigCreator} accordingly, to produce the new Config.
|
|
||||||
*/
|
|
||||||
public interface ConfigConverter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This describes the version this Converter can convert from. The version
|
|
||||||
* it should convert to is the version 1 above this number. But this is not
|
|
||||||
* a necessity. In the config Object as parameter given in {@link #update(YAPIONObject)}
|
|
||||||
* you should update the <b>@version</b> variable in the root object to the
|
|
||||||
* new version this converter produced.
|
|
||||||
*
|
|
||||||
* @return the version number
|
|
||||||
*/
|
|
||||||
int version();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should update everything needed to go from a lower config
|
|
||||||
* version to a higher. It should update the <b>@version</b> variable
|
|
||||||
* accordingly. Anything else is up the implementation. If anything goes wrong
|
|
||||||
* do not silently exit this method, throw an Exception. The updater Code will
|
|
||||||
* deal with it. Never leave the inputted object in a corrupted state.
|
|
||||||
*
|
|
||||||
* @param config the config object to update
|
|
||||||
*/
|
|
||||||
void update(YAPIONObject config);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.configplayer;
|
|
||||||
|
|
||||||
import de.steamwar.bausystem.features.hotbar.DefaultHotbar;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class ConfigCreator {
|
|
||||||
|
|
||||||
public static final int currentVersion = 1;
|
|
||||||
|
|
||||||
public YAPIONObject createDefaultConfig() {
|
|
||||||
YAPIONObject yapionObject = new YAPIONObject();
|
|
||||||
// This call should never be touched
|
|
||||||
yapionObject.add("@version", currentVersion);
|
|
||||||
|
|
||||||
// Any initialising goes into here
|
|
||||||
yapionObject.add("baugui", defaultBauGui());
|
|
||||||
|
|
||||||
// Default Hotbar Gui
|
|
||||||
yapionObject.add("hotbar", DefaultHotbar.defaultHotbar());
|
|
||||||
return yapionObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private YAPIONObject defaultBauGui() {
|
|
||||||
YAPIONObject yapionObject = new YAPIONObject();
|
|
||||||
|
|
||||||
// 0: ? | 1: ? | 2: 10 | 3: 3 | 4: 7 | 5: 17 | 6: 15 | 7: ? | 8: ?
|
|
||||||
// 9: 5 | 10: ? | 11: ? | 12: ? | 13: ? | 14: ? | 15: ? | 16: ? | 17: 16
|
|
||||||
// 18: 4 | 19: ? | 20: 19 | 21: 21 | 22: 9 | 23: 0 | 24: 1 | 25: ? | 26: 11
|
|
||||||
// 27: 6 | 28: ? | 29: ? | 30: ? | 31: ? | 32: ? | 33: ? | 34: ? | 35: 18
|
|
||||||
// 36: ? | 37: 23 | 38: 20 | 39: 8 | 40: 22 | 41: 26 | 42: 12 | 43: 14 | 44: ?
|
|
||||||
|
|
||||||
yapionObject.add("10", 2).add("3", 3).add("7", 4).add("17", 5).add("15", 6);
|
|
||||||
yapionObject.add("5", 9).add("4", 18).add("6", 27);
|
|
||||||
yapionObject.add("16", 17).add("11", 26).add("18", 35);
|
|
||||||
yapionObject.add("19", 20).add("21", 21).add("9", 22).add("0", 23).add("1", 24);
|
|
||||||
yapionObject.add("23", 37).add("20", 38).add("8", 39).add("22", 40).add("26", 41).add("12", 42).add("14", 43);
|
|
||||||
yapionObject.add("size", 45);
|
|
||||||
return yapionObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.configplayer;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.config.VersionedConfig;
|
||||||
|
import de.steamwar.bausystem.config.legacy.YapionReader;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The legacy config that was stored in the YAPION format.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ConfigV1 implements VersionedConfig {
|
||||||
|
|
||||||
|
public static final int VERSION = 1;
|
||||||
|
|
||||||
|
@Setter(AccessLevel.NONE)
|
||||||
|
protected int version = VERSION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BauGui item id to inventory slot
|
||||||
|
*/
|
||||||
|
protected Map<Integer, Integer> bauGui = new HashMap<>();
|
||||||
|
protected int bauGuiSize = 45;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minecraft version to the hotbar serialized by YAPION, read with {@link YapionReader}.
|
||||||
|
* Use {@link de.steamwar.bausystem.config.legacy.YapionItemDeserializer} to get the items.
|
||||||
|
*/
|
||||||
|
protected Map<Integer, List<?>> hotbars = new HashMap<>();
|
||||||
|
|
||||||
|
protected boolean nightVision = false;
|
||||||
|
protected boolean tntClickDetails = true;
|
||||||
|
protected boolean detonatorAutostart = false;
|
||||||
|
protected boolean inventoryFill = false;
|
||||||
|
protected boolean rayVisualizer = false;
|
||||||
|
protected boolean smartPlace = false;
|
||||||
|
protected boolean blockCounter = false;
|
||||||
|
protected boolean depthMessage = true;
|
||||||
|
|
||||||
|
public static ConfigV1 parse(String yapion) {
|
||||||
|
Map<String, Object> object = YapionReader.parse(yapion);
|
||||||
|
ConfigV1 config = new ConfigV1();
|
||||||
|
config.version = (Integer) object.get("@version");
|
||||||
|
|
||||||
|
if (object.get("baugui") instanceof Map<?, ?> bauGui) {
|
||||||
|
bauGui.forEach((key, value) -> {
|
||||||
|
if (key.equals("size")) {
|
||||||
|
config.bauGuiSize = (Integer) value;
|
||||||
|
} else {
|
||||||
|
config.bauGui.put(Integer.parseInt((String) key), (Integer) value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
object.forEach((key, value) -> {
|
||||||
|
if (!(value instanceof List<?> hotbar)) return;
|
||||||
|
if (key.equals("hotbar")) {
|
||||||
|
// Hotbars were stored without version prior to 1.19
|
||||||
|
config.hotbars.putIfAbsent(19, hotbar);
|
||||||
|
} else if (key.startsWith("hotbar-")) {
|
||||||
|
config.hotbars.put(Integer.parseInt(key.substring("hotbar-".length())), hotbar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
config.nightVision = getBoolean(object, "nightvision", config.nightVision);
|
||||||
|
config.tntClickDetails = getBoolean(object, "tnt_click_details", config.tntClickDetails);
|
||||||
|
config.detonatorAutostart = getBoolean(object, "detonator-autostart", config.detonatorAutostart);
|
||||||
|
config.inventoryFill = getBoolean(object, "inventoryfill", config.inventoryFill);
|
||||||
|
config.rayVisualizer = getBoolean(object, "rayvisualizer", config.rayVisualizer);
|
||||||
|
config.smartPlace = getBoolean(object, "smartPlace", config.smartPlace);
|
||||||
|
config.blockCounter = getBoolean(object, "blockCounter", config.blockCounter);
|
||||||
|
config.depthMessage = getBoolean(object, "depth_message", config.depthMessage);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean getBoolean(Map<String, Object> object, String key, boolean defaultValue) {
|
||||||
|
return object.get(key) instanceof Boolean value ? value : defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.configplayer.converter;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.config.ConfigConverter;
|
||||||
|
import de.steamwar.bausystem.config.legacy.YapionItemDeserializer;
|
||||||
|
import de.steamwar.bausystem.configplayer.Config;
|
||||||
|
import de.steamwar.bausystem.configplayer.ConfigV1;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public class ConfigV1ToV2Converter implements ConfigConverter<ConfigV1, Config> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int version() {
|
||||||
|
return ConfigV1.VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Config convert(ConfigV1 old) {
|
||||||
|
Config config = new Config();
|
||||||
|
config.setBauGui(new HashMap<>(old.getBauGui()));
|
||||||
|
config.setBauGuiSize(old.getBauGuiSize());
|
||||||
|
|
||||||
|
List<?> hotbar = old.getHotbars().get(Core.getVersion());
|
||||||
|
if (hotbar != null) {
|
||||||
|
config.setHotbar(convertHotbar(hotbar));
|
||||||
|
}
|
||||||
|
|
||||||
|
config.setNightVision(old.isNightVision());
|
||||||
|
config.setTntClickDetails(old.isTntClickDetails());
|
||||||
|
config.setDetonatorAutostart(old.isDetonatorAutostart());
|
||||||
|
config.setInventoryFill(old.isInventoryFill());
|
||||||
|
config.setRayVisualizer(old.isRayVisualizer());
|
||||||
|
config.setSmartPlace(old.isSmartPlace());
|
||||||
|
config.setBlockCounter(old.isBlockCounter());
|
||||||
|
config.setDepthMessage(old.isDepthMessage());
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack[] convertHotbar(List<?> hotbar) {
|
||||||
|
ItemStack[] items = new ItemStack[13];
|
||||||
|
for (int i = 0; i < Math.min(hotbar.size(), items.length); i++) {
|
||||||
|
try {
|
||||||
|
items[i] = YapionItemDeserializer.deserializeItem(hotbar.get(i));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Bukkit.getLogger().log(Level.WARNING, "Could not convert hotbar item " + i, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
-90
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.configplayer.serializer;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import yapion.hierarchy.api.groups.YAPIONAnyType;
|
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
import yapion.serializing.api.SerializerObject;
|
|
||||||
import yapion.serializing.data.DeserializeData;
|
|
||||||
import yapion.serializing.data.SerializeData;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static yapion.utils.IdentifierUtils.TYPE_IDENTIFIER;
|
|
||||||
|
|
||||||
public class ConfigurationSerializableSerializer extends SerializerObject<ConfigurationSerializable> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ConfigurationSerializable> type() {
|
|
||||||
return ConfigurationSerializable.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInterface() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public YAPIONObject serialize(SerializeData<ConfigurationSerializable> serializeData) {
|
|
||||||
YAPIONObject yapionObject = new YAPIONObject();
|
|
||||||
yapionObject.add(TYPE_IDENTIFIER, serializeData.object.getClass().getTypeName());
|
|
||||||
if (serializeData.object instanceof ItemStack) {
|
|
||||||
yapionObject.add(TYPE_IDENTIFIER, ItemStack.class.getTypeName());
|
|
||||||
}
|
|
||||||
if (serializeData.object instanceof ItemMeta) {
|
|
||||||
yapionObject.add(TYPE_IDENTIFIER, ItemMeta.class.getTypeName());
|
|
||||||
}
|
|
||||||
Map<String, Object> serializeDataMap = serializeData.object.serialize();
|
|
||||||
serializeDataMap.forEach((s, o) -> {
|
|
||||||
YAPIONAnyType yapionAnyType = serializeData.serialize(o);
|
|
||||||
if (yapionAnyType instanceof YAPIONObject) {
|
|
||||||
YAPIONObject object = (YAPIONObject) yapionAnyType;
|
|
||||||
if (object.containsKey(TYPE_IDENTIFIER) && object.getPlainValue(TYPE_IDENTIFIER).equals("com.google.common.collect.RegularImmutableList")) {
|
|
||||||
object.put(TYPE_IDENTIFIER, ArrayList.class.getTypeName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yapionObject.add(s, yapionAnyType);
|
|
||||||
});
|
|
||||||
return yapionObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigurationSerializable deserialize(DeserializeData<YAPIONObject> deserializeData) {
|
|
||||||
Map<String, Object> deserializeDataMap = new HashMap<>();
|
|
||||||
deserializeData.object.forEach((s, yapionAnyType) -> {
|
|
||||||
if (s.equals(TYPE_IDENTIFIER)) {
|
|
||||||
if (yapionAnyType.toString().equals("(org.bukkit.inventory.meta.ItemMeta)")) {
|
|
||||||
deserializeDataMap.put("==", "ItemMeta");
|
|
||||||
} else {
|
|
||||||
deserializeDataMap.put("==", deserializeData.deserialize(yapionAnyType));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
deserializeDataMap.put(s, deserializeData.deserialize(yapionAnyType));
|
|
||||||
});
|
|
||||||
return ConfigurationSerialization.deserializeObject(deserializeDataMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
-4
@@ -76,13 +76,21 @@ public class AttributesCopyCommand extends SWCommand {
|
|||||||
if (itemStack.getType() == Material.ZOMBIE_HEAD && block.getType() == Material.ZOMBIE_WALL_HEAD) return true;
|
if (itemStack.getType() == Material.ZOMBIE_HEAD && block.getType() == Material.ZOMBIE_WALL_HEAD) return true;
|
||||||
if (itemStack.getType() == Material.CREEPER_HEAD && block.getType() == Material.CREEPER_WALL_HEAD) return true;
|
if (itemStack.getType() == Material.CREEPER_HEAD && block.getType() == Material.CREEPER_WALL_HEAD) return true;
|
||||||
if (itemStack.getType() == Material.DRAGON_HEAD && block.getType() == Material.DRAGON_WALL_HEAD) return true;
|
if (itemStack.getType() == Material.DRAGON_HEAD && block.getType() == Material.DRAGON_WALL_HEAD) return true;
|
||||||
if (itemStack.getType() == Material.SKELETON_SKULL && block.getType() == Material.SKELETON_WALL_SKULL) return true;
|
if (itemStack.getType() == Material.SKELETON_SKULL && block.getType() == Material.SKELETON_WALL_SKULL) {
|
||||||
if (itemStack.getType() == Material.WITHER_SKELETON_SKULL && block.getType() == Material.WITHER_SKELETON_WALL_SKULL) return true;
|
return true;
|
||||||
|
}
|
||||||
|
if (itemStack.getType() == Material.WITHER_SKELETON_SKULL && block.getType() == Material.WITHER_SKELETON_WALL_SKULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (itemStack.getType() == Material.TORCH && block.getType() == Material.WALL_TORCH) return true;
|
if (itemStack.getType() == Material.TORCH && block.getType() == Material.WALL_TORCH) return true;
|
||||||
if (itemStack.getType() == Material.SOUL_TORCH && block.getType() == Material.SOUL_WALL_TORCH) return true;
|
if (itemStack.getType() == Material.SOUL_TORCH && block.getType() == Material.SOUL_WALL_TORCH) return true;
|
||||||
if (itemStack.getType() == Material.REDSTONE_TORCH && block.getType() == Material.REDSTONE_WALL_TORCH) return true;
|
if (itemStack.getType() == Material.REDSTONE_TORCH && block.getType() == Material.REDSTONE_WALL_TORCH) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (itemStack.getType() == Material.WHEAT_SEEDS && block.getType() == Material.WHEAT) return true;
|
if (itemStack.getType() == Material.WHEAT_SEEDS && block.getType() == Material.WHEAT) return true;
|
||||||
if (itemStack.getType().name().contains("_BANNER") && block.getType().name().contains("_WALL_BANNER")) return true;
|
if (itemStack.getType().name().contains("_BANNER") && block.getType().name().contains("_WALL_BANNER")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ public class AttributesPlaceListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockPlace(BlockPlaceEvent event) {
|
public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
ItemStack itemStack = event.getItemInHand();
|
ItemStack itemStack = event.getItemInHand();
|
||||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
if (itemMeta == null) return;
|
if (itemMeta == null) return;
|
||||||
|
|||||||
+2
-2
@@ -65,7 +65,7 @@ public class AutostartListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
if (!ItemUtils.isItem(event.getItem(), "autostart")) {
|
if (!ItemUtils.isItem(event.getItem(), "autostart")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ public class AutostartListener implements Listener {
|
|||||||
if (!(event.getPlayer() instanceof Player)) {
|
if (!(event.getPlayer() instanceof Player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!Permission.BUILD.hasPermission((Player) event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission((Player) event.getPlayer())) return;
|
||||||
if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) {
|
if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -104,7 +104,8 @@ public class BackupCommand extends SWCommand {
|
|||||||
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("BACKUP_LORE", p));
|
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("BACKUP_LORE", p));
|
||||||
for (int i = 0; i < backups.size(); i++) {
|
for (int i = 0; i < backups.size(); i++) {
|
||||||
RegionBackups.Backup backup = backups.get(i);
|
RegionBackups.Backup backup = backups.get(i);
|
||||||
SWItem swItem = new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("BACKUP_ITEM_NAME", p, backup.getName()), lore, false, clickType -> {});
|
SWItem swItem = new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("BACKUP_ITEM_NAME", p, backup.getName()), lore, false, clickType -> {
|
||||||
|
});
|
||||||
swItem.getItemStack().setAmount(i + 1);
|
swItem.getItemStack().setAmount(i + 1);
|
||||||
swListEntries.add(new SWListInv.SWListEntry<>(swItem, backup));
|
swListEntries.add(new SWListInv.SWListEntry<>(swItem, backup));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class Depth {
|
|||||||
dimensions.setZ(Math.abs(dimensions.getZ()));
|
dimensions.setZ(Math.abs(dimensions.getZ()));
|
||||||
|
|
||||||
RegionUtils.message(region, player -> {
|
RegionUtils.message(region, player -> {
|
||||||
if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
|
if (Config.STORE.get(player).isDepthMessage()) {
|
||||||
player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount));
|
player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+3
-3
@@ -34,11 +34,11 @@ public class DepthCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void toggle(Player player) {
|
public void toggle(Player player) {
|
||||||
if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
|
if (Config.STORE.get(player).isDepthMessage()) {
|
||||||
Config.getInstance().get(player).put("depth_message", false);
|
Config.STORE.get(player).setDepthMessage(false);
|
||||||
BauSystem.MESSAGE.send("DEPTH_COUNTER_DISABLE", player);
|
BauSystem.MESSAGE.send("DEPTH_COUNTER_DISABLE", player);
|
||||||
} else {
|
} else {
|
||||||
Config.getInstance().get(player).put("depth_message", true);
|
Config.STORE.get(player).setDepthMessage(true);
|
||||||
BauSystem.MESSAGE.send("DEPTH_COUNTER_ENABLE", player);
|
BauSystem.MESSAGE.send("DEPTH_COUNTER_ENABLE", player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-10
@@ -21,9 +21,7 @@ package de.steamwar.bausystem.features.design.endstone;
|
|||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.*;
|
||||||
import de.steamwar.entity.REntityServer;
|
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -59,15 +57,15 @@ public class DesignEndStone {
|
|||||||
.filter(material -> material.getBlastResistance() > region.getGameModeConfig().Schematic.MaxDesignBlastResistance)
|
.filter(material -> material.getBlastResistance() > region.getGameModeConfig().Schematic.MaxDesignBlastResistance)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
calculateFromBottom = region.getGameModeConfig().Arena.NoFloor;
|
calculateFromBottom = region.getGameModeConfig().Arena.NoFloor;
|
||||||
|
}
|
||||||
|
|
||||||
entityServer.setCallback((player, rEntity, entityAction) -> {
|
private void interact(Player player, RInteraction entity, REntityAction action) {
|
||||||
if (entityAction != REntityServer.EntityAction.ATTACK) return;
|
if (action != REntityAction.ATTACK) return;
|
||||||
Location location = new Location(WORLD, rEntity.getX(), rEntity.getY(), rEntity.getZ());
|
Location location = new Location(WORLD, entity.getX(), entity.getY(), entity.getZ());
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
location.getBlock().breakNaturally();
|
location.getBlock().breakNaturally();
|
||||||
calc();
|
calc();
|
||||||
}, 1);
|
}, 1);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void calc() {
|
public void calc() {
|
||||||
@@ -110,12 +108,15 @@ public class DesignEndStone {
|
|||||||
Material material = WORLD.getBlockAt(cx, cy, cz).getType();
|
Material material = WORLD.getBlockAt(cx, cy, cz).getType();
|
||||||
|
|
||||||
if (material != Material.WATER && material != Material.LAVA && limited.contains(material)) {
|
if (material != Material.WATER && material != Material.LAVA && limited.contains(material)) {
|
||||||
Location location = new Location(WORLD, cx + 0.5, cy, cz + 0.5);
|
Location location = new Location(WORLD, cx, cy, cz);
|
||||||
if (!locations.add(location)) break;
|
if (!locations.add(location)) break;
|
||||||
RFallingBlockEntity entity = new RFallingBlockEntity(entityServer, location, Material.RED_STAINED_GLASS);
|
RBlockDisplay entity = new RBlockDisplay(entityServer, location);
|
||||||
entity.setNoGravity(true);
|
entity.setBlock(Material.RED_STAINED_GLASS.createBlockData());
|
||||||
entity.setGlowing(true);
|
entity.setGlowing(true);
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
|
RInteraction interaction = new RInteraction(entityServer, location);
|
||||||
|
interaction.setCallback(this::interact);
|
||||||
|
entities.add(interaction);
|
||||||
break;
|
break;
|
||||||
} else if (!material.isAir() && material != Material.WATER && material != Material.LAVA) {
|
} else if (!material.isAir() && material != Material.WATER && material != Material.LAVA) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
+11
-10
@@ -26,8 +26,9 @@ import de.steamwar.bausystem.features.autostart.AutostartListener;
|
|||||||
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
|
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
|
||||||
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
|
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
|
||||||
import de.steamwar.core.SWPlayer;
|
import de.steamwar.core.SWPlayer;
|
||||||
|
import de.steamwar.entity.RBlockDisplay;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
import de.steamwar.entity.RInteraction;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
@@ -58,10 +59,6 @@ public class Detonator {
|
|||||||
@Override
|
@Override
|
||||||
public void onMount(SWPlayer player) {
|
public void onMount(SWPlayer player) {
|
||||||
entities.addPlayer(player.getPlayer());
|
entities.addPlayer(player.getPlayer());
|
||||||
entities.setCallback((player1, entity, action) -> {
|
|
||||||
Vector vector = new Vector(entity.getX(), entity.getY(), entity.getZ());
|
|
||||||
DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,8 +67,6 @@ public class Detonator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Vector HALF = new Vector(0.5, 0, 0.5);
|
|
||||||
|
|
||||||
public static boolean isDetonator(ItemStack itemStack) {
|
public static boolean isDetonator(ItemStack itemStack) {
|
||||||
return ItemStorage.isDetonator(itemStack);
|
return ItemStorage.isDetonator(itemStack);
|
||||||
}
|
}
|
||||||
@@ -79,8 +74,14 @@ public class Detonator {
|
|||||||
public static void showDetonator(Player p, List<Location> locs) {
|
public static void showDetonator(Player p, List<Location> locs) {
|
||||||
DetonatorComponent detonatorComponent = SWPlayer.of(p).getComponentOrDefault(DetonatorComponent.class, DetonatorComponent::new);
|
DetonatorComponent detonatorComponent = SWPlayer.of(p).getComponentOrDefault(DetonatorComponent.class, DetonatorComponent::new);
|
||||||
locs.forEach(location -> {
|
locs.forEach(location -> {
|
||||||
RFallingBlockEntity entity = new RFallingBlockEntity(detonatorComponent.entities, location.clone().add(HALF), Material.RED_STAINED_GLASS);
|
RBlockDisplay blockDisplay = new RBlockDisplay(detonatorComponent.entities, location);
|
||||||
entity.setNoGravity(true);
|
blockDisplay.setBlock(Material.RED_STAINED_GLASS.createBlockData());
|
||||||
|
|
||||||
|
RInteraction interaction = new RInteraction(detonatorComponent.entities, location);
|
||||||
|
interaction.setCallback((player, entity, action) -> {
|
||||||
|
Vector vector = new Vector(entity.getX(), entity.getY(), entity.getZ());
|
||||||
|
DetonatorListener.addLocationToDetonator(vector.toLocation(player.getWorld()).getBlock().getLocation(), player);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ public class Detonator {
|
|||||||
|
|
||||||
public static void activateDetonator(DetonatorStorage detonator) {
|
public static void activateDetonator(DetonatorStorage detonator) {
|
||||||
Player p = detonator.getPlayer();
|
Player p = detonator.getPlayer();
|
||||||
if (Config.getInstance().get(p).getPlainValueOrDefault("detonator-autostart", false)) {
|
if (Config.STORE.get(p).isDetonatorAutostart()) {
|
||||||
AutostartListener.instance.activate(p);
|
AutostartListener.instance.activate(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -76,8 +76,8 @@ public class DetonatorCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register(value = "autostart", description = "DETONATOR_HELP_AUTOSTART")
|
@Register(value = "autostart", description = "DETONATOR_HELP_AUTOSTART")
|
||||||
public void toggleAutostartTimer(Player p) {
|
public void toggleAutostartTimer(Player p) {
|
||||||
boolean current = Config.getInstance().get(p).getPlainValueOrDefault("detonator-autostart", false);
|
boolean current = Config.STORE.get(p).isDetonatorAutostart();
|
||||||
Config.getInstance().get(p).put("detonator-autostart", !current);
|
Config.STORE.get(p).setDetonatorAutostart(!current);
|
||||||
if (!current) {
|
if (!current) {
|
||||||
BauSystem.MESSAGE.send("DETONATOR_AUTOSTART_ENABLE", p);
|
BauSystem.MESSAGE.send("DETONATOR_AUTOSTART_ENABLE", p);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+10
-10
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of the SteamWar software.
|
* This file is a part of the SteamWar software.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
@@ -17,15 +17,15 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.steamwar.linkage;
|
package de.steamwar.bausystem.features.experimental;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import de.steamwar.command.SWCommand;
|
||||||
import java.lang.annotation.Retention;
|
import de.steamwar.linkage.Linked;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Linked
|
||||||
@Target({ElementType.TYPE})
|
public class ExperimentalCommand extends SWCommand {
|
||||||
public @interface MaxVersion {
|
|
||||||
int value();
|
public ExperimentalCommand() {
|
||||||
|
super("experimental", "experiment");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.features.experimental.redstone_engine;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.features.experimental.ExperimentalCommand;
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
|
import de.steamwar.command.AbstractSWCommand;
|
||||||
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import io.papermc.paper.configuration.WorldConfiguration;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.title.TitlePart;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@AbstractSWCommand.PartOf(ExperimentalCommand.class)
|
||||||
|
@Linked
|
||||||
|
public class RedstoneEngine extends SWCommand implements Listener, ScoreboardElement {
|
||||||
|
|
||||||
|
public RedstoneEngine() {
|
||||||
|
super("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private WorldConfiguration.Misc getConfig() {
|
||||||
|
return ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle().paperConfig().misc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register("redstone")
|
||||||
|
@Register("redstoneengine")
|
||||||
|
public void setRedstoneEngine(Player player, @StaticValue("alternate_current") String __, WorldConfiguration.Misc.AlternateCurrentUpdateOrder updateOrder) {
|
||||||
|
WorldConfiguration.Misc misc = getConfig();
|
||||||
|
misc.redstoneImplementation = WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT;
|
||||||
|
misc.alternateCurrentUpdateOrder = updateOrder;
|
||||||
|
broadcastTitle(Bukkit.getOnlinePlayers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register("redstone")
|
||||||
|
@Register("redstoneengine")
|
||||||
|
public void setRedstoneEngine(Player player, WorldConfiguration.Misc.RedstoneImplementation implementation) {
|
||||||
|
getConfig().redstoneImplementation = implementation;
|
||||||
|
broadcastTitle(Bukkit.getOnlinePlayers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
WorldConfiguration.Misc misc = getConfig();
|
||||||
|
if (misc.redstoneImplementation != WorldConfiguration.Misc.RedstoneImplementation.EIGENCRAFT) {
|
||||||
|
broadcastTitle(List.of(event.getPlayer()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void broadcastTitle(Collection<? extends Player> players) {
|
||||||
|
WorldConfiguration.Misc misc = getConfig();
|
||||||
|
Component title = switch (misc.redstoneImplementation) {
|
||||||
|
case VANILLA -> Component.text("⚠").color(NamedTextColor.RED).append(Component.text(" Redstone: Vanilla ").color(NamedTextColor.WHITE)).append(Component.text("⚠").color(NamedTextColor.RED));
|
||||||
|
case EIGENCRAFT -> Component.text("Redstone: Eigencraft");
|
||||||
|
case ALTERNATE_CURRENT -> Component.text("⚠").color(NamedTextColor.RED).append(Component.text(" Redstone: AC ").color(NamedTextColor.WHITE)).append(Component.text("⚠").color(NamedTextColor.RED));
|
||||||
|
};
|
||||||
|
Component subtitle;
|
||||||
|
if (misc.redstoneImplementation != WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) {
|
||||||
|
subtitle = Component.text().build();
|
||||||
|
} else {
|
||||||
|
subtitle = switch (misc.alternateCurrentUpdateOrder) {
|
||||||
|
case VERTICAL_FIRST_INWARD -> Component.text("Y first inwards"); // Y before XZ
|
||||||
|
case VERTICAL_FIRST_OUTWARD -> Component.text("Y first outwards"); // XZ before Y
|
||||||
|
case HORIZONTAL_FIRST_INWARD -> Component.text("XZ first inwards"); // Y before XZ
|
||||||
|
case HORIZONTAL_FIRST_OUTWARD -> Component.text("XZ first outwards"); // XZ before Y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
players.forEach(player -> {
|
||||||
|
player.sendTitlePart(TitlePart.TITLE, title);
|
||||||
|
player.sendTitlePart(TitlePart.SUBTITLE, subtitle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScoreboardGroup getGroup() {
|
||||||
|
return ScoreboardGroup.FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int order() {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Region region, Player p) {
|
||||||
|
WorldConfiguration.Misc misc = getConfig();
|
||||||
|
switch (misc.redstoneImplementation) {
|
||||||
|
case ALTERNATE_CURRENT:
|
||||||
|
switch (misc.alternateCurrentUpdateOrder) {
|
||||||
|
case VERTICAL_FIRST_INWARD:
|
||||||
|
return "§eRedstone§8: §cAC §8(§7Y in§8)";
|
||||||
|
case VERTICAL_FIRST_OUTWARD:
|
||||||
|
return "§eRedstone§8: §cAC §8(§7Y out§8)";
|
||||||
|
case HORIZONTAL_FIRST_INWARD:
|
||||||
|
return "§eRedstone§8: §cAC §8(§7XZ in§8)";
|
||||||
|
case HORIZONTAL_FIRST_OUTWARD:
|
||||||
|
return "§eRedstone§8: §cAC §8(§7XZ out§8)";
|
||||||
|
}
|
||||||
|
return "§eRedstone§8: §cAC";
|
||||||
|
case EIGENCRAFT:
|
||||||
|
return null;
|
||||||
|
case VANILLA:
|
||||||
|
default:
|
||||||
|
return "§eRedstone§8: §cVanilla";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-2
@@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.gui.editor;
|
|||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.gui.BauGUI;
|
import de.steamwar.bausystem.features.gui.BauGUI;
|
||||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||||
import de.steamwar.core.TrickyTrialsWrapper;
|
|
||||||
import de.steamwar.data.CMDs;
|
import de.steamwar.data.CMDs;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.inventory.SWListInv;
|
import de.steamwar.inventory.SWListInv;
|
||||||
@@ -74,7 +73,7 @@ public class BauGuiEditor implements Listener {
|
|||||||
|
|
||||||
inv.setItem(mapping.getSize() + 5, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_TRASH", p), Arrays.asList(BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_TRASH_LORE", p)), false, clickType -> {
|
inv.setItem(mapping.getSize() + 5, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_TRASH", p), Arrays.asList(BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_TRASH_LORE", p)), false, clickType -> {
|
||||||
}).getItemStack());
|
}).getItemStack());
|
||||||
inv.setItem(mapping.getSize() + 6, new SWItem(TrickyTrialsWrapper.impl.getTurtleScute(), BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_MORE", p)).getItemStack());
|
inv.setItem(mapping.getSize() + 6, new SWItem(Material.TURTLE_SCUTE, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_MORE", p)).getItemStack());
|
||||||
inv.setItem(mapping.getSize() + 8, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_CLOSE", p)).setCustomModelData(CMDs.BACK).getItemStack());
|
inv.setItem(mapping.getSize() + 8, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_CLOSE", p)).setCustomModelData(CMDs.BACK).getItemStack());
|
||||||
|
|
||||||
p.openInventory(inv);
|
p.openInventory(inv);
|
||||||
|
|||||||
+15
-16
@@ -28,7 +28,6 @@ import lombok.Setter;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -52,15 +51,15 @@ public class BauGuiMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final YAPIONObject object;
|
private final Config config;
|
||||||
@Getter
|
@Getter
|
||||||
private final Player owner;
|
private final Player owner;
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private boolean saved;
|
private boolean saved;
|
||||||
|
|
||||||
protected BauGuiMapping(YAPIONObject object, Player p) {
|
protected BauGuiMapping(Config config, Player p) {
|
||||||
this.object = object;
|
this.config = config;
|
||||||
this.owner = p;
|
this.owner = p;
|
||||||
fromUUID.put(p.getUniqueId(), this);
|
fromUUID.put(p.getUniqueId(), this);
|
||||||
mappings.add(this);
|
mappings.add(this);
|
||||||
@@ -70,19 +69,18 @@ public class BauGuiMapping {
|
|||||||
BauGuiMapping mapping = fromUUID.get(p.getUniqueId());
|
BauGuiMapping mapping = fromUUID.get(p.getUniqueId());
|
||||||
|
|
||||||
if (mapping == null) {
|
if (mapping == null) {
|
||||||
YAPIONObject yapionObject = Config.getInstance().get(p);
|
mapping = new BauGuiMapping(Config.STORE.get(p), p);
|
||||||
mapping = new BauGuiMapping(yapionObject.getObject("baugui"), p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShown(int id) {
|
public boolean isShown(int id) {
|
||||||
return object.getPlainValueOrDefault(Integer.toString(id), -1) >= 0;
|
return config.getBauGui().getOrDefault(id, -1) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSlot(int id) {
|
public int getSlot(int id) {
|
||||||
return object.getPlainValue(Integer.toString(id));
|
return config.getBauGui().get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, Integer> getMapping() {
|
public Map<Integer, Integer> getMapping() {
|
||||||
@@ -94,7 +92,7 @@ public class BauGuiMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return object.getPlainValueOrDefault("size", 45);
|
return config.getBauGuiSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSize(int size) {
|
public void setSize(int size) {
|
||||||
@@ -102,7 +100,7 @@ public class BauGuiMapping {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
object.add("size", size);
|
config.setBauGuiSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tick() {
|
private void tick() {
|
||||||
@@ -111,16 +109,17 @@ public class BauGuiMapping {
|
|||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
if (saved) return;
|
if (saved) return;
|
||||||
YAPIONObject config = Config.getInstance().get(owner);
|
Config current = Config.STORE.get(owner);
|
||||||
config.add("baugui", object);
|
current.setBauGui(config.getBauGui());
|
||||||
Config.getInstance().save(owner);
|
current.setBauGuiSize(config.getBauGuiSize());
|
||||||
|
Config.STORE.save(owner);
|
||||||
saved = true;
|
saved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, Integer> internalReadMap() {
|
private Map<Integer, Integer> internalReadMap() {
|
||||||
Map<Integer, Integer> map = new HashMap<>();
|
Map<Integer, Integer> map = new HashMap<>();
|
||||||
for (Map.Entry<Integer, BauGuiItem> e : BauGUI.getITEMS().entrySet()) {
|
for (Map.Entry<Integer, BauGuiItem> e : BauGUI.getITEMS().entrySet()) {
|
||||||
Integer value = object.getPlainValueOrDefault(e.getKey().toString(), -1);
|
Integer value = config.getBauGui().getOrDefault(e.getKey(), -1);
|
||||||
if (value == -1) continue;
|
if (value == -1) continue;
|
||||||
map.put(e.getKey(), value);
|
map.put(e.getKey(), value);
|
||||||
}
|
}
|
||||||
@@ -129,10 +128,10 @@ public class BauGuiMapping {
|
|||||||
|
|
||||||
private void internalWriteMap(Map<Integer, Integer> map) {
|
private void internalWriteMap(Map<Integer, Integer> map) {
|
||||||
for (Map.Entry<Integer, BauGuiItem> e : BauGUI.getITEMS().entrySet()) {
|
for (Map.Entry<Integer, BauGuiItem> e : BauGUI.getITEMS().entrySet()) {
|
||||||
object.remove(e.getKey().toString());
|
config.getBauGui().remove(e.getKey());
|
||||||
Integer value = map.getOrDefault(e.getKey(), -1);
|
Integer value = map.getOrDefault(e.getKey(), -1);
|
||||||
if (value == -1) continue;
|
if (value == -1) continue;
|
||||||
object.add(e.getKey().toString(), value);
|
config.getBauGui().put(e.getKey(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-40
@@ -20,39 +20,23 @@
|
|||||||
package de.steamwar.bausystem.features.hotbar;
|
package de.steamwar.bausystem.features.hotbar;
|
||||||
|
|
||||||
import de.steamwar.bausystem.configplayer.Config;
|
import de.steamwar.bausystem.configplayer.Config;
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import yapion.hierarchy.types.YAPIONArray;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
import yapion.hierarchy.types.YAPIONValue;
|
|
||||||
import yapion.parser.YAPIONParser;
|
|
||||||
import yapion.serializing.YAPIONDeserializer;
|
|
||||||
import yapion.serializing.YAPIONSerializer;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class DefaultHotbar {
|
public class DefaultHotbar {
|
||||||
|
|
||||||
private final YAPIONArray DEFAULT_HOTBAR = YAPIONParser.parse("{[{@type(org.bukkit.inventory.ItemStack)v(2230)type(WOODEN_AXE)meta{@type(org.bukkit.inventory.meta.ItemMeta)meta-type(UNSPECIFIC)display-name(WorldEdit Wand)lore{@type(java.util.ArrayList)values[Left click: select pos #1,Right click: select pos #2]}}},{@type(org.bukkit.inventory.ItemStack)v(2230)type(COMPASS)meta{@type(org.bukkit.inventory.meta.ItemMeta)meta-type(UNSPECIFIC)display-name(Navigation Wand)lore{@type(java.util.ArrayList)values[Left click: jump to location,Right click: pass through walls]}}},null,null,null,null,null,null,{@type(org.bukkit.inventory.ItemStack)v(2230)type(NETHER_STAR)meta{@type(org.bukkit.inventory.meta.ItemMeta)meta-type(UNSPECIFIC)display-name(§eBau GUI)}},null,null,{@type(org.bukkit.inventory.ItemStack)v(3117)type(ELYTRA)},null]}").getArray("");
|
|
||||||
|
|
||||||
public void updateHotbar(Player p) {
|
public void updateHotbar(Player p) {
|
||||||
ItemStack[] hotbar = new ItemStack[13];
|
ItemStack[] hotbar = new ItemStack[13];
|
||||||
System.arraycopy(p.getInventory().getContents(), 0, hotbar, 0, 9);
|
System.arraycopy(p.getInventory().getContents(), 0, hotbar, 0, 9);
|
||||||
System.arraycopy(p.getInventory().getArmorContents(), 0, hotbar, 9, 4);
|
System.arraycopy(p.getInventory().getArmorContents(), 0, hotbar, 9, 4);
|
||||||
YAPIONArray yapionArray = new YAPIONArray();
|
Config.STORE.get(p).setHotbar(copy(hotbar));
|
||||||
for (ItemStack itemStack : hotbar) {
|
Config.STORE.save(p);
|
||||||
if (itemStack != null) {
|
|
||||||
yapionArray.add(YAPIONSerializer.serialize(itemStack));
|
|
||||||
} else {
|
|
||||||
yapionArray.add(new YAPIONValue<>(null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Config.getInstance().get(p).add("hotbar-" + Core.getVersion(), yapionArray);
|
|
||||||
Config.getInstance().save(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHotbar(Player p) {
|
public void setHotbar(Player p) {
|
||||||
@@ -66,28 +50,34 @@ public class DefaultHotbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack[] getItems(Player p) {
|
public ItemStack[] getItems(Player p) {
|
||||||
Config.getInstance().get(p).remap("hotbar", "hotbar-19");
|
return copy(Config.STORE.get(p).getHotbar());
|
||||||
YAPIONArray yapionArray = Config.getInstance().get(p).getYAPIONArrayOrSetDefault("hotbar-" + Core.getVersion(), defaultHotbar());
|
}
|
||||||
|
|
||||||
|
public ItemStack[] defaultHotbar() {
|
||||||
ItemStack[] hotbar = new ItemStack[13];
|
ItemStack[] hotbar = new ItemStack[13];
|
||||||
Set<Integer> invalid = new HashSet<>();
|
hotbar[0] = item(Material.WOODEN_AXE, "WorldEdit Wand", "Left click: select pos #1", "Right click: select pos #2");
|
||||||
yapionArray.forEach((integer, yapionAnyType) -> {
|
hotbar[1] = item(Material.COMPASS, "Navigation Wand", "Left click: jump to location", "Right click: pass through walls");
|
||||||
if (yapionAnyType instanceof YAPIONValue) {
|
hotbar[8] = item(Material.NETHER_STAR, "§eBau GUI");
|
||||||
hotbar[integer] = null;
|
hotbar[11] = new ItemStack(Material.ELYTRA);
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
hotbar[integer] = YAPIONDeserializer.deserialize((YAPIONObject) yapionAnyType);
|
|
||||||
} catch (Exception e) {
|
|
||||||
invalid.add(integer);
|
|
||||||
hotbar[integer] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
invalid.forEach(i -> yapionArray.set(i, new YAPIONValue<>(null)));
|
|
||||||
if (!invalid.isEmpty()) Config.getInstance().save(p);
|
|
||||||
return hotbar;
|
return hotbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public YAPIONArray defaultHotbar() {
|
private ItemStack item(Material material, String name, String... lore) {
|
||||||
return DEFAULT_HOTBAR;
|
ItemStack itemStack = new ItemStack(material);
|
||||||
|
ItemMeta meta = itemStack.getItemMeta();
|
||||||
|
meta.setDisplayName(name);
|
||||||
|
if (lore.length > 0) {
|
||||||
|
meta.setLore(List.of(lore));
|
||||||
|
}
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack[] copy(ItemStack[] hotbar) {
|
||||||
|
ItemStack[] copy = new ItemStack[13];
|
||||||
|
for (int i = 0; i < Math.min(hotbar.length, copy.length); i++) {
|
||||||
|
copy[i] = hotbar[i] == null ? null : hotbar[i].clone();
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ public class HotbarListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
if (allNull(event.getPlayer().getInventory().getContents()) && allNull(event.getPlayer().getInventory().getArmorContents())) {
|
if (allNull(event.getPlayer().getInventory().getContents()) && allNull(event.getPlayer().getInventory().getArmorContents())) {
|
||||||
DefaultHotbar.setHotbar(event.getPlayer());
|
DefaultHotbar.setHotbar(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -49,8 +49,9 @@ public class InventoryFillBauGuiItem extends BauGuiItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItem(Player player) {
|
public ItemStack getItem(Player player) {
|
||||||
String loreKey = Config.getInstance().get(player).getPlainValueOrDefault("inventoryfill", false) ? "OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE" : "OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE";
|
String loreKey = Config.STORE.get(player).isInventoryFill() ? "OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE" : "OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE";
|
||||||
return new SWItem(Material.HOPPER, BauSystem.MESSAGE.parse("OTHER_ITEMS_INVENTORY_FILL_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse(loreKey, player)), false, clickType -> {}).getItemStack();
|
return new SWItem(Material.HOPPER, BauSystem.MESSAGE.parse("OTHER_ITEMS_INVENTORY_FILL_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse(loreKey, player)), false, clickType -> {
|
||||||
|
}).getItemStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+4
-4
@@ -39,8 +39,8 @@ public class InventoryFiller implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
|
if (!Config.STORE.get(event.getPlayer()).isInventoryFill()) return;
|
||||||
if (!event.getPlayer().isSneaking()) return;
|
if (!event.getPlayer().isSneaking()) return;
|
||||||
Block block = event.getPlayer().getTargetBlockExact(5);
|
Block block = event.getPlayer().getTargetBlockExact(5);
|
||||||
if (block == null) return;
|
if (block == null) return;
|
||||||
@@ -61,8 +61,8 @@ public class InventoryFiller implements Listener {
|
|||||||
*/
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
|
if (!Config.STORE.get(event.getPlayer()).isInventoryFill()) return;
|
||||||
if (!event.getPlayer().isSneaking()) return;
|
if (!event.getPlayer().isSneaking()) return;
|
||||||
ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand();
|
ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand();
|
||||||
if (itemStack.getType() == Material.AIR) return;
|
if (itemStack.getType() == Material.AIR) return;
|
||||||
|
|||||||
+2
-2
@@ -68,8 +68,8 @@ public class InventoryFillerCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register(description = {"INVENTORY_FILL_HELP", "INVENTORY_FILL_INFO"})
|
@Register(description = {"INVENTORY_FILL_HELP", "INVENTORY_FILL_INFO"})
|
||||||
public void toggle(Player player) {
|
public void toggle(Player player) {
|
||||||
boolean inventoryFill = Config.getInstance().get(player).getPlainValueOrDefault("inventoryfill", false);
|
boolean inventoryFill = Config.STORE.get(player).isInventoryFill();
|
||||||
Config.getInstance().get(player).put("inventoryfill", !inventoryFill);
|
Config.STORE.get(player).setInventoryFill(!inventoryFill);
|
||||||
if (!inventoryFill) {
|
if (!inventoryFill) {
|
||||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("INVENTORY_FILL_ENABLE", player));
|
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("INVENTORY_FILL_ENABLE", player));
|
||||||
BauSystem.MESSAGE.send("INVENTORY_FILL_INFO", player);
|
BauSystem.MESSAGE.send("INVENTORY_FILL_INFO", player);
|
||||||
|
|||||||
+9
-5
@@ -24,9 +24,9 @@ import de.steamwar.bausystem.region.Point;
|
|||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||||
|
import de.steamwar.entity.RBlockDisplay;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@@ -104,7 +104,9 @@ public class KillcheckerVisualizer {
|
|||||||
Block block = WORLD.getBlockAt(x, y, z);
|
Block block = WORLD.getBlockAt(x, y, z);
|
||||||
if (block.getType().isAir()) continue;
|
if (block.getType().isAir()) continue;
|
||||||
String name = block.getType().name();
|
String name = block.getType().name();
|
||||||
if (!name.endsWith("_WOOL") && !name.endsWith("_STAINED_GLASS") && !name.endsWith("_CONCRETE") && !name.endsWith("_TERRACOTTA")) continue;
|
if (!name.endsWith("_WOOL") && !name.endsWith("_STAINED_GLASS") && !name.endsWith("_CONCRETE") && !name.endsWith("_TERRACOTTA")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (name.equals("_GLAZED_TERRACOTTA")) continue;
|
if (name.equals("_GLAZED_TERRACOTTA")) continue;
|
||||||
Cuboid cuboid = create(block.getType(), x, y, z);
|
Cuboid cuboid = create(block.getType(), x, y, z);
|
||||||
cuboids.add(cuboid);
|
cuboids.add(cuboid);
|
||||||
@@ -283,11 +285,13 @@ public class KillcheckerVisualizer {
|
|||||||
}
|
}
|
||||||
kill.forEach((point, count) -> {
|
kill.forEach((point, count) -> {
|
||||||
if (rEntities.containsKey(point)) {
|
if (rEntities.containsKey(point)) {
|
||||||
if (killCount.get(point) == count && outlinePoints.contains(point) == outlinePointsCacheLast.contains(point)) return;
|
if (killCount.get(point) == count && outlinePoints.contains(point) == outlinePointsCacheLast.contains(point)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
rEntities.get(point).die();
|
rEntities.get(point).die();
|
||||||
}
|
}
|
||||||
RFallingBlockEntity entity = new RFallingBlockEntity(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5), MATERIALS[Math.min(count - 1, MATERIALS.length) - 1]);
|
RBlockDisplay entity = new RBlockDisplay(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0, 0, 0));
|
||||||
entity.setNoGravity(true);
|
entity.setBlock(MATERIALS[Math.min(count - 1, MATERIALS.length) - 1].createBlockData());
|
||||||
rEntities.put(point, entity);
|
rEntities.put(point, entity);
|
||||||
if (outlinePoints.contains(point)) outlinePointsCache.add(point);
|
if (outlinePoints.contains(point)) outlinePointsCache.add(point);
|
||||||
killCount.put(point, count);
|
killCount.put(point, count);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class Loader implements Listener, SWPlayer.Component {
|
|||||||
|
|
||||||
BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
|
BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
|
||||||
if (stage != Stage.RUNNING && stage != Stage.SINGLE) return;
|
if (stage != Stage.RUNNING && stage != Stage.SINGLE) return;
|
||||||
if(!Permission.BUILD.hasPermission(p)) return;
|
if (!Permission.BUILD.hasPermission(p)) return;
|
||||||
if (waitTime > 0) {
|
if (waitTime > 0) {
|
||||||
waitTime--;
|
waitTime--;
|
||||||
return;
|
return;
|
||||||
@@ -213,7 +213,8 @@ public class Loader implements Listener, SWPlayer.Component {
|
|||||||
};
|
};
|
||||||
updateRunnable.run();
|
updateRunnable.run();
|
||||||
|
|
||||||
SWListInv<LoaderElement> swListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("LOADER_GUI_TITLE", p), false, list, (clickType, loaderElement) -> {});
|
SWListInv<LoaderElement> swListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("LOADER_GUI_TITLE", p), false, list, (clickType, loaderElement) -> {
|
||||||
|
});
|
||||||
swListInv.setCallback((clickType, entry) -> entry.click(p, () -> {
|
swListInv.setCallback((clickType, entry) -> entry.click(p, () -> {
|
||||||
updateRunnable.run();
|
updateRunnable.run();
|
||||||
swListInv.open();
|
swListInv.open();
|
||||||
@@ -363,7 +364,9 @@ public class Loader implements Listener, SWPlayer.Component {
|
|||||||
public static int LENGTH = SettingsSorting.values().length;
|
public static int LENGTH = SettingsSorting.values().length;
|
||||||
|
|
||||||
public abstract Material getMaterial();
|
public abstract Material getMaterial();
|
||||||
|
|
||||||
public abstract String getName();
|
public abstract String getName();
|
||||||
|
|
||||||
public abstract boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next);
|
public abstract boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ public class LoaderScoreboardElement implements ScoreboardElement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(Region region, Player p) {
|
public String get(Region region, Player p) {
|
||||||
if(!Permission.BUILD.hasPermission(p)) return null;
|
if (!Permission.BUILD.hasPermission(p)) return null;
|
||||||
Loader loader = Loader.getLoader(p);
|
Loader loader = Loader.getLoader(p);
|
||||||
if (loader == null) return null;
|
if (loader == null) return null;
|
||||||
if (loader.getStage() == Loader.Stage.RUNNING) {
|
if (loader.getStage() == Loader.Stage.RUNNING) {
|
||||||
|
|||||||
+2
@@ -26,6 +26,8 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public interface LoaderElement {
|
public interface LoaderElement {
|
||||||
SWItem menu(Player player);
|
SWItem menu(Player player);
|
||||||
|
|
||||||
void execute(Consumer<Long> delay);
|
void execute(Consumer<Long> delay);
|
||||||
|
|
||||||
void click(Player player, Runnable backAction);
|
void click(Player player, Runnable backAction);
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-6
@@ -95,7 +95,8 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
|
|||||||
};
|
};
|
||||||
updateRunnable.run();
|
updateRunnable.run();
|
||||||
|
|
||||||
SWListInv<Integer> listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {});
|
SWListInv<Integer> listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {
|
||||||
|
});
|
||||||
listInv.setCallback((clickType, entry) -> {
|
listInv.setCallback((clickType, entry) -> {
|
||||||
openIndividualSettingsMenu(player, entry, () -> {
|
openIndividualSettingsMenu(player, entry, () -> {
|
||||||
updateRunnable.run();
|
updateRunnable.run();
|
||||||
@@ -150,7 +151,10 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
|
|||||||
}
|
}
|
||||||
|
|
||||||
SWInventory swInventory = new SWInventory(player, guiSize, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
|
SWInventory swInventory = new SWInventory(player, guiSize, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
|
||||||
for (int i = guiSize - 9; i < guiSize; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", clickType -> {}));
|
for (int i = guiSize - 9; i < guiSize; i++) {
|
||||||
|
swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", clickType -> {
|
||||||
|
}));
|
||||||
|
}
|
||||||
swInventory.setItem(guiSize - 9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).setCustomModelData(CMDs.BACK).getItemStack(), clickType -> back.run());
|
swInventory.setItem(guiSize - 9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).setCustomModelData(CMDs.BACK).getItemStack(), clickType -> back.run());
|
||||||
swInventory.setItem(guiSize - 5, new SWItem(Material.WOODEN_AXE, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_COPY", player)).getItemStack(), clickType -> {
|
swInventory.setItem(guiSize - 5, new SWItem(Material.WOODEN_AXE, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_COPY", player)).getItemStack(), clickType -> {
|
||||||
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_GUI_COPY_TITLE", player), "1");
|
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_GUI_COPY_TITLE", player), "1");
|
||||||
@@ -197,7 +201,8 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
|
|||||||
for (int power = 0; power < 16; power++) {
|
for (int power = 0; power < 16; power++) {
|
||||||
int finalPowerPosition = power;
|
int finalPowerPosition = power;
|
||||||
if (power >= 9) finalPowerPosition++;
|
if (power >= 9) finalPowerPosition++;
|
||||||
SWItem powerItem = new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power), Arrays.asList(), false, clickType -> {});
|
SWItem powerItem = new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power), Arrays.asList(), false, clickType -> {
|
||||||
|
});
|
||||||
powerItem.getItemStack().setAmount(Math.max(power, 1));
|
powerItem.getItemStack().setAmount(Math.max(power, 1));
|
||||||
if (extraPower.get(index) == power) powerItem.setEnchanted(true);
|
if (extraPower.get(index) == power) powerItem.setEnchanted(true);
|
||||||
|
|
||||||
@@ -210,7 +215,8 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentElement.hasTicks(this)) {
|
if (currentElement.hasTicks(this)) {
|
||||||
swInventory.setItem(ticksStart + 3, new SWItem(SWItem.getDye(1), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
|
swInventory.setItem(ticksStart + 3, new SWItem(Material.RED_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {
|
||||||
|
}).getItemStack(), clickType -> {
|
||||||
long ticks = extraTicks.get(index);
|
long ticks = extraTicks.get(index);
|
||||||
ticks -= clickType.isShiftClick() ? 5 : 1;
|
ticks -= clickType.isShiftClick() ? 5 : 1;
|
||||||
if (ticks < 1) ticks = 1;
|
if (ticks < 1) ticks = 1;
|
||||||
@@ -218,7 +224,8 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
|
|||||||
openIndividualSettingsMenu(player, index, back, delete);
|
openIndividualSettingsMenu(player, index, back, delete);
|
||||||
});
|
});
|
||||||
|
|
||||||
SWItem ticksItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS", player, extraTicks.get(index)), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)), false, clickType -> {});
|
SWItem ticksItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS", player, extraTicks.get(index)), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)), false, clickType -> {
|
||||||
|
});
|
||||||
ticksItem.getItemStack().setAmount((int) Math.min(extraTicks.get(index), 64));
|
ticksItem.getItemStack().setAmount((int) Math.min(extraTicks.get(index), 64));
|
||||||
swInventory.setItem(ticksStart + 4, ticksItem.getItemStack(), clickType -> {
|
swInventory.setItem(ticksStart + 4, ticksItem.getItemStack(), clickType -> {
|
||||||
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_NAME", player), extraTicks.get(index) + "");
|
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_NAME", player), extraTicks.get(index) + "");
|
||||||
@@ -234,7 +241,8 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
|
|||||||
swAnvilInv.open();
|
swAnvilInv.open();
|
||||||
});
|
});
|
||||||
|
|
||||||
swInventory.setItem(ticksStart + 5, new SWItem(SWItem.getDye(10), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
|
swInventory.setItem(ticksStart + 5, new SWItem(Material.LIME_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {
|
||||||
|
}).getItemStack(), clickType -> {
|
||||||
long ticks = extraTicks.get(index);
|
long ticks = extraTicks.get(index);
|
||||||
ticks += clickType.isShiftClick() ? 5 : 1;
|
ticks += clickType.isShiftClick() ? 5 : 1;
|
||||||
extraTicks.set(index, ticks);
|
extraTicks.set(index, ticks);
|
||||||
|
|||||||
+3
@@ -28,10 +28,13 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public interface LoaderSettingsEnum<T, P extends LoaderInteractionElement<E>, E extends Enum<E> & LoaderSettingsEnum<T, P, E>> {
|
public interface LoaderSettingsEnum<T, P extends LoaderInteractionElement<E>, E extends Enum<E> & LoaderSettingsEnum<T, P, E>> {
|
||||||
int getPos();
|
int getPos();
|
||||||
|
|
||||||
SWItem menu(Player player, P parent, int power, long ticks);
|
SWItem menu(Player player, P parent, int power, long ticks);
|
||||||
|
|
||||||
default boolean hasPower(P parent) {
|
default boolean hasPower(P parent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean hasTicks(P parent) {
|
default boolean hasTicks(P parent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -63,7 +63,8 @@ public class LoaderWait implements LoaderElement {
|
|||||||
for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
|
for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
|
||||||
swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_WAIT_BACK", player)).setCustomModelData(CMDs.BACK).getItemStack(), clickType -> backAction.run());
|
swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_WAIT_BACK", player)).setCustomModelData(CMDs.BACK).getItemStack(), clickType -> backAction.run());
|
||||||
|
|
||||||
swInventory.setItem(3, new SWItem(SWItem.getDye(1), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
|
swInventory.setItem(3, new SWItem(Material.RED_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {
|
||||||
|
}).getItemStack(), clickType -> {
|
||||||
delay -= clickType.isShiftClick() ? 5 : 1;
|
delay -= clickType.isShiftClick() ? 5 : 1;
|
||||||
if (delay < 0) delay = 0;
|
if (delay < 0) delay = 0;
|
||||||
swInventory.setItem(4, menu(player));
|
swInventory.setItem(4, menu(player));
|
||||||
@@ -80,7 +81,8 @@ public class LoaderWait implements LoaderElement {
|
|||||||
});
|
});
|
||||||
swAnvilInv.open();
|
swAnvilInv.open();
|
||||||
});
|
});
|
||||||
swInventory.setItem(5, new SWItem(SWItem.getDye(10), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
|
swInventory.setItem(5, new SWItem(Material.LIME_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {
|
||||||
|
}).getItemStack(), clickType -> {
|
||||||
delay += clickType.isShiftClick() ? 5 : 1;
|
delay += clickType.isShiftClick() ? 5 : 1;
|
||||||
swInventory.setItem(4, menu(player));
|
swInventory.setItem(4, menu(player));
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-4
@@ -146,8 +146,7 @@ public class Loadtimer implements Listener {
|
|||||||
if ((stage == Stage.COUNTING || stage == Stage.ACTIVATED)) {
|
if ((stage == Stage.COUNTING || stage == Stage.ACTIVATED)) {
|
||||||
stage = Stage.IGNITION;
|
stage = Stage.IGNITION;
|
||||||
ignite = TPSUtils.currentRealTick.get();
|
ignite = TPSUtils.currentRealTick.get();
|
||||||
if (activate == -1)
|
if (activate == -1) activate = TPSUtils.currentRealTick.get();
|
||||||
activate = TPSUtils.currentRealTick.get();
|
|
||||||
if (finishOnActive) {
|
if (finishOnActive) {
|
||||||
stage = Stage.END;
|
stage = Stage.END;
|
||||||
print();
|
print();
|
||||||
@@ -184,8 +183,7 @@ public class Loadtimer implements Listener {
|
|||||||
|
|
||||||
long ignTime = ignite - activate;
|
long ignTime = ignite - activate;
|
||||||
long explTime = explode - ignTime - activate;
|
long explTime = explode - ignTime - activate;
|
||||||
if (explTime < 0)
|
if (explTime < 0) explTime = loadTime;
|
||||||
explTime = loadTime;
|
|
||||||
|
|
||||||
int finalAllTnt = allTnt;
|
int finalAllTnt = allTnt;
|
||||||
long finalExplTime = explTime;
|
long finalExplTime = explTime;
|
||||||
|
|||||||
+4
-2
@@ -40,17 +40,19 @@ public class LoadtimerCommand extends SWCommand {
|
|||||||
public void start(@Validator Player p, TimerMode mode) {
|
public void start(@Validator Player p, TimerMode mode) {
|
||||||
Region r = Region.getRegion(p.getLocation());
|
Region r = Region.getRegion(p.getLocation());
|
||||||
if (r.getType().isGlobal()) return;
|
if (r.getType().isGlobal()) return;
|
||||||
if (!Loadtimer.hasTimer(r))
|
if (!Loadtimer.hasTimer(r)) {
|
||||||
Loadtimer.createLoadtimer(r, mode == TimerMode.HALF);
|
Loadtimer.createLoadtimer(r, mode == TimerMode.HALF);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Register(value = "stop", description = "LOADTIMER_HELP_STOP")
|
@Register(value = "stop", description = "LOADTIMER_HELP_STOP")
|
||||||
public void stop(@Validator Player p) {
|
public void stop(@Validator Player p) {
|
||||||
Region r = Region.getRegion(p.getLocation());
|
Region r = Region.getRegion(p.getLocation());
|
||||||
if (r.getType().isGlobal()) return;
|
if (r.getType().isGlobal()) return;
|
||||||
if (Loadtimer.hasTimer(r))
|
if (Loadtimer.hasTimer(r)) {
|
||||||
Loadtimer.getTimer(r).delete();
|
Loadtimer.getTimer(r).delete();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum TimerMode {
|
public enum TimerMode {
|
||||||
FULL,
|
FULL,
|
||||||
|
|||||||
+2
-1
@@ -46,8 +46,9 @@ public class LoadtimerGuiItem extends BauGuiItem {
|
|||||||
@Override
|
@Override
|
||||||
public ItemStack getItem(Player player) {
|
public ItemStack getItem(Player player) {
|
||||||
Region r = Region.getRegion(player.getLocation());
|
Region r = Region.getRegion(player.getLocation());
|
||||||
if (r.getType().isGlobal())
|
if (r.getType().isGlobal()) {
|
||||||
return new SWItem(Material.BOWL, BauSystem.MESSAGE.parse("LOADTIMER_GUI_GLOBAL", player)).getItemStack();
|
return new SWItem(Material.BOWL, BauSystem.MESSAGE.parse("LOADTIMER_GUI_GLOBAL", player)).getItemStack();
|
||||||
|
}
|
||||||
if (Loadtimer.hasTimer(r)) {
|
if (Loadtimer.hasTimer(r)) {
|
||||||
return new SWItem(Material.BOW, BauSystem.MESSAGE.parse("LOADTIMER_GUI_STOP", player)).getItemStack();
|
return new SWItem(Material.BOW, BauSystem.MESSAGE.parse("LOADTIMER_GUI_STOP", player)).getItemStack();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+3
-3
@@ -20,9 +20,9 @@
|
|||||||
package de.steamwar.bausystem.features.loadtimer;
|
package de.steamwar.bausystem.features.loadtimer;
|
||||||
|
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.core.TrickyTrialsWrapper;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
@@ -57,7 +57,7 @@ public class LoadtimerListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntitySpawn(EntitySpawnEvent event) {
|
public void onEntitySpawn(EntitySpawnEvent event) {
|
||||||
if (!getTimers().isEmpty() && event.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
|
if (!getTimers().isEmpty() && event.getEntityType() == EntityType.TNT) {
|
||||||
Region r = Region.getRegion(event.getLocation());
|
Region r = Region.getRegion(event.getLocation());
|
||||||
if (hasTimer(r)) {
|
if (hasTimer(r)) {
|
||||||
getTimer(r).onTntSpawn();
|
getTimer(r).onTntSpawn();
|
||||||
@@ -67,7 +67,7 @@ public class LoadtimerListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntityExplode(EntityExplodeEvent event) {
|
public void onEntityExplode(EntityExplodeEvent event) {
|
||||||
if (!getTimers().isEmpty() && event.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
|
if (!getTimers().isEmpty() && event.getEntityType() == EntityType.TNT) {
|
||||||
Region r = Region.getRegion(event.getLocation());
|
Region r = Region.getRegion(event.getLocation());
|
||||||
if (hasTimer(r)) {
|
if (hasTimer(r)) {
|
||||||
getTimer(r).onTntExplode(event);
|
getTimer(r).onTntExplode(event);
|
||||||
|
|||||||
+2
-2
@@ -46,7 +46,7 @@ public class ObserverTracerListener implements Listener {
|
|||||||
public ObserverTracerListener() {
|
public ObserverTracerListener() {
|
||||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||||
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
||||||
if (pair.getPlayer().getGameMode() != GameMode.SPECTATOR) return;
|
if (pair.getSwPlayer().getPlayer().getGameMode() != GameMode.SPECTATOR) return;
|
||||||
pair.getComponent().show();
|
pair.getComponent().show();
|
||||||
});
|
});
|
||||||
}, 15L, 15L);
|
}, 15L, 15L);
|
||||||
@@ -54,7 +54,7 @@ public class ObserverTracerListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
if (!enabled.contains(event.getPlayer())) return;
|
if (!enabled.contains(event.getPlayer())) return;
|
||||||
if (event.getClickedBlock() == null) return;
|
if (event.getClickedBlock() == null) return;
|
||||||
ObserverTracer observerTracer = SWPlayer.of(event.getPlayer()).getComponent(ObserverTracer.class).orElse(null);
|
ObserverTracer observerTracer = SWPlayer.of(event.getPlayer()).getComponent(ObserverTracer.class).orElse(null);
|
||||||
|
|||||||
+7
-9
@@ -28,7 +28,6 @@ import de.steamwar.command.SWCommand;
|
|||||||
import de.steamwar.entity.CRay;
|
import de.steamwar.entity.CRay;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -42,7 +41,6 @@ import org.bukkit.util.RayTraceResult;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(20)
|
|
||||||
public class RayVisualizerCommand extends SWCommand implements Listener {
|
public class RayVisualizerCommand extends SWCommand implements Listener {
|
||||||
|
|
||||||
private BlockData VISIBLE = Material.LIME_CONCRETE.createBlockData();
|
private BlockData VISIBLE = Material.LIME_CONCRETE.createBlockData();
|
||||||
@@ -63,9 +61,9 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean locEquals(Location loc1, Location loc2) {
|
private boolean locEquals(Location loc1, Location loc2) {
|
||||||
if ((long)(loc1.getX() * 1000) != (long)(loc2.getX() * 1000)) return false;
|
if ((long) (loc1.getX() * 1000) != (long) (loc2.getX() * 1000)) return false;
|
||||||
if ((long)(loc1.getY() * 1000) != (long)(loc2.getY() * 1000)) return false;
|
if ((long) (loc1.getY() * 1000) != (long) (loc2.getY() * 1000)) return false;
|
||||||
if ((long)(loc1.getZ() * 1000) != (long)(loc2.getZ() * 1000)) return false;
|
if ((long) (loc1.getZ() * 1000) != (long) (loc2.getZ() * 1000)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +167,7 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
boolean rayvisualizer = Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("rayvisualizer", false);
|
boolean rayvisualizer = Config.STORE.get(event.getPlayer()).isRayVisualizer();
|
||||||
if (rayvisualizer) server.addPlayer(event.getPlayer());
|
if (rayvisualizer) server.addPlayer(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +181,7 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
|||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (Permission.BUILD.hasPermission(player)) {
|
if (Permission.BUILD.hasPermission(player)) {
|
||||||
boolean rayvisualizer = Config.getInstance().get(player).getPlainValueOrDefault("rayvisualizer", false);
|
boolean rayvisualizer = Config.STORE.get(player).isRayVisualizer();
|
||||||
if (rayvisualizer) server.addPlayer(player);
|
if (rayvisualizer) server.addPlayer(player);
|
||||||
} else {
|
} else {
|
||||||
server.removePlayer(player);
|
server.removePlayer(player);
|
||||||
@@ -194,8 +192,8 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
|||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void toggle(@Validator Player player) {
|
public void toggle(@Validator Player player) {
|
||||||
boolean rayvisualizer = Config.getInstance().get(player).getPlainValueOrDefault("rayvisualizer", false);
|
boolean rayvisualizer = Config.STORE.get(player).isRayVisualizer();
|
||||||
Config.getInstance().get(player).put("rayvisualizer", !rayvisualizer);
|
Config.STORE.get(player).setRayVisualizer(!rayvisualizer);
|
||||||
if (!rayvisualizer) {
|
if (!rayvisualizer) {
|
||||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("RAY_VISUALIZER_ENABLE", player));
|
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("RAY_VISUALIZER_ENABLE", player));
|
||||||
server.addPlayer(player);
|
server.addPlayer(player);
|
||||||
|
|||||||
+6
-2
@@ -36,12 +36,16 @@ public class FireListener implements Listener, ScoreboardElement {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onFireDamage(BlockBurnEvent e) {
|
public void onFireDamage(BlockBurnEvent e) {
|
||||||
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true);
|
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onFireSpread(BlockSpreadEvent e) {
|
public void onFireSpread(BlockSpreadEvent e) {
|
||||||
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true);
|
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) {
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+2
-2
@@ -44,11 +44,11 @@ public class FreezeCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEnableMessage(){
|
private String getEnableMessage() {
|
||||||
return "REGION_FREEZE_ENABLED";
|
return "REGION_FREEZE_ENABLED";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDisableMessage(){
|
private String getDisableMessage() {
|
||||||
return "REGION_FREEZE_DISABLED";
|
return "REGION_FREEZE_DISABLED";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-7
@@ -24,8 +24,6 @@ import de.steamwar.bausystem.region.Region;
|
|||||||
import de.steamwar.bausystem.region.flags.Flag;
|
import de.steamwar.bausystem.region.flags.Flag;
|
||||||
import de.steamwar.bausystem.region.flags.FreezeMode;
|
import de.steamwar.bausystem.region.flags.FreezeMode;
|
||||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.core.TrickyTrialsWrapper;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -33,6 +31,7 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.data.type.NoteBlock;
|
import org.bukkit.block.data.type.NoteBlock;
|
||||||
import org.bukkit.block.data.type.Switch;
|
import org.bukkit.block.data.type.Switch;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
@@ -48,7 +47,9 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockExplode(BlockExplodeEvent e) {
|
public void onBlockExplode(BlockExplodeEvent e) {
|
||||||
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
|
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
BlockState state = e.getBlock().getState();
|
BlockState state = e.getBlock().getState();
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
@@ -58,9 +59,11 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntitySpawn(EntitySpawnEvent e) {
|
public void onEntitySpawn(EntitySpawnEvent e) {
|
||||||
if (Region.getRegion(e.getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
|
if (Region.getRegion(e.getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
if (e.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
|
if (e.getEntityType() == EntityType.TNT) {
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
e.getLocation().getBlock().setType(Material.TNT, false);
|
e.getLocation().getBlock().setType(Material.TNT, false);
|
||||||
}, 1L);
|
}, 1L);
|
||||||
@@ -70,7 +73,9 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockCanBuild(BlockCanBuildEvent e) {
|
public void onBlockCanBuild(BlockCanBuildEvent e) {
|
||||||
if (!e.isBuildable()) return;
|
if (!e.isBuildable()) return;
|
||||||
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
|
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (e.getMaterial() == Material.TNT) {
|
if (e.getMaterial() == Material.TNT) {
|
||||||
e.setBuildable(false);
|
e.setBuildable(false);
|
||||||
e.getBlock().setType(Material.TNT, false);
|
e.getBlock().setType(Material.TNT, false);
|
||||||
@@ -155,7 +160,6 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockBreak(BlockBreakEvent e) {
|
public void onBlockBreak(BlockBreakEvent e) {
|
||||||
if (Core.getVersion() < 19) return;
|
|
||||||
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
|
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
|
||||||
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
|
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
|||||||
+2
-4
@@ -25,11 +25,9 @@ import de.steamwar.bausystem.region.flags.Flag;
|
|||||||
import de.steamwar.bausystem.region.flags.ItemMode;
|
import de.steamwar.bausystem.region.flags.ItemMode;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public class ItemsCommand extends SWCommand {
|
public class ItemsCommand extends SWCommand {
|
||||||
|
|
||||||
public ItemsCommand() {
|
public ItemsCommand() {
|
||||||
@@ -46,11 +44,11 @@ public class ItemsCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEnableMessage(){
|
private String getEnableMessage() {
|
||||||
return "REGION_ITEMS_ENABLED";
|
return "REGION_ITEMS_ENABLED";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDisableMessage(){
|
private String getDisableMessage() {
|
||||||
return "REGION_ITEMS_DISABLED";
|
return "REGION_ITEMS_DISABLED";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,12 @@ import de.steamwar.bausystem.region.flags.Flag;
|
|||||||
import de.steamwar.bausystem.region.flags.ItemMode;
|
import de.steamwar.bausystem.region.flags.ItemMode;
|
||||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public class ItemsListener implements Listener, ScoreboardElement {
|
public class ItemsListener implements Listener, ScoreboardElement {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
+2
-2
@@ -97,7 +97,7 @@ public class RegionCommand extends SWCommand {
|
|||||||
@Register(value = "restore", description = "REGION_REGION_HELP_RESTORE")
|
@Register(value = "restore", description = "REGION_REGION_HELP_RESTORE")
|
||||||
public void genericRestoreCommand(@Validator Player p) {
|
public void genericRestoreCommand(@Validator Player p) {
|
||||||
Region region = Region.getRegion(p.getLocation());
|
Region region = Region.getRegion(p.getLocation());
|
||||||
if(checkGlobalRegion(region, p)) return;
|
if (checkGlobalRegion(region, p)) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
|
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
|
||||||
@@ -116,7 +116,7 @@ public class RegionCommand extends SWCommand {
|
|||||||
Region region = Region.getRegion(p.getLocation());
|
Region region = Region.getRegion(p.getLocation());
|
||||||
if (checkGlobalRegion(region, p)) return;
|
if (checkGlobalRegion(region, p)) return;
|
||||||
|
|
||||||
if(node.isDir()) {
|
if (node.isDir()) {
|
||||||
BauSystem.MESSAGE.send("ONLY_SCHEMS", p);
|
BauSystem.MESSAGE.send("ONLY_SCHEMS", p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -59,7 +59,9 @@ public class RegionListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockPhysics(final BlockPhysicsEvent event) {
|
public void onBlockPhysics(final BlockPhysicsEvent event) {
|
||||||
if (event.getBlock().getType() != event.getChangedType()) RegionListener.tagChangedRegion(event.getBlock().getLocation());
|
if (event.getBlock().getType() != event.getChangedType()) {
|
||||||
|
RegionListener.tagChangedRegion(event.getBlock().getLocation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
|||||||
+5
-6
@@ -72,7 +72,7 @@ public class TestblockCommand extends SWCommand {
|
|||||||
resetRegion(p, node, isExtension ? RegionExtensionType.EXTENSION : RegionExtensionType.NORMAL, isIgnoreAir, isOnlyColor, replaceTNT, replaceWater);
|
resetRegion(p, node, isExtension ? RegionExtensionType.EXTENSION : RegionExtensionType.NORMAL, isIgnoreAir, isOnlyColor, replaceTNT, replaceWater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(value="default")
|
@Register(value = "default")
|
||||||
public void setTestblockDefault(Player p) {
|
public void setTestblockDefault(Player p) {
|
||||||
Region region = regionCheck(p);
|
Region region = regionCheck(p);
|
||||||
if (region == null) return;
|
if (region == null) return;
|
||||||
@@ -185,17 +185,16 @@ public class TestblockCommand extends SWCommand {
|
|||||||
return new TypeMapper<SchematicNode>() {
|
return new TypeMapper<SchematicNode>() {
|
||||||
@Override
|
@Override
|
||||||
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||||
List<String> stringList = new ArrayList<>(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
|
List<String> stringList = new ArrayList<>();
|
||||||
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.byId(0), s));
|
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.byId(0), s));
|
||||||
|
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
|
||||||
return stringList;
|
return stringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SchematicNode map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
public SchematicNode map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||||
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
|
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
|
||||||
if (node == null) {
|
if (node == null) node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
|
||||||
node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
|
|
||||||
}
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-2
@@ -33,11 +33,11 @@ public class WaterDestroyCommand extends SWCommand {
|
|||||||
super("waterdestroy");
|
super("waterdestroy");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEnableMessage(){
|
private String getEnableMessage() {
|
||||||
return "REGION_WATER_ENABLED";
|
return "REGION_WATER_ENABLED";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDisableMessage(){
|
private String getDisableMessage() {
|
||||||
return "REGION_WATER_DISABLED";
|
return "REGION_WATER_DISABLED";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -36,7 +36,9 @@ public class WaterDestroyListener implements Listener, ScoreboardElement {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockFromTo(BlockFromToEvent event) {
|
public void onBlockFromTo(BlockFromToEvent event) {
|
||||||
if (event.getBlock().getType() == Material.WATER && event.getToBlock().getType() != Material.AIR && Region.getRegion(event.getBlock().getLocation()).getRegionData().get(Flag.WATER_DESTROY).isWithDefault(WaterDestroyMode.DENY)) event.setCancelled(true);
|
if (event.getBlock().getType() == Material.WATER && event.getToBlock().getType() != Material.AIR && Region.getRegion(event.getBlock().getLocation()).getRegionData().get(Flag.WATER_DESTROY).isWithDefault(WaterDestroyMode.DENY)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class ScriptGUI implements Listener {
|
|||||||
lore.add(BauSystem.MESSAGE.parse("SCRIPT_ERROR_GUI", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length))));
|
lore.add(BauSystem.MESSAGE.parse("SCRIPT_ERROR_GUI", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!lore.isEmpty()) {
|
if (!lore.isEmpty()) {
|
||||||
lore.add("");
|
lore.add("");
|
||||||
}
|
}
|
||||||
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_1", player));
|
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_1", player));
|
||||||
@@ -75,16 +75,17 @@ public class ScriptGUI implements Listener {
|
|||||||
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_3", player));
|
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_3", player));
|
||||||
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_4", player));
|
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_4", player));
|
||||||
|
|
||||||
entries.add(new SWListInv.SWListEntry<>(new SWItem(Material.ENCHANTED_BOOK, script.getName(), new ArrayList<>(lore), false, clickType -> {}), script));
|
entries.add(new SWListInv.SWListEntry<>(new SWItem(Material.ENCHANTED_BOOK, script.getName(), new ArrayList<>(lore), false, clickType -> {
|
||||||
|
}), script));
|
||||||
lore.clear();
|
lore.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
SWListInv<Script> inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_NAME", player), false, entries, (clickType, script) -> {
|
SWListInv<Script> inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_NAME", player), false, entries, (clickType, script) -> {
|
||||||
ItemStack itemStack = ScriptHelper.getScriptItem(script, clickType.isRightClick());
|
ItemStack itemStack = ScriptHelper.getScriptItem(script, clickType.isRightClick());
|
||||||
|
|
||||||
if(clickType == ClickType.MIDDLE) {
|
if (clickType == ClickType.MIDDLE) {
|
||||||
player.openBook(itemStack);
|
player.openBook(itemStack);
|
||||||
} else if(!clickType.isShiftClick()) {
|
} else if (!clickType.isShiftClick()) {
|
||||||
script.delete();
|
script.delete();
|
||||||
ScriptRunner.updateGlobalScript(player);
|
ScriptRunner.updateGlobalScript(player);
|
||||||
open(player, itemStack);
|
open(player, itemStack);
|
||||||
@@ -93,14 +94,14 @@ public class ScriptGUI implements Listener {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
inv.setItem(49, Material.HOPPER, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_LORE", player)), false, click -> {
|
inv.setItem(49, Material.HOPPER, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_LORE", player)), false, click -> {
|
||||||
if(player.getOpenInventory().getCursor() != null) {
|
if (player.getOpenInventory().getCursor() != null) {
|
||||||
ItemStack cursor = player.getOpenInventory().getCursor();
|
ItemStack cursor = player.getOpenInventory().getCursor();
|
||||||
if(!(cursor.getItemMeta() instanceof BookMeta)) {
|
if (!(cursor.getItemMeta() instanceof BookMeta)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BookMeta meta = (BookMeta) cursor.getItemMeta();
|
BookMeta meta = (BookMeta) cursor.getItemMeta();
|
||||||
if(meta == null) {
|
if (meta == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,14 +109,14 @@ public class ScriptGUI implements Listener {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
inv.open();
|
inv.open();
|
||||||
if(setCursor != null) {
|
if (setCursor != null) {
|
||||||
player.getOpenInventory().setCursor(setCursor);
|
player.getOpenInventory().setCursor(setCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void saveWithName(Player player, BookMeta meta, String name) {
|
private static void saveWithName(Player player, BookMeta meta, String name) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
if(name != null && Script.list(user).stream().noneMatch(script -> script.getName().equalsIgnoreCase(name))) {
|
if (name != null && Script.list(user).stream().noneMatch(script -> script.getName().equalsIgnoreCase(name))) {
|
||||||
Script.create(user, name, ScriptHelper.getScriptString(meta.getPages()));
|
Script.create(user, name, ScriptHelper.getScriptString(meta.getPages()));
|
||||||
player.getOpenInventory().setCursor(null);
|
player.getOpenInventory().setCursor(null);
|
||||||
ScriptRunner.updateGlobalScript(player);
|
ScriptRunner.updateGlobalScript(player);
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ public class ScriptHelper {
|
|||||||
public static ItemStack getScriptItem(Script script, boolean writeable) {
|
public static ItemStack getScriptItem(Script script, boolean writeable) {
|
||||||
ItemStack itemStack = new ItemStack(writeable ? Material.WRITABLE_BOOK : Material.WRITTEN_BOOK);
|
ItemStack itemStack = new ItemStack(writeable ? Material.WRITABLE_BOOK : Material.WRITTEN_BOOK);
|
||||||
BookMeta meta = (BookMeta) itemStack.getItemMeta();
|
BookMeta meta = (BookMeta) itemStack.getItemMeta();
|
||||||
if(!writeable) {
|
if (!writeable) {
|
||||||
meta.setTitle(script.getName());
|
meta.setTitle(script.getName());
|
||||||
meta.setAuthor(SteamwarUser.byId(script.getUserId()).getUserName());
|
meta.setAuthor(SteamwarUser.byId(script.getUserId()).getUserName());
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -44,7 +44,7 @@ public class ScriptListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
public void onLeftClick(PlayerInteractEvent event) {
|
public void onLeftClick(PlayerInteractEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
|
|
||||||
ItemStack item = event.getItem();
|
ItemStack item = event.getItem();
|
||||||
if (item == null || FlatteningWrapper.impl.isNoBook(item) || item.getItemMeta() == null) {
|
if (item == null || FlatteningWrapper.impl.isNoBook(item) || item.getItemMeta() == null) {
|
||||||
@@ -72,7 +72,7 @@ public class ScriptListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
ScriptRunner.updateGlobalScript(event.getPlayer());
|
ScriptRunner.updateGlobalScript(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ public class ScriptRunner {
|
|||||||
.orElse(Collections.emptyMap())
|
.orElse(Collections.emptyMap())
|
||||||
.getOrDefault(event, Collections.emptyList());
|
.getOrDefault(event, Collections.emptyList());
|
||||||
if (luaFunctions.isEmpty()) {
|
if (luaFunctions.isEmpty()) {
|
||||||
if(event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) {
|
if (event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) {
|
||||||
player.performCommand("gui");
|
player.performCommand("gui");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ public class CommandListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||||
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
String[] split = event.getMessage().split(" ");
|
String[] split = event.getMessage().split(" ");
|
||||||
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
|
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
|
||||||
if (scriptData.getCalledCommands().contains(split[0])) return;
|
if (scriptData.getCalledCommands().contains(split[0])) return;
|
||||||
|
|||||||
+3
-3
@@ -26,10 +26,10 @@ import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
|
|||||||
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
|
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.core.SWPlayer;
|
import de.steamwar.core.SWPlayer;
|
||||||
import de.steamwar.core.TrickyTrialsWrapper;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
@@ -141,7 +141,7 @@ public class EventListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
public void onEntitySpawn(EntitySpawnEvent event) {
|
public void onEntitySpawn(EntitySpawnEvent event) {
|
||||||
if (event.getEntityType() != TrickyTrialsWrapper.impl.getTntEntityType()) {
|
if (event.getEntityType() != EntityType.TNT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Region tntRegion = Region.getRegion(event.getLocation());
|
Region tntRegion = Region.getRegion(event.getLocation());
|
||||||
@@ -156,7 +156,7 @@ public class EventListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onEntityExplode(EntityExplodeEvent event) {
|
public void onEntityExplode(EntityExplodeEvent event) {
|
||||||
if (event.getEntityType() != TrickyTrialsWrapper.impl.getTntEntityType()) {
|
if (event.getEntityType() != EntityType.TNT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Region tntRegion = Region.getRegion(event.getLocation());
|
Region tntRegion = Region.getRegion(event.getLocation());
|
||||||
|
|||||||
+15
-7
@@ -72,7 +72,7 @@ public interface LuaLib {
|
|||||||
|
|
||||||
default LuaTable toPos(Point point) {
|
default LuaTable toPos(Point point) {
|
||||||
if (point == null) return LuaTable.tableOf();
|
if (point == null) return LuaTable.tableOf();
|
||||||
return LuaValue.tableOf(new LuaValue[] {
|
return LuaValue.tableOf(new LuaValue[]{
|
||||||
LuaValue.valueOf("x"), LuaValue.valueOf(point.getX()),
|
LuaValue.valueOf("x"), LuaValue.valueOf(point.getX()),
|
||||||
LuaValue.valueOf("y"), LuaValue.valueOf(point.getY()),
|
LuaValue.valueOf("y"), LuaValue.valueOf(point.getY()),
|
||||||
LuaValue.valueOf("z"), LuaValue.valueOf(point.getZ())
|
LuaValue.valueOf("z"), LuaValue.valueOf(point.getZ())
|
||||||
@@ -82,7 +82,9 @@ public interface LuaLib {
|
|||||||
default Class<? extends LuaLib> parent() {
|
default Class<? extends LuaLib> parent() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String name();
|
String name();
|
||||||
|
|
||||||
LuaTable get(Player player);
|
LuaTable get(Player player);
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -103,27 +105,33 @@ public interface LuaLib {
|
|||||||
try {
|
try {
|
||||||
consumer.accept(luaValue.toboolean());
|
consumer.accept(luaValue.toboolean());
|
||||||
return NIL;
|
return NIL;
|
||||||
} catch (Exception ingored) {}
|
} catch (Exception ingored) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
consumer.accept((long) luaValue.toint());
|
consumer.accept((long) luaValue.toint());
|
||||||
return NIL;
|
return NIL;
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
consumer.accept(luaValue.toint());
|
consumer.accept(luaValue.toint());
|
||||||
return NIL;
|
return NIL;
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
consumer.accept(luaValue.todouble());
|
consumer.accept(luaValue.todouble());
|
||||||
return NIL;
|
return NIL;
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
consumer.accept((float) luaValue.todouble());
|
consumer.accept((float) luaValue.todouble());
|
||||||
return NIL;
|
return NIL;
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
consumer.accept(luaValue.toString());
|
consumer.accept(luaValue.toString());
|
||||||
return NIL;
|
return NIL;
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
throw new LuaError("Invalid lua type: " + luaValue.typename());
|
throw new LuaError("Invalid lua type: " + luaValue.typename());
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
throw new LuaError("Error in '" + name + "' " + throwable.getMessage());
|
throw new LuaError("Error in '" + name + "' " + throwable.getMessage());
|
||||||
|
|||||||
+33
-18
@@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.script.lua.libs;
|
|||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.region.RegionSystem;
|
import de.steamwar.bausystem.region.RegionSystem;
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.api.Disable;
|
import de.steamwar.linkage.api.Disable;
|
||||||
import de.steamwar.linkage.api.Enable;
|
import de.steamwar.linkage.api.Enable;
|
||||||
@@ -56,7 +55,6 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
if (Core.getVersion() <= 15) return;
|
|
||||||
if (!storageDirectory.exists()) storageDirectory.mkdirs();
|
if (!storageDirectory.exists()) storageDirectory.mkdirs();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -64,7 +62,8 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
jsonObject.keySet().forEach(key -> {
|
jsonObject.keySet().forEach(key -> {
|
||||||
GLOBAL_STORAGE.put(key, fromJson(jsonObject.get(key)));
|
GLOBAL_STORAGE.put(key, fromJson(jsonObject.get(key)));
|
||||||
});
|
});
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
File regionStorageDirectory = new File(storageDirectory, "region");
|
File regionStorageDirectory = new File(storageDirectory, "region");
|
||||||
regionStorageDirectory.mkdirs();
|
regionStorageDirectory.mkdirs();
|
||||||
@@ -77,7 +76,8 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
});
|
});
|
||||||
Region region = RegionSystem.INSTANCE.getRegion(UUID.fromString(regionStorage.getName().substring(0, regionStorage.getName().length() - ".json".length()))).orElse(null);
|
Region region = RegionSystem.INSTANCE.getRegion(UUID.fromString(regionStorage.getName().substring(0, regionStorage.getName().length() - ".json".length()))).orElse(null);
|
||||||
REGION_STORAGE.put(region, map);
|
REGION_STORAGE.put(region, map);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File playerStorageDirectory = new File(storageDirectory, "player");
|
File playerStorageDirectory = new File(storageDirectory, "player");
|
||||||
@@ -91,7 +91,8 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
});
|
});
|
||||||
SteamwarUser steamwarUser = SteamwarUser.byId(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
|
SteamwarUser steamwarUser = SteamwarUser.byId(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
|
||||||
PLAYER_STORAGE.put(steamwarUser.getUUID(), map);
|
PLAYER_STORAGE.put(steamwarUser.getUUID(), map);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,10 +108,12 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
if (jsonPrimitive.isNumber()) {
|
if (jsonPrimitive.isNumber()) {
|
||||||
try {
|
try {
|
||||||
return LuaValue.valueOf(jsonPrimitive.getAsInt());
|
return LuaValue.valueOf(jsonPrimitive.getAsInt());
|
||||||
} catch (NumberFormatException e) {}
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return LuaValue.valueOf(jsonPrimitive.getAsDouble());
|
return LuaValue.valueOf(jsonPrimitive.getAsDouble());
|
||||||
} catch (NumberFormatException e) {}
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (jsonPrimitive.isString()) {
|
if (jsonPrimitive.isString()) {
|
||||||
return LuaValue.valueOf(jsonPrimitive.getAsString());
|
return LuaValue.valueOf(jsonPrimitive.getAsString());
|
||||||
@@ -132,13 +135,13 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
if (Core.getVersion() <= 15) return;
|
|
||||||
if (!storageDirectory.exists()) storageDirectory.mkdirs();
|
if (!storageDirectory.exists()) storageDirectory.mkdirs();
|
||||||
try {
|
try {
|
||||||
FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json"));
|
FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json"));
|
||||||
gson.toJson(toJson(GLOBAL_STORAGE), fileWriter);
|
gson.toJson(toJson(GLOBAL_STORAGE), fileWriter);
|
||||||
fileWriter.close();
|
fileWriter.close();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
|
||||||
File regionStorageDirectory = new File(storageDirectory, "region");
|
File regionStorageDirectory = new File(storageDirectory, "region");
|
||||||
regionStorageDirectory.mkdirs();
|
regionStorageDirectory.mkdirs();
|
||||||
@@ -147,7 +150,8 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
FileWriter fileWriter = new FileWriter(new File(regionStorageDirectory, entry.getKey().getID().toString() + ".json"));
|
FileWriter fileWriter = new FileWriter(new File(regionStorageDirectory, entry.getKey().getID().toString() + ".json"));
|
||||||
gson.toJson(toJson(entry.getValue()), fileWriter);
|
gson.toJson(toJson(entry.getValue()), fileWriter);
|
||||||
fileWriter.close();
|
fileWriter.close();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File playerStorageDirectory = new File(storageDirectory, "player");
|
File playerStorageDirectory = new File(storageDirectory, "player");
|
||||||
@@ -157,7 +161,8 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
FileWriter fileWriter = new FileWriter(new File(playerStorageDirectory, SteamwarUser.get(entry.getKey()).getId() + ".json"));
|
FileWriter fileWriter = new FileWriter(new File(playerStorageDirectory, SteamwarUser.get(entry.getKey()).getId() + ".json"));
|
||||||
gson.toJson(toJson(entry.getValue()), fileWriter);
|
gson.toJson(toJson(entry.getValue()), fileWriter);
|
||||||
fileWriter.close();
|
fileWriter.close();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,13 +182,16 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return new JsonPrimitive(luaValue.checkboolean());
|
return new JsonPrimitive(luaValue.checkboolean());
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return new JsonPrimitive(luaValue.checkint());
|
return new JsonPrimitive(luaValue.checkint());
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return new JsonPrimitive(luaValue.checkdouble());
|
return new JsonPrimitive(luaValue.checkdouble());
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
if (luaValue.isstring()) {
|
if (luaValue.isstring()) {
|
||||||
return new JsonPrimitive(luaValue.tojstring());
|
return new JsonPrimitive(luaValue.tojstring());
|
||||||
@@ -196,7 +204,8 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
if (value == null) continue;
|
if (value == null) continue;
|
||||||
try {
|
try {
|
||||||
jsonObject.add(key.checkjstring(), value);
|
jsonObject.add(key.checkjstring(), value);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
@@ -252,7 +261,9 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
});
|
});
|
||||||
storageLib.set("global", global);
|
storageLib.set("global", global);
|
||||||
|
|
||||||
@@ -297,7 +308,9 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
});
|
});
|
||||||
storageLib.set("player", playerStorage);
|
storageLib.set("player", playerStorage);
|
||||||
|
|
||||||
@@ -346,7 +359,9 @@ public class StorageLib implements LuaLib, Enable, Disable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
});
|
});
|
||||||
storageLib.set("region", regionStorage);
|
storageLib.set("region", regionStorage);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ public class WorldEditLib implements LuaLib {
|
|||||||
return selection;
|
return selection;
|
||||||
}, o -> {
|
}, o -> {
|
||||||
LuaTable selection = o.checktable();
|
LuaTable selection = o.checktable();
|
||||||
if(selection.length() != 2) {
|
if (selection.length() != 2) {
|
||||||
throw new IllegalArgumentException("selection must have exactly 2 elements");
|
throw new IllegalArgumentException("selection must have exactly 2 elements");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -26,7 +26,9 @@ import org.bukkit.entity.Player;
|
|||||||
public interface BlockDataConfiguration<T extends BlockData> {
|
public interface BlockDataConfiguration<T extends BlockData> {
|
||||||
|
|
||||||
void previous();
|
void previous();
|
||||||
|
|
||||||
void next();
|
void next();
|
||||||
|
|
||||||
SWItem get(Player player);
|
SWItem get(Player player);
|
||||||
|
|
||||||
void apply(T copied, T worldOriginal);
|
void apply(T copied, T worldOriginal);
|
||||||
|
|||||||
-2
@@ -29,14 +29,12 @@ import de.steamwar.command.TypeMapper;
|
|||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.LinkedInstance;
|
import de.steamwar.linkage.LinkedInstance;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public class SimulatorCommand extends SWCommand {
|
public class SimulatorCommand extends SWCommand {
|
||||||
|
|
||||||
@LinkedInstance
|
@LinkedInstance
|
||||||
|
|||||||
+104
-209
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.simulator;
|
package de.steamwar.bausystem.features.simulator;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.SWUtils;
|
import de.steamwar.bausystem.SWUtils;
|
||||||
@@ -38,79 +38,88 @@ import de.steamwar.bausystem.features.simulator.gui.SimulatorGui;
|
|||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||||
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
||||||
import de.steamwar.bausystem.utils.ItemUtils;
|
import de.steamwar.bausystem.utils.ItemUtils;
|
||||||
import de.steamwar.bausystem.utils.RayTraceUtils;
|
import de.steamwar.core.SWPlayer;
|
||||||
|
import de.steamwar.cursor.Cursor;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
|
||||||
import de.steamwar.inventory.SWAnvilInv;
|
import de.steamwar.inventory.SWAnvilInv;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||||
import org.bukkit.event.player.*;
|
import org.bukkit.event.player.*;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public class SimulatorCursor implements Listener {
|
public class SimulatorCursor implements Listener {
|
||||||
|
|
||||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
private static final Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
private static final Map<Player, REntityServer> emptyTargetServers = Collections.synchronizedMap(new HashMap<>());
|
||||||
private static Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
|
||||||
private static Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
|
|
||||||
private static final Set<Player> calculating = new HashSet<>();
|
|
||||||
|
|
||||||
public static boolean isSimulatorItem(ItemStack itemStack) {
|
public static boolean isSimulatorItem(ItemStack itemStack) {
|
||||||
return ItemUtils.isItem(itemStack, "simulator");
|
return ItemUtils.isItem(itemStack, "simulator");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimulatorCursor() {
|
private static boolean hasSimulatorItem(Player player) {
|
||||||
BiFunction<Player, Object, Object> function = (player, object) -> {
|
return isSimulatorItem(player.getInventory().getItemInMainHand()) || isSimulatorItem(player.getInventory().getItemInOffHand());
|
||||||
calcCursor(player);
|
}
|
||||||
return object;
|
|
||||||
};
|
private static Set<Player> scheduledUpdates = new HashSet<>();
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, function);
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Rot.class, function);
|
private static void scheduleCursorUpdate(Player player) {
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, function);
|
scheduledUpdates.add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onServerTickEnd(ServerTickEndEvent event) {
|
||||||
|
scheduledUpdates.forEach(SimulatorCursor::calcCursor);
|
||||||
|
scheduledUpdates.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
scheduleCursorUpdate(event.getPlayer());
|
||||||
calcCursor(event.getPlayer());
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
calcCursor(event.getPlayer());
|
scheduleCursorUpdate(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
scheduleCursorUpdate(event.getPlayer());
|
||||||
calcCursor(event.getPlayer());
|
}
|
||||||
}, 1);
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(InventoryClickEvent event) {
|
||||||
|
if (!(event.getWhoClicked() instanceof Player player)) return;
|
||||||
|
if (!Permission.BUILD.hasPermission(player)) return;
|
||||||
|
scheduleCursorUpdate(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryDrag(InventoryDragEvent event) {
|
||||||
|
if (!(event.getWhoClicked() instanceof Player player)) return;
|
||||||
|
if (!Permission.BUILD.hasPermission(player)) return;
|
||||||
|
scheduleCursorUpdate(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -121,10 +130,8 @@ public class SimulatorCursor implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
cursorType.remove(event.getPlayer());
|
cursorType.remove(event.getPlayer());
|
||||||
cursors.remove(event.getPlayer());
|
removeCursor(event.getPlayer());
|
||||||
synchronized (calculating) {
|
scheduledUpdates.remove(event.getPlayer());
|
||||||
calculating.remove(event.getPlayer());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
|
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
|
||||||
@@ -140,7 +147,7 @@ public class SimulatorCursor implements Listener {
|
|||||||
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
|
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
|
||||||
if (!event.isSneaking()) return;
|
if (!event.isSneaking()) return;
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) {
|
if (!hasSimulatorItem(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (LAST_SNEAKS.containsKey(player)) {
|
if (LAST_SNEAKS.containsKey(player)) {
|
||||||
@@ -166,17 +173,10 @@ public class SimulatorCursor implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void calcCursor(Player player) {
|
public static void calcCursor(Player player) {
|
||||||
synchronized (calculating) {
|
if (!Permission.BUILD.hasPermission(player) || !hasSimulatorItem(player)) {
|
||||||
if (calculating.contains(player)) return;
|
if (removeCursor(player) | SimulatorWatcher.show(null, player)) {
|
||||||
calculating.add(player);
|
|
||||||
}
|
|
||||||
if (!Permission.BUILD.hasPermission(player) || (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand()))) {
|
|
||||||
if (removeCursor(player) || SimulatorWatcher.show(null, player)) {
|
|
||||||
SWUtils.sendToActionbar(player, "");
|
SWUtils.sendToActionbar(player, "");
|
||||||
}
|
}
|
||||||
synchronized (calculating) {
|
|
||||||
calculating.remove(player);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,202 +185,98 @@ public class SimulatorCursor implements Listener {
|
|||||||
removeCursor(player);
|
removeCursor(player);
|
||||||
SimulatorWatcher.show(null, player);
|
SimulatorWatcher.show(null, player);
|
||||||
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
||||||
synchronized (calculating) {
|
|
||||||
calculating.remove(player);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatorWatcher.show(simulator, player);
|
SimulatorWatcher.show(simulator, player);
|
||||||
List<REntity> entities = SimulatorWatcher.getEntitiesOfSimulator(simulator);
|
Cursor cursor = getOrCreateCursor(player, simulator, cursorType.getOrDefault(player, CursorType.TNT));
|
||||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities);
|
cursor.renderDeduplicated();
|
||||||
if (rayTraceResult == null) {
|
|
||||||
removeCursor(player);
|
|
||||||
if (simulator == null) {
|
|
||||||
SWUtils.sendToActionbar(player, "§eSelect Simulator");
|
|
||||||
} else {
|
|
||||||
SWUtils.sendToActionbar(player, "§eOpen Simulator");
|
|
||||||
}
|
|
||||||
synchronized (calculating) {
|
|
||||||
calculating.remove(player);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showCursor(player, rayTraceResult, simulator != null);
|
private static Cursor getOrCreateCursor(Player player, Simulator simulator, CursorType type) {
|
||||||
synchronized (calculating) {
|
REntityServer targetServer = simulator == null ? emptyTargetServers.computeIfAbsent(player, __ -> new REntityServer()) : SimulatorWatcher.getEntityServerOfSimulator(simulator);
|
||||||
calculating.remove(player);
|
SWPlayer swPlayer = SWPlayer.of(player);
|
||||||
|
Optional<Cursor> activeCursor = swPlayer.getComponent(Cursor.class);
|
||||||
|
|
||||||
|
Cursor cursor = activeCursor.orElse(null);
|
||||||
|
if (cursor == null || cursor.getTargetServer() != targetServer) {
|
||||||
|
swPlayer.removeComponent(Cursor.class);
|
||||||
|
cursor = new Cursor(
|
||||||
|
targetServer,
|
||||||
|
player,
|
||||||
|
Material.GLASS,
|
||||||
|
type.material,
|
||||||
|
type.cursorModes,
|
||||||
|
(location, hitEntity, action) -> handlePlayerClick(player, location, hitEntity, action),
|
||||||
|
(location, hitEntity) -> sendCursorActionbar(player, SimulatorStorage.getSimulator(player), location != null, hitEntity.isPresent())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cursor.setCursorMaterial(type.material);
|
||||||
|
cursor.setAllowedCursorModes(type.cursorModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized boolean removeCursor(Player player) {
|
private static synchronized boolean removeCursor(Player player) {
|
||||||
REntityServer entityServer = cursors.get(player);
|
Optional<Cursor> cursor = SWPlayer.of(player).getComponent(Cursor.class);
|
||||||
boolean hadCursor = entityServer != null && !entityServer.getEntities().isEmpty();
|
cursor.ifPresent(__ -> SWPlayer.of(player).removeComponent(Cursor.class));
|
||||||
if (entityServer != null) {
|
REntityServer emptyTargetServer = emptyTargetServers.remove(player);
|
||||||
entityServer.getEntities().forEach(REntity::die);
|
if (emptyTargetServer != null) {
|
||||||
|
emptyTargetServer.close();
|
||||||
}
|
}
|
||||||
return hadCursor;
|
return cursor.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, boolean hasSimulatorSelected) {
|
private static void sendCursorActionbar(Player player, Simulator simulator, boolean hasCursorLocation, boolean hasHitEntity) {
|
||||||
REntityServer entityServer = cursors.computeIfAbsent(player, __ -> {
|
if (!hasCursorLocation) {
|
||||||
REntityServer rEntityServer = new REntityServer();
|
SWUtils.sendToActionbar(player, simulator == null ? "§eSelect Simulator" : "§eOpen Simulator");
|
||||||
rEntityServer.addPlayer(player);
|
} else if (simulator == null) {
|
||||||
return rEntityServer;
|
SWUtils.sendToActionbar(player, "§eCreate new Simulator");
|
||||||
});
|
} else if (hasHitEntity) {
|
||||||
|
|
||||||
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
|
||||||
REntity hitEntity = rayTraceResult.getHitEntity();
|
|
||||||
Location location = hitEntity != null ? new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD) :
|
|
||||||
type.position.apply(player, rayTraceResult).toLocation(WORLD);
|
|
||||||
|
|
||||||
Material material = hitEntity != null ? Material.GLASS : type.getMaterial();
|
|
||||||
List<RFallingBlockEntity> entities = entityServer.getEntitiesByType(RFallingBlockEntity.class);
|
|
||||||
entities.removeIf(rFallingBlockEntity -> {
|
|
||||||
if (rFallingBlockEntity.getMaterial() != material) {
|
|
||||||
rFallingBlockEntity.die();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
rFallingBlockEntity.move(location);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
if (entities.isEmpty()) {
|
|
||||||
RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(entityServer, location, material);
|
|
||||||
rFallingBlockEntity.setNoGravity(true);
|
|
||||||
if (material == Material.GLASS) {
|
|
||||||
rFallingBlockEntity.setGlowing(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasSimulatorSelected) {
|
|
||||||
if (hitEntity != null) {
|
|
||||||
SWUtils.sendToActionbar(player, "§eEdit Position");
|
SWUtils.sendToActionbar(player, "§eEdit Position");
|
||||||
} else {
|
} else {
|
||||||
SWUtils.sendToActionbar(player, "§eAdd new " + type.name);
|
SWUtils.sendToActionbar(player, "§eAdd new " + cursorType.getOrDefault(player, CursorType.TNT).name);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
SWUtils.sendToActionbar(player, "§eCreate new Simulator");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector getPosFree(Player player, RayTraceUtils.RRayTraceResult result) {
|
|
||||||
Vector pos = result.getHitPosition();
|
|
||||||
|
|
||||||
BlockFace face = result.getHitBlockFace();
|
|
||||||
if (face != null) {
|
|
||||||
switch (face) {
|
|
||||||
case DOWN:
|
|
||||||
pos.setY(pos.getY() - 0.98);
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
pos.setX(pos.getX() + 0.49);
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
pos.setX(pos.getX() - 0.49);
|
|
||||||
break;
|
|
||||||
case NORTH:
|
|
||||||
pos.setZ(pos.getZ() - 0.49);
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
pos.setZ(pos.getZ() + 0.49);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (face.getModY() == 0 && player.isSneaking()) {
|
|
||||||
pos.setY(pos.getY() - 0.49);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!player.isSneaking()) {
|
|
||||||
pos.setX(pos.getBlockX() + 0.5);
|
|
||||||
if (face == null || face.getModY() == 0)
|
|
||||||
pos.setY(pos.getBlockY() + 0.0);
|
|
||||||
pos.setZ(pos.getBlockZ() + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Vector getPosBlockAligned(Player player, RayTraceUtils.RRayTraceResult result) {
|
|
||||||
Vector pos = result.getHitPosition();
|
|
||||||
|
|
||||||
BlockFace face = result.getHitBlockFace();
|
|
||||||
if (face != null) {
|
|
||||||
switch (face) {
|
|
||||||
case DOWN:
|
|
||||||
pos.setY(pos.getY() - 0.98);
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
pos.setX(pos.getX() + 0.49);
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
pos.setX(pos.getX() - 0.49);
|
|
||||||
break;
|
|
||||||
case NORTH:
|
|
||||||
pos.setZ(pos.getZ() - 0.49);
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
pos.setZ(pos.getZ() + 0.49);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.setX(pos.getBlockX() + 0.5);
|
|
||||||
if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) {
|
|
||||||
pos.setY(pos.getBlockY() + 1.0);
|
|
||||||
} else {
|
|
||||||
pos.setY(pos.getBlockY());
|
|
||||||
}
|
|
||||||
pos.setZ(pos.getBlockZ() + 0.5);
|
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum CursorType {
|
public enum CursorType {
|
||||||
TNT(Material.TNT, Material.GUNPOWDER, SimulatorCursor::getPosFree, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
|
TNT(Material.TNT, Material.GUNPOWDER, List.of(Cursor.CursorMode.FREE, Cursor.CursorMode.SURFACE_ALIGNED), "TNT", vector -> new TNTElement(vector).add(new TNTPhase())),
|
||||||
REDSTONE_BLOCK(Material.REDSTONE_BLOCK, Material.REDSTONE, SimulatorCursor::getPosBlockAligned, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
|
REDSTONE_BLOCK(Material.REDSTONE_BLOCK, Material.REDSTONE, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())),
|
||||||
OBSERVER(Material.OBSERVER, Material.QUARTZ, SimulatorCursor::getPosBlockAligned, "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())),
|
OBSERVER(Material.OBSERVER, Material.QUARTZ, List.of(Cursor.CursorMode.BLOCK_ALIGNED), "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())),
|
||||||
;
|
;
|
||||||
|
|
||||||
public final Material material;
|
public final Material material;
|
||||||
public final Material nonSelectedMaterial;
|
public final Material nonSelectedMaterial;
|
||||||
public final BiFunction<Player, RayTraceUtils.RRayTraceResult, Vector> position;
|
public final List<Cursor.CursorMode> cursorModes;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final Function<Vector, SimulatorElement<?>> elementFunction;
|
public final Function<Vector, SimulatorElement<?>> elementFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
private static void handlePlayerClick(Player player, Location cursorLocation, Optional<REntity> hitEntity, Action action) {
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
if (!Permission.BUILD.hasPermission(player)) return;
|
||||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
if (!hasSimulatorItem(player)) {
|
||||||
if (!ItemUtils.isItem(event.getItem(), "simulator")) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
Simulator simulator = SimulatorStorage.getSimulator(player);
|
Simulator simulator = SimulatorStorage.getSimulator(player);
|
||||||
|
|
||||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
|
if (action == Action.LEFT_CLICK_BLOCK || action == Action.LEFT_CLICK_AIR) {
|
||||||
if (simulator == null) {
|
if (simulator == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SimulatorExecutor.run(event.getPlayer(), simulator, null);
|
SimulatorExecutor.run(player, simulator, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) {
|
if (action != Action.RIGHT_CLICK_BLOCK && action != Action.RIGHT_CLICK_AIR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), SimulatorWatcher.getEntitiesOfSimulator(simulator));
|
|
||||||
if (simulator == null) {
|
if (simulator == null) {
|
||||||
if (rayTraceResult == null) {
|
if (cursorLocation == null) {
|
||||||
SimulatorStorage.openSimulatorSelector(player);
|
SimulatorStorage.openSimulatorSelector(player);
|
||||||
} else {
|
} else {
|
||||||
SWAnvilInv anvilInv = new SWAnvilInv(player, "Name");
|
SWAnvilInv anvilInv = new SWAnvilInv(player, "Name");
|
||||||
@@ -396,7 +292,7 @@ public class SimulatorCursor implements Listener {
|
|||||||
}
|
}
|
||||||
sim = new Simulator(s);
|
sim = new Simulator(s);
|
||||||
SimulatorStorage.addSimulator(s, sim);
|
SimulatorStorage.addSimulator(s, sim);
|
||||||
createElement(player, rayTraceResult, sim);
|
createElement(player, cursorLocation, sim);
|
||||||
SimulatorStorage.setSimulator(player, sim);
|
SimulatorStorage.setSimulator(player, sim);
|
||||||
});
|
});
|
||||||
anvilInv.open();
|
anvilInv.open();
|
||||||
@@ -404,13 +300,20 @@ public class SimulatorCursor implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayTraceResult == null) {
|
if (cursorLocation == null) {
|
||||||
new SimulatorGui(player, simulator).open();
|
new SimulatorGui(player, simulator).open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rayTraceResult.getHitEntity() != null) {
|
if (hitEntity.isPresent()) {
|
||||||
REntity hitEntity = rayTraceResult.getHitEntity();
|
openElement(player, simulator, hitEntity.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createElement(player, cursorLocation, simulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void openElement(Player player, Simulator simulator, REntity hitEntity) {
|
||||||
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
|
Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ());
|
||||||
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
|
List<SimulatorElement<?>> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> {
|
||||||
return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0);
|
return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0);
|
||||||
@@ -420,7 +323,6 @@ public class SimulatorCursor implements Listener {
|
|||||||
case 0:
|
case 0:
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
// Open single element present in Simulator
|
|
||||||
SimulatorElement<?> element = elements.get(0);
|
SimulatorElement<?> element = elements.get(0);
|
||||||
SimulatorGroup group1 = element.getGroup(simulator);
|
SimulatorGroup group1 = element.getGroup(simulator);
|
||||||
SimulatorBaseGui back = new SimulatorGui(player, simulator);
|
SimulatorBaseGui back = new SimulatorGui(player, simulator);
|
||||||
@@ -432,11 +334,9 @@ public class SimulatorCursor implements Listener {
|
|||||||
default:
|
default:
|
||||||
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
|
List<SimulatorGroup> parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList());
|
||||||
if (parents.size() == 1) {
|
if (parents.size() == 1) {
|
||||||
// Open multi element present in Simulator in existing group
|
|
||||||
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
|
SimulatorGui simulatorGui = new SimulatorGui(player, simulator);
|
||||||
new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open();
|
new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open();
|
||||||
} else {
|
} else {
|
||||||
// Open multi element present in Simulator in implicit group
|
|
||||||
SimulatorGroup group2 = new SimulatorGroup();
|
SimulatorGroup group2 = new SimulatorGroup();
|
||||||
group2.setMaterial(null);
|
group2.setMaterial(null);
|
||||||
group2.getElements().addAll(elements);
|
group2.getElements().addAll(elements);
|
||||||
@@ -445,16 +345,11 @@ public class SimulatorCursor implements Listener {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new Element to current simulator
|
private static void createElement(Player player, Location cursorLocation, Simulator simulator) {
|
||||||
createElement(player, rayTraceResult, simulator);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createElement(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, Simulator simulator) {
|
|
||||||
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
CursorType type = cursorType.getOrDefault(player, CursorType.TNT);
|
||||||
Vector vector = type.position.apply(player, rayTraceResult);
|
Vector vector = cursorLocation.toVector();
|
||||||
if (type == CursorType.REDSTONE_BLOCK) {
|
if (type == CursorType.REDSTONE_BLOCK) {
|
||||||
vector.subtract(new Vector(0.5, 0, 0.5));
|
vector.subtract(new Vector(0.5, 0, 0.5));
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -32,7 +32,6 @@ import de.steamwar.bausystem.utils.ItemUtils;
|
|||||||
import de.steamwar.inventory.SWAnvilInv;
|
import de.steamwar.inventory.SWAnvilInv;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import de.steamwar.linkage.api.Enable;
|
import de.steamwar.linkage.api.Enable;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -47,7 +46,6 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public class SimulatorStorage implements Enable {
|
public class SimulatorStorage implements Enable {
|
||||||
|
|
||||||
public static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators");
|
public static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators");
|
||||||
|
|||||||
+7
-2
@@ -28,7 +28,6 @@ import de.steamwar.entity.REntity;
|
|||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import de.steamwar.entity.RFallingBlockEntity;
|
import de.steamwar.entity.RFallingBlockEntity;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -75,7 +74,6 @@ public class SimulatorWatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public static class QuitListener implements Listener {
|
public static class QuitListener implements Listener {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -126,4 +124,11 @@ public class SimulatorWatcher {
|
|||||||
}
|
}
|
||||||
return entityServer.getEntities();
|
return entityServer.getEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized REntityServer getEntityServerOfSimulator(Simulator simulator) {
|
||||||
|
if (simulator == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return entityServers.computeIfAbsent(simulator, __ -> createSim(new REntityServer(), simulator));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.simulator.data;
|
|||||||
|
|
||||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||||
|
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||||
import de.steamwar.inventory.InvCallback;
|
import de.steamwar.inventory.InvCallback;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -28,7 +29,6 @@ import lombok.Setter;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -120,6 +120,10 @@ public abstract class SimulatorElement<T extends SimulatorPhase> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract String getType();
|
public abstract String getType();
|
||||||
public void saveExtra(YAPIONObject elementObject) {}
|
|
||||||
public void loadExtra(YAPIONObject elementObject) {}
|
public void saveExtra(SimulatorConfig.Element element) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadExtra(SimulatorConfig.Element element) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -20,10 +20,10 @@
|
|||||||
package de.steamwar.bausystem.features.simulator.data;
|
package de.steamwar.bausystem.features.simulator.data;
|
||||||
|
|
||||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||||
|
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
@@ -37,6 +37,10 @@ public abstract class SimulatorPhase {
|
|||||||
protected int order = 0;
|
protected int order = 0;
|
||||||
|
|
||||||
public abstract void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd);
|
public abstract void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd);
|
||||||
public void saveExtra(YAPIONObject phaseObject) {}
|
|
||||||
public void loadExtra(YAPIONObject phaseObject) {}
|
public void saveExtra(SimulatorConfig.Phase phase) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadExtra(SimulatorConfig.Phase phase) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.simulator.data.observer;
|
|||||||
|
|
||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||||
|
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -31,7 +32,6 @@ import org.bukkit.block.BlockFace;
|
|||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.data.type.Observer;
|
import org.bukkit.block.data.type.Observer;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
@@ -70,12 +70,12 @@ public final class ObserverPhase extends SimulatorPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveExtra(YAPIONObject phaseObject) {
|
public void saveExtra(SimulatorConfig.Phase phase) {
|
||||||
phaseObject.add("orientation", orientation.name());
|
phase.setOrientation(orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadExtra(YAPIONObject phaseObject) {
|
public void loadExtra(SimulatorConfig.Phase phase) {
|
||||||
orientation = BlockFace.valueOf(phaseObject.getPlainValue("orientation"));
|
if (phase.getOrientation() != null) orientation = phase.getOrientation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -24,13 +24,13 @@ import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
|||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.SimulatorTNTGui;
|
import de.steamwar.bausystem.features.simulator.gui.SimulatorTNTGui;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||||
|
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||||
import de.steamwar.inventory.InvCallback;
|
import de.steamwar.inventory.InvCallback;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
public final class TNTElement extends SimulatorElement<TNTPhase> {
|
public final class TNTElement extends SimulatorElement<TNTPhase> {
|
||||||
|
|
||||||
@@ -100,14 +100,14 @@ public final class TNTElement extends SimulatorElement<TNTPhase> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveExtra(YAPIONObject elementObject) {
|
public void saveExtra(SimulatorConfig.Element element) {
|
||||||
elementObject.add("alignmentX", alignment.getX());
|
element.setAlignmentX(alignment.getX());
|
||||||
elementObject.add("alignmentZ", alignment.getZ());
|
element.setAlignmentZ(alignment.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadExtra(YAPIONObject elementObject) {
|
public void loadExtra(SimulatorConfig.Element element) {
|
||||||
alignment.setX(elementObject.getDoubleOrSetDefault("alignmentX", 0));
|
alignment.setX(element.getAlignmentX() != null ? element.getAlignmentX() : 0);
|
||||||
alignment.setZ(elementObject.getDoubleOrSetDefault("alignmentZ", 0));
|
alignment.setZ(element.getAlignmentZ() != null ? element.getAlignmentZ() : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-12
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.simulator.data.tnt;
|
|||||||
|
|
||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||||
|
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.region.flags.Flag;
|
import de.steamwar.bausystem.region.flags.Flag;
|
||||||
import de.steamwar.bausystem.region.flags.FreezeMode;
|
import de.steamwar.bausystem.region.flags.FreezeMode;
|
||||||
@@ -31,7 +32,6 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.TNTPrimed;
|
import org.bukkit.entity.TNTPrimed;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import yapion.hierarchy.types.YAPIONObject;
|
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
@@ -65,7 +65,9 @@ public final class TNTPhase extends SimulatorPhase {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(World world) {
|
public void accept(World world) {
|
||||||
Location location = position.toLocation(world);
|
Location location = position.toLocation(world);
|
||||||
if (Region.getRegion(location).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) return;
|
if (Region.getRegion(location).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
TNTPrimed tnt = world.spawn(location, TNTPrimed.class);
|
TNTPrimed tnt = world.spawn(location, TNTPrimed.class);
|
||||||
if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0));
|
if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0));
|
||||||
if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0));
|
if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0));
|
||||||
@@ -81,18 +83,18 @@ public final class TNTPhase extends SimulatorPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveExtra(YAPIONObject phaseObject) {
|
public void saveExtra(SimulatorConfig.Phase phase) {
|
||||||
phaseObject.add("count", count);
|
phase.setCount(count);
|
||||||
phaseObject.add("xJump", xJump);
|
phase.setXJump(xJump);
|
||||||
phaseObject.add("yJump", yJump);
|
phase.setYJump(yJump);
|
||||||
phaseObject.add("zJump", zJump);
|
phase.setZJump(zJump);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadExtra(YAPIONObject phaseObject) {
|
public void loadExtra(SimulatorConfig.Phase phase) {
|
||||||
count = phaseObject.getPlainValue("count");
|
if (phase.getCount() != null) count = phase.getCount();
|
||||||
xJump = phaseObject.getPlainValue("xJump");
|
if (phase.getXJump() != null) xJump = phase.getXJump();
|
||||||
yJump = phaseObject.getPlainValue("yJump");
|
if (phase.getYJump() != null) yJump = phase.getYJump();
|
||||||
zJump = phaseObject.getPlainValue("zJump");
|
if (phase.getZJump() != null) zJump = phase.getZJump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -29,7 +29,6 @@ import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
|||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.utils.TickManager;
|
import de.steamwar.bausystem.utils.TickManager;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -40,7 +39,6 @@ import java.util.*;
|
|||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(19)
|
|
||||||
public class SimulatorExecutor implements Listener {
|
public class SimulatorExecutor implements Listener {
|
||||||
|
|
||||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||||
@@ -142,7 +140,7 @@ public class SimulatorExecutor implements Listener {
|
|||||||
private void runActions(List<SimulatorAction> actionsToRun) {
|
private void runActions(List<SimulatorAction> actionsToRun) {
|
||||||
while (!actionsToRun.isEmpty()) {
|
while (!actionsToRun.isEmpty()) {
|
||||||
Collections.shuffle(actionsToRun);
|
Collections.shuffle(actionsToRun);
|
||||||
for (int i = actionsToRun.size() - 1 ; i >= 0; i--) {
|
for (int i = actionsToRun.size() - 1; i >= 0; i--) {
|
||||||
SimulatorAction action = actionsToRun.get(i);
|
SimulatorAction action = actionsToRun.get(i);
|
||||||
action.accept(WORLD);
|
action.accept(WORLD);
|
||||||
action.setCount(action.getCount() - 1);
|
action.setCount(action.getCount() - 1);
|
||||||
|
|||||||
+2
-1
@@ -55,8 +55,9 @@ public class StabGenerator extends StabStep implements Listener {
|
|||||||
if (!(event.getEntity() instanceof TNTPrimed)) return;
|
if (!(event.getEntity() instanceof TNTPrimed)) return;
|
||||||
if (Region.getRegion(event.getEntity().getLocation()) == data.region) {
|
if (Region.getRegion(event.getEntity().getLocation()) == data.region) {
|
||||||
event.blockList().forEach(block -> {
|
event.blockList().forEach(block -> {
|
||||||
if (!data.region.getTestblockArea().inRegion(block.getLocation(), true))
|
if (!data.region.getTestblockArea().inRegion(block.getLocation(), true)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
int component = data.direction.component.apply(block.getLocation().toVector());
|
int component = data.direction.component.apply(block.getLocation().toVector());
|
||||||
destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>())
|
destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>())
|
||||||
.add(block.getLocation());
|
.add(block.getLocation());
|
||||||
|
|||||||
+11
-11
@@ -69,7 +69,7 @@ public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
// Base Tick
|
// Base Tick
|
||||||
int baseTicks = simulatorGroup.getBaseTick();
|
int baseTicks = simulatorGroup.getBaseTick();
|
||||||
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(9, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
simulatorGroup.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
simulatorGroup.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -83,7 +83,7 @@ public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
|
|||||||
});
|
});
|
||||||
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
||||||
inventory.setItem(18, baseTick);
|
inventory.setItem(18, baseTick);
|
||||||
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(27, new SWItem(baseTicks > 0 ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
||||||
simulatorGroup.changeBaseTicks(-baseTicks);
|
simulatorGroup.changeBaseTicks(-baseTicks);
|
||||||
} else {
|
} else {
|
||||||
@@ -163,13 +163,13 @@ public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Pos X
|
//Pos X
|
||||||
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(15, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
|
||||||
simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0, 0);
|
simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
inventory.setItem(24, new SWItem(Material.PAPER, "§eX", clickType -> {
|
inventory.setItem(24, new SWItem(Material.PAPER, "§eX", clickType -> {
|
||||||
new SimulatorAnvilGui<>(player, "Relative X", "", Double::parseDouble, number -> {
|
new SimulatorAnvilGui<>(player, "Relative X", "", Double::parseDouble, number -> {
|
||||||
if(!allTNT){
|
if (!allTNT) {
|
||||||
number = (double) Math.round(number);
|
number = (double) Math.round(number);
|
||||||
}
|
}
|
||||||
simulatorGroup.move(number, 0, 0);
|
simulatorGroup.move(number, 0, 0);
|
||||||
@@ -177,19 +177,19 @@ public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
|
|||||||
return true;
|
return true;
|
||||||
}, this).setItem(Material.PAPER).open();
|
}, this).setItem(Material.PAPER).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(33, new SWItem(Material.RED_DYE, "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
|
||||||
simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0, 0);
|
simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Y
|
//Pos Y
|
||||||
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(16, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
|
||||||
simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0);
|
simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
inventory.setItem(25, new SWItem(Material.PAPER, "§eY", clickType -> {
|
inventory.setItem(25, new SWItem(Material.PAPER, "§eY", clickType -> {
|
||||||
new SimulatorAnvilGui<>(player, "Relative Y", "", Double::parseDouble, number -> {
|
new SimulatorAnvilGui<>(player, "Relative Y", "", Double::parseDouble, number -> {
|
||||||
if(!allTNT){
|
if (!allTNT) {
|
||||||
number = (double) Math.round(number);
|
number = (double) Math.round(number);
|
||||||
}
|
}
|
||||||
simulatorGroup.move(0, number, 0);
|
simulatorGroup.move(0, number, 0);
|
||||||
@@ -197,19 +197,19 @@ public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
|
|||||||
return true;
|
return true;
|
||||||
}, this).setItem(Material.PAPER).open();
|
}, this).setItem(Material.PAPER).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(34, new SWItem(Material.RED_DYE, "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
|
||||||
simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0);
|
simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Z
|
//Pos Z
|
||||||
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(17, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> {
|
||||||
simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1);
|
simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
inventory.setItem(26, new SWItem(Material.PAPER, "§eZ", clickType -> {
|
inventory.setItem(26, new SWItem(Material.PAPER, "§eZ", clickType -> {
|
||||||
new SimulatorAnvilGui<>(player, "Relative Z", "", Double::parseDouble, number -> {
|
new SimulatorAnvilGui<>(player, "Relative Z", "", Double::parseDouble, number -> {
|
||||||
if(!allTNT){
|
if (!allTNT) {
|
||||||
number = (double) Math.round(number);
|
number = (double) Math.round(number);
|
||||||
}
|
}
|
||||||
simulatorGroup.move(0, 0, number);
|
simulatorGroup.move(0, 0, number);
|
||||||
@@ -217,7 +217,7 @@ public class SimulatorGroupSettingsGui extends SimulatorBaseGui {
|
|||||||
return true;
|
return true;
|
||||||
}, this).setItem(Material.PAPER).open();
|
}, this).setItem(Material.PAPER).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(35, new SWItem(Material.RED_DYE, "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> {
|
||||||
simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1);
|
simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|||||||
+5
-5
@@ -148,14 +148,14 @@ public class SimulatorObserverGui extends SimulatorScrollGui<ObserverPhase> {
|
|||||||
|
|
||||||
Supplier<Integer> getter = observerPhase::getTickOffset;
|
Supplier<Integer> getter = observerPhase::getTickOffset;
|
||||||
Consumer<Integer> setter = observerPhase::setTickOffset;
|
Consumer<Integer> setter = observerPhase::setTickOffset;
|
||||||
return new SWItem[] {
|
return new SWItem[]{
|
||||||
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(getter.get() < max ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
observer,
|
observer,
|
||||||
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
new SWItem(getter.get() > min ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -169,13 +169,13 @@ public class SimulatorObserverGui extends SimulatorScrollGui<ObserverPhase> {
|
|||||||
@Override
|
@Override
|
||||||
public SWItem[] lastColumn() {
|
public SWItem[] lastColumn() {
|
||||||
return new SWItem[]{
|
return new SWItem[]{
|
||||||
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
addNewPhase(clickType.isShiftClick());
|
addNewPhase(clickType.isShiftClick());
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
new SWItem(Material.QUARTZ, "§eObserver§8:§a New Phase", clickType -> {
|
new SWItem(Material.QUARTZ, "§eObserver§8:§a New Phase", clickType -> {
|
||||||
addNewPhase(false);
|
addNewPhase(false);
|
||||||
}).setCustomModelData(CMDs.Simulator.NEW_PHASE),
|
}).setCustomModelData(CMDs.Simulator.NEW_PHASE),
|
||||||
new SWItem(SWItem.getDye(8), "§7", clickType -> {
|
new SWItem(Material.GRAY_DYE, "§7", clickType -> {
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-8
@@ -26,7 +26,6 @@ import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement;
|
|||||||
import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
|
import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.data.CMDs;
|
import de.steamwar.data.CMDs;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -97,7 +96,7 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Tick Offset
|
//Tick Offset
|
||||||
int offset = observer.getTickOffset();
|
int offset = observer.getTickOffset();
|
||||||
inventory.setItem(10, new SWItem(SWItem.getDye(offset < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(10, new SWItem(offset < max ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setTickOffset(Math.min(max, offset + (clickType.isShiftClick() ? 5 : 1)));
|
observer.setTickOffset(Math.min(max, offset + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -114,7 +113,7 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64)));
|
offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64)));
|
||||||
inventory.setItem(19, offsetItem);
|
inventory.setItem(19, offsetItem);
|
||||||
|
|
||||||
inventory.setItem(28, new SWItem(SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(28, new SWItem(offset > min ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -122,26 +121,25 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Order
|
//Order
|
||||||
int order = observer.getOrder();
|
int order = observer.getOrder();
|
||||||
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(13, new SWItem(order < SimulatorPhase.ORDER_LIMIT ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
observer.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
|
|
||||||
Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR");
|
SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : Material.RECOVERY_COMPASS, "§eActivation Order§8:§7 " + order, clickType -> {
|
||||||
SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eActivation Order§8:§7 " + order, clickType -> {
|
|
||||||
new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> {
|
new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> {
|
||||||
if (integer < -SimulatorPhase.ORDER_LIMIT) return false;
|
if (integer < -SimulatorPhase.ORDER_LIMIT) return false;
|
||||||
if (integer > SimulatorPhase.ORDER_LIMIT) return false;
|
if (integer > SimulatorPhase.ORDER_LIMIT) return false;
|
||||||
observer.setOrder(integer);
|
observer.setOrder(integer);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
return true;
|
return true;
|
||||||
}, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open();
|
}, this).setItem(order >= 0 ? Material.COMPASS : Material.RECOVERY_COMPASS).open();
|
||||||
});
|
});
|
||||||
orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30)));
|
orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30)));
|
||||||
inventory.setItem(22, orderItem);
|
inventory.setItem(22, orderItem);
|
||||||
|
|
||||||
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(31, new SWItem(order > -SimulatorPhase.ORDER_LIMIT ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
|
|||||||
+8
-8
@@ -67,7 +67,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
// Base Tick
|
// Base Tick
|
||||||
int baseTicks = observer.getBaseTick();
|
int baseTicks = observer.getBaseTick();
|
||||||
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(9, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
observer.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -82,7 +82,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
});
|
});
|
||||||
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
||||||
inventory.setItem(18, baseTick);
|
inventory.setItem(18, baseTick);
|
||||||
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(27, new SWItem(baseTicks > 0 ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
||||||
observer.changeBaseTicks(-baseTicks);
|
observer.changeBaseTicks(-baseTicks);
|
||||||
@@ -93,7 +93,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos X
|
//Pos X
|
||||||
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(15, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
|
observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -105,14 +105,14 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
return true;
|
return true;
|
||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(33, new SWItem(Material.RED_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
|
observer.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Y
|
//Pos Y
|
||||||
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(16, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, clickType.isShiftClick() ? 5 : 1, 0);
|
observer.move(0, clickType.isShiftClick() ? 5 : 1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -124,14 +124,14 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
return true;
|
return true;
|
||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(34, new SWItem(Material.RED_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, clickType.isShiftClick() ? -5 : -1, 0);
|
observer.move(0, clickType.isShiftClick() ? -5 : -1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Z
|
//Pos Z
|
||||||
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(17, new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, 0, clickType.isShiftClick() ? 5 : 1);
|
observer.move(0, 0, clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -143,7 +143,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
return true;
|
return true;
|
||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(35, new SWItem(Material.RED_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, 0, clickType.isShiftClick() ? -5 : -1);
|
observer.move(0, 0, clickType.isShiftClick() ? -5 : -1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
|
|||||||
+5
-5
@@ -163,14 +163,14 @@ public class SimulatorRedstoneGui extends SimulatorScrollGui<SimulatorRedstoneGu
|
|||||||
|
|
||||||
Supplier<Integer> getter = redstoneSubPhase.place ? redstoneSubPhase.phase::getTickOffset : redstoneSubPhase.phase::getLifetime;
|
Supplier<Integer> getter = redstoneSubPhase.place ? redstoneSubPhase.phase::getTickOffset : redstoneSubPhase.phase::getLifetime;
|
||||||
Consumer<Integer> setter = redstoneSubPhase.place ? redstoneSubPhase.phase::setTickOffset : redstoneSubPhase.phase::setLifetime;
|
Consumer<Integer> setter = redstoneSubPhase.place ? redstoneSubPhase.phase::setTickOffset : redstoneSubPhase.phase::setLifetime;
|
||||||
return new SWItem[] {
|
return new SWItem[]{
|
||||||
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(getter.get() < max ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
redstone,
|
redstone,
|
||||||
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
new SWItem(getter.get() > min ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -184,13 +184,13 @@ public class SimulatorRedstoneGui extends SimulatorScrollGui<SimulatorRedstoneGu
|
|||||||
@Override
|
@Override
|
||||||
public SWItem[] lastColumn() {
|
public SWItem[] lastColumn() {
|
||||||
return new SWItem[]{
|
return new SWItem[]{
|
||||||
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(Material.LIME_DYE, "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
addNewPhase(clickType.isShiftClick());
|
addNewPhase(clickType.isShiftClick());
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
new SWItem(Material.REDSTONE, "§eRedstone§8:§a New Phase", clickType -> {
|
new SWItem(Material.REDSTONE, "§eRedstone§8:§a New Phase", clickType -> {
|
||||||
addNewPhase(false);
|
addNewPhase(false);
|
||||||
}).setCustomModelData(CMDs.Simulator.NEW_PHASE),
|
}).setCustomModelData(CMDs.Simulator.NEW_PHASE),
|
||||||
new SWItem(SWItem.getDye(8), "§7", clickType -> {
|
new SWItem(Material.GRAY_DYE, "§7", clickType -> {
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-10
@@ -26,7 +26,6 @@ import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
|
|||||||
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
|
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
|
||||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import de.steamwar.data.CMDs;
|
import de.steamwar.data.CMDs;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -98,7 +97,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Tick Offset
|
//Tick Offset
|
||||||
int offset = redstone.getTickOffset();
|
int offset = redstone.getTickOffset();
|
||||||
inventory.setItem(10, new SWItem(SWItem.getDye(offset < maxOffset ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(10, new SWItem(offset < maxOffset ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setTickOffset(Math.min(maxOffset, offset + (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setTickOffset(Math.min(maxOffset, offset + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -115,7 +114,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64)));
|
offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64)));
|
||||||
inventory.setItem(19, offsetItem);
|
inventory.setItem(19, offsetItem);
|
||||||
|
|
||||||
inventory.setItem(28, new SWItem(SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(28, new SWItem(offset > min ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -123,7 +122,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Lifetime
|
//Lifetime
|
||||||
int lifetime = redstone.getLifetime();
|
int lifetime = redstone.getLifetime();
|
||||||
inventory.setItem(11, new SWItem(SWItem.getDye(lifetime < maxLifetime ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(11, new SWItem(lifetime < maxLifetime ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setLifetime(Math.min(maxLifetime, lifetime + (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setLifetime(Math.min(maxLifetime, lifetime + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -140,7 +139,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
lifetimeItem.getItemStack().setAmount(Math.max(1, Math.min(lifetime, 64)));
|
lifetimeItem.getItemStack().setAmount(Math.max(1, Math.min(lifetime, 64)));
|
||||||
inventory.setItem(20, lifetimeItem);
|
inventory.setItem(20, lifetimeItem);
|
||||||
|
|
||||||
inventory.setItem(29, new SWItem(SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(29, new SWItem(lifetime > 0 ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setLifetime(Math.max(0, lifetime - (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setLifetime(Math.max(0, lifetime - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
@@ -148,26 +147,25 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Order
|
//Order
|
||||||
int order = redstone.getOrder();
|
int order = redstone.getOrder();
|
||||||
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(13, new SWItem(order < SimulatorPhase.ORDER_LIMIT ? Material.LIME_DYE : Material.GRAY_DYE, "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
|
|
||||||
Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR");
|
SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : Material.RECOVERY_COMPASS, "§eActivation Order§8:§7 " + order, clickType -> {
|
||||||
SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eActivation Order§8:§7 " + order, clickType -> {
|
|
||||||
new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> {
|
new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> {
|
||||||
if (integer < -SimulatorPhase.ORDER_LIMIT) return false;
|
if (integer < -SimulatorPhase.ORDER_LIMIT) return false;
|
||||||
if (integer > SimulatorPhase.ORDER_LIMIT) return false;
|
if (integer > SimulatorPhase.ORDER_LIMIT) return false;
|
||||||
redstone.setOrder(integer);
|
redstone.setOrder(integer);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
return true;
|
return true;
|
||||||
}, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open();
|
}, this).setItem(order >= 0 ? Material.COMPASS : Material.RECOVERY_COMPASS).open();
|
||||||
});
|
});
|
||||||
orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30)));
|
orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30)));
|
||||||
inventory.setItem(22, orderItem);
|
inventory.setItem(22, orderItem);
|
||||||
|
|
||||||
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(31, new SWItem(order > -SimulatorPhase.ORDER_LIMIT ? Material.RED_DYE : Material.GRAY_DYE, "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
if (clickType == ClickType.DOUBLE_CLICK) return;
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user