mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-09-27 22:47:28 +02:00
Compare commits
405 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a693d23489 | ||
|
98e85733b9 | ||
|
e6da2a5810 | ||
|
259fcc2f29 | ||
|
93548e4fe9 | ||
|
29c9feea44 | ||
|
55059437be | ||
|
42bd4583fa | ||
|
9ff3f45e52 | ||
|
c5d6466eed | ||
|
7bc2e0181b | ||
|
756b9d00af | ||
|
a3cb8af95d | ||
|
d3cc84c026 | ||
|
553c89beeb | ||
|
ba9aff2a8a | ||
|
58243b6757 | ||
|
5cc5ce5537 | ||
|
e994c765fa | ||
|
f71043bea6 | ||
|
d89cb44db7 | ||
|
4879e0b62a | ||
|
e1a62156c2 | ||
|
57c85d0aac | ||
|
3132b8f1f2 | ||
|
2eee25e44e | ||
|
56499b7752 | ||
|
361a4e3dce | ||
|
a31dd987a5 | ||
|
c5640e5038 | ||
|
e901a0eba6 | ||
|
4c87fea95c | ||
|
c6db4e10fd | ||
|
d1f6ef14ef | ||
|
dd28c78a36 | ||
|
92e50d5897 | ||
|
4c9f9606d9 | ||
|
8c3e6b7e08 | ||
|
b514efecfc | ||
|
049dbe2dc2 | ||
|
d13b946b02 | ||
|
a1ffd3d5ff | ||
|
4bd026239d | ||
|
14f3b914d3 | ||
|
b39b388645 | ||
|
28e2537aaa | ||
|
ab71b938e5 | ||
|
70e24e432c | ||
|
ee9950bca7 | ||
|
dc2d277517 | ||
|
56a71fae5e | ||
|
e5c6a79f65 | ||
|
e5c7042e25 | ||
|
d131fa657e | ||
|
6afe1b0ca6 | ||
|
e64debbc2a | ||
|
772de99706 | ||
|
f0fbd34d3c | ||
|
5d0d461baf | ||
|
2d77214aa9 | ||
|
dbf28a41d4 | ||
|
783fda82bf | ||
|
846495ee66 | ||
|
bcab75fe53 | ||
|
c704f34e9b | ||
|
6bd4e990db | ||
|
40906b40f4 | ||
|
1c17b1001d | ||
|
8448b39414 | ||
|
ba066847c4 | ||
|
0baddf7034 | ||
|
beb5cd61a4 | ||
|
5e85cee058 | ||
|
626169ad1f | ||
|
0d10c1b690 | ||
|
e26cdc6112 | ||
|
be9f606027 | ||
|
3c9b0fa3ea | ||
|
ae4083c9be | ||
|
ac3005be36 | ||
|
7962a15c47 | ||
|
ce69326bb5 | ||
|
e9c5d54ce5 | ||
|
abe8b3f99a | ||
|
7f659a8b4f | ||
|
2fef5e2e40 | ||
|
0cf2a92d4c | ||
|
9ce9885fb5 | ||
|
bcd60813b6 | ||
|
2713a68343 | ||
|
26f4eaeb06 | ||
|
c075b53784 | ||
|
d2302d4088 | ||
|
47ce67c325 | ||
|
e447ef10a0 | ||
|
dfa66ea86b | ||
|
2bd8b6b6a0 | ||
|
e1569b85e2 | ||
|
50bef3fb0c | ||
|
7d35200727 | ||
|
193519bbb8 | ||
|
f3fdef6a46 | ||
|
05f8b758d8 | ||
|
934897ff1c | ||
|
28ee68f0a6 | ||
|
b8a0dea4bd | ||
|
b7f1ee30c6 | ||
|
71dedf61d8 | ||
|
671c781a7c | ||
|
9023723a0e | ||
|
406bc9c017 | ||
|
f7decab132 | ||
|
936bd6fa91 | ||
|
0640b19733 | ||
|
8da1224e08 | ||
|
ca5ffe081b | ||
|
d3ddd9ea6a | ||
|
9002a9a78f | ||
|
629f90cdaa | ||
|
9a67e7deb0 | ||
|
e57ac75a50 | ||
|
7108d62567 | ||
|
0af4a02687 | ||
|
aa33250d42 | ||
|
db7110dac8 | ||
|
beb2e0e1b0 | ||
|
3893aab67e | ||
|
0021ab0d61 | ||
|
4095181346 | ||
|
fc74879a84 | ||
|
c4b24e501b | ||
|
175bafdffb | ||
|
57a977e148 | ||
|
3e15d63448 | ||
|
765be78aff | ||
|
839a3151d5 | ||
|
9e6b3fabe4 | ||
|
de52cfc656 | ||
|
57f61f4f74 | ||
|
83e818d1c9 | ||
|
0866842257 | ||
|
fc1a8da8e2 | ||
|
16e7a90802 | ||
|
f777211b90 | ||
|
46e36d90a4 | ||
|
39ef1d7d62 | ||
|
ea8d93c64b | ||
|
a703bba082 | ||
|
c836e0ef68 | ||
|
213207ab7b | ||
|
d0a55ba4a4 | ||
|
7e2b2e45b4 | ||
|
c1e13b14a7 | ||
|
a3a28fe3de | ||
|
e75ff89429 | ||
|
c472e85a27 | ||
|
4394b45743 | ||
|
1fabc98aff | ||
|
d0a2cabd5c | ||
|
8dfde39cae | ||
|
1acc77a0c6 | ||
|
1b55aa0b0c | ||
|
055a08b741 | ||
|
fa7fc22398 | ||
|
c683b414ba | ||
|
c12f685f0f | ||
|
60d07b5c2f | ||
|
e6128ecf63 | ||
|
1c6097454f | ||
|
12265521c8 | ||
|
c1ef78b30f | ||
|
55a8978869 | ||
|
f2412bca13 | ||
|
a78411dfdc | ||
|
3ed2e57f3a | ||
|
371e1bb27e | ||
|
4d08c1229b | ||
|
f5f13ddbe3 | ||
|
a00345fd94 | ||
|
dc593a4667 | ||
|
074cf281c9 | ||
|
7501eabd2e | ||
|
efef7bcc00 | ||
|
7cbb117215 | ||
|
9a8ec501b7 | ||
|
c8eea3c976 | ||
|
bc9ccbd898 | ||
|
6138a20105 | ||
|
3ee4ab1e73 | ||
|
8796252c95 | ||
|
db3c83fdef | ||
|
bcfc7275ad | ||
|
7f26c57ed9 | ||
|
cc97c8d21e | ||
|
29794d4ccd | ||
|
c4d373549a | ||
|
9144d37c25 | ||
|
b8f37feef1 | ||
|
eaedd5442a | ||
|
3dbe0e9c30 | ||
|
4049014cb8 | ||
|
11dcafbcb8 | ||
|
099f733989 | ||
|
58bf6f3172 | ||
|
7eb83c000b | ||
|
cf27decdb4 | ||
|
01554bf1fb | ||
|
6c05ec3b2a | ||
|
999e97a2de | ||
|
ca1a62ac79 | ||
|
c6605ce587 | ||
|
d58a8549cb | ||
|
c93c4aee65 | ||
|
435ffe934e | ||
|
d219f5d02d | ||
|
24f907395d | ||
|
b281370f3b | ||
|
3cae6e08c8 | ||
|
d66c14b06d | ||
|
d541115a3b | ||
|
5d076ef4b2 | ||
|
fb744cdb21 | ||
|
7aebc60983 | ||
|
f95b659860 | ||
|
9a54719d13 | ||
|
fc599f2f86 | ||
|
0bf6595ddd | ||
|
3b5c1d1c8b | ||
|
63a40653cc | ||
|
2a7e111f46 | ||
|
fe17434d00 | ||
|
8218e831ac | ||
|
345b344000 | ||
|
ba5f37cd32 | ||
|
0d9e79f4ae | ||
|
0d1b46189b | ||
|
90713991a9 | ||
|
89bd2c0025 | ||
|
e1df0ac8d1 | ||
|
63cb4784e7 | ||
|
199eea5d9f | ||
|
7a9ed0f512 | ||
|
af43e19018 | ||
|
c71d872517 | ||
|
6839d5531f | ||
|
03318369ae | ||
|
d32bcaac4b | ||
|
e244235350 | ||
|
1bebe14b67 | ||
|
19a9db3abf | ||
|
7519f735bc | ||
|
0f2125cc83 | ||
|
81a76dfd30 | ||
|
916bca59ba | ||
|
4d62867cb6 | ||
|
2ec9a92268 | ||
|
e8feaa9204 | ||
|
eaa8fbfc9d | ||
|
8e3e5b0d14 | ||
|
29337e17d1 | ||
|
6cec36af99 | ||
|
13b5ded4e9 | ||
|
668f6c6e34 | ||
|
7065492740 | ||
|
cfe47d25d2 | ||
|
32cf8e47cc | ||
|
a89bdae93b | ||
|
02f2572cf5 | ||
|
40a569e14e | ||
|
11ac395ff6 | ||
|
b4bb0ddc15 | ||
|
3182441e66 | ||
|
124cc02350 | ||
|
bd346bc4c5 | ||
|
5298c5401f | ||
|
72d85e0754 | ||
|
5fdad79469 | ||
|
a7aef5bfd2 | ||
|
7997c60db4 | ||
|
8830f9269c | ||
|
d1231fb56d | ||
|
049aff4d74 | ||
|
5bdc2d6519 | ||
|
39216dee42 | ||
|
6c67192fe2 | ||
|
d8d273a163 | ||
|
6968e66ad8 | ||
|
c938a61896 | ||
|
b1f8bbddfa | ||
|
7968cdc232 | ||
|
79fe27ab3e | ||
|
48992d2a4a | ||
|
1f185e52b9 | ||
|
fa7a5f1423 | ||
|
5bb585db37 | ||
|
12ac22a9f7 | ||
|
51a541eee1 | ||
|
18c71453ce | ||
|
ae3981cebf | ||
|
7c3ac8e362 | ||
|
aace4a37cb | ||
|
789c923106 | ||
|
65939fa878 | ||
|
a5d70a65aa | ||
|
bc5241274c | ||
|
485427c667 | ||
|
83d6d0d1e0 | ||
|
c696b0260a | ||
|
a2daa3a6a5 | ||
|
fac3772eed | ||
|
5cc4f6a37f | ||
|
f991f4ad88 | ||
|
353f93951c | ||
|
8c29292bad | ||
|
e54df5a403 | ||
|
1967dd0769 | ||
|
a07ad2c470 | ||
|
3d8fdb021a | ||
|
5045e3e6cd | ||
|
e6f417de55 | ||
|
25ef3a0c81 | ||
|
4a9721edd3 | ||
|
a19e9a45e9 | ||
|
cf54fdc8c5 | ||
|
871074ec8e | ||
|
c9ca0791ea | ||
|
9cc588d5c9 | ||
|
ddcc297ec5 | ||
|
9128a17533 | ||
|
044fc0a44c | ||
|
3644ad9d70 | ||
|
b430f4748a | ||
|
7df831cc58 | ||
|
dc8a18af9d | ||
|
c4165a76a4 | ||
|
80672f74e7 | ||
|
d450b8f0bc | ||
|
77cf4ec34c | ||
|
61f3dcaacc | ||
|
09addf9073 | ||
|
ca7579e0a7 | ||
|
7141cc4a9c | ||
|
dd29dd518d | ||
|
9c1fe2571b | ||
|
ce394bceae | ||
|
df12aa421e | ||
|
4c2754d6df | ||
|
504f790b61 | ||
|
f38796656c | ||
|
e1c3404b16 | ||
|
e09c0c2224 | ||
|
519a95b4b9 | ||
|
fa8d9d322e | ||
|
fb8f76f833 | ||
|
147c1c87fe | ||
|
598fcb8fcd | ||
|
9ef163af52 | ||
|
1b504e949c | ||
|
b902a57c2c | ||
|
6f664c19bb | ||
|
46634b1b26 | ||
|
bad4705f7a | ||
|
ec5e45fdd2 | ||
|
371b4f5ee5 | ||
|
21e976ce4d | ||
|
7136fb422e | ||
|
ad60b90987 | ||
|
ea63c77d7e | ||
|
724bf55f13 | ||
|
68bda0d775 | ||
|
e1ab82d07b | ||
|
ca906cc8c3 | ||
|
5125a18540 | ||
|
6ee7f47129 | ||
|
17d3e574fb | ||
|
613f6bd5c0 | ||
|
1186a00b47 | ||
|
bcbf307e8d | ||
|
8d5e329eea | ||
|
083d4e7d08 | ||
|
ff42446f19 | ||
|
8cd6c1512b | ||
|
78e795d21a | ||
|
134daefa24 | ||
|
d78d533acd | ||
|
e2e31b364d | ||
|
bcb9320a45 | ||
|
2448b2fe22 | ||
|
446dc9c568 | ||
|
0a246fc90f | ||
|
0a127dfb40 | ||
|
5be72dd5d7 | ||
|
780a1ec16f | ||
|
4b7c1e987b | ||
|
9366acd6dc | ||
|
274bc6d9a7 | ||
|
b36c3dfc90 | ||
|
a1ccdf0543 | ||
|
0a776078ea | ||
|
4609b472fe | ||
|
e6ea640d21 | ||
|
bb7b1cb736 | ||
|
e1e31beff0 | ||
|
189e8189fb | ||
|
9126c083ab |
2
.github/CONTRIBUTING.md
vendored
Normal file
2
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
### Bugs
|
||||
Please provide a proper title, description, console log, your FAWE configuration, and info about replicating the issue on your issue post.
|
23
.github/ISSUE_TEMPLATE.md
vendored
Normal file
23
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# *NOTICE: Bukkit/Spigot versions 1.7.10 to 1.12.2 are considered as legacy and receive no support. Please consider upgrading to 1.15.2 or higher versions for future support. Plugins exist that bring back old behaviors found in 1.8*
|
||||
# Bug report for FastAsyncWorldEdit < 1.12.2
|
||||
<!--- REPORT ISSUES REGARDING FAWE FOR 1.13 AND HIGHER HERE: https://github.com/IntellectualSites/FastAsyncWorldEdit/issues --->
|
||||
<!--- Follow this template if reporting an issue. -->
|
||||
<!--- Remove this template if making a suggestion or asking a question. -->
|
||||
<!--- Please comment or react to an existing ticket if it exists -->
|
||||
**Debug paste link**:
|
||||
<!--- Enter /fawe debugpaste in game or in your console and copy the output here -->
|
||||
|
||||
**Description of the problem:**
|
||||
<!--- Include relevant info like errors or a picture of the problem -->
|
||||
|
||||
**How to replicate**:
|
||||
<!--- If you can reproduce the issue please tell us as detailed as possible step by step how to do that -->
|
||||
|
||||
**Checklist**:
|
||||
<!--- Make sure you've completed the following steps (put an "X" between of brackets): -->
|
||||
- [] I read the information at the top of the issue stating that versions up to 1.12.2 are classified as legacy and receive no support. Given that, I understand that my issue won't receive an answer or fix anytime soon since my version is very old and I should update my server to a version past 1.14.4 of minecraft.
|
||||
- [] I made sure that I'm using FAWE on 1.12.2 or lower
|
||||
- [] I included a `/fawe debugpaste` link
|
||||
- [] I made sure there aren't duplicates of this report [(Use Search)](https://github.com/boy0001/FastAsyncWorldedit/issues?utf8=%E2%9C%93&q=is%3Aissue)
|
||||
- [] I made sure I am using an up-to-date version of [FAWE < 1.12.2](https://ci.athion.net/job/FastAsyncWorldEdit/)
|
||||
- [] I made sure the bug/error is not caused by any other plugin
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: FAWE 1.15+ Issue Tracker
|
||||
url: https://github.com/IntellectualSites/FastAsyncWorldEdit/issues
|
||||
about: Click here to move to our new issue tracker, DO NOT USE THIS ONE! YOUR ISSUE WILL BE IGNORED!!!
|
13
.gitignore
vendored
13
.gitignore
vendored
@ -20,6 +20,10 @@ gradle.log
|
||||
/forge1710/build
|
||||
/sponge/build
|
||||
/sponge111/build
|
||||
/bukkit/out
|
||||
/nukkit/out
|
||||
/sponge112/build
|
||||
/core/out
|
||||
/bukkit/build
|
||||
/bukkit0/build
|
||||
/bukkit19/build
|
||||
@ -30,3 +34,12 @@ spigot-1.10
|
||||
wiki_permissions.md
|
||||
/textures
|
||||
*.iml
|
||||
/obj
|
||||
docs/
|
||||
|
||||
bukkit/bin/
|
||||
core/bin/
|
||||
favs/bin/
|
||||
forge110/bin/
|
||||
forge189/bin/
|
||||
forge194/bin/
|
||||
|
@ -1,2 +0,0 @@
|
||||
### Bugs
|
||||
Please provide a console log and your fawe configuration.
|
@ -1,19 +0,0 @@
|
||||
# Bug report
|
||||
<!--- Follow this template if reporting an issue. -->
|
||||
<!--- Remove this template if making a suggestion or asking a question. -->
|
||||
<!--- Please comment or react to an existing ticket if it exists -->
|
||||
**Debug paste link**:
|
||||
<!--- Enter /fawe debugpaste in game or in your console and copy the output here -->
|
||||
|
||||
**Description of the problem:**
|
||||
<!--- Include relevant info like errors or a picture of the problem -->
|
||||
|
||||
**How to replicate**:
|
||||
<!--- If you can reproduce the issue please tell us as detailed as possible step by step how to do that -->
|
||||
|
||||
**Checklist**:
|
||||
<!--- Make sure you've completed the following steps (put an "X" between of brackets): -->
|
||||
- [] I included a `/fawe debugpaste` link
|
||||
- [] I made sure there aren't duplicates of this report [(Use Search)](https://github.com/boy0001/FastAsyncWorldedit/issues?utf8=%E2%9C%93&q=is%3Aissue)
|
||||
- [] I made sure I am using an up-to-date version of FAWE
|
||||
- [] I Made sure the bug/error is not caused by any other plugin
|
34
README.md
34
README.md
@ -1,14 +1,36 @@
|
||||
# FastAsyncWorldEdit
|
||||
<p align="center">
|
||||
<img src="https://i.imgur.com/Fog5fDB.png">
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
# This is the legacy version of FAWE (1.8 - 1.12 and other platforms). It is no longer maintained. The focus lays on the newer versions of minecraft. You can find the new version of FAWE [here](https://github.com/IntellectualSites/FastAsyncWorldEdit).
|
||||
|
||||
FAWE is a fork of WorldEdit that has huge speed and memory improvements and considerably more features
|
||||
|
||||
It is available for Bukkit, Forge, Sponge and Nukkit.
|
||||
|
||||
## Chat
|
||||
Meet us on [`Discord`](https://discord.gg/ngZCzbU) or [`irc.esper.net #IntellectualCrafters`](http://webchat.esper.net/?nick=&channels=IntellectualCrafters).
|
||||
## Links
|
||||
|
||||
## Releases
|
||||
* [Spigot Page](https://www.spigotmc.org/threads/fast-async-worldedit.100104/)
|
||||
* [Discord](https://discord.gg/ngZCzbU)
|
||||
* [Wiki](https://github.com/boy0001/FastAsyncWorldedit/wiki)
|
||||
|
||||
https://github.com/boy0001/FastAsyncWorldedit/releases/latest
|
||||
## Downloads
|
||||
### <1.12.2
|
||||
* [Download](https://empcraft.com/fawe/download/?bukkit)
|
||||
* [Jenkins](https://ci.athion.net/job/FastAsyncWorldEdit/)
|
||||
* [JavaDoc](https://ci.athion.net/job/FastAsyncWorldEdit/javadoc/)
|
||||
|
||||
### 1.13+
|
||||
* [Download](https://empcraft.com/fawe/download/?bukkit113)
|
||||
* [Jenkins](https://ci.athion.net/job/FastAsyncWorldEdit-1.13/)
|
||||
* [JavaDoc](https://ci.athion.net/job/FastAsyncWorldEdit-1.13/javadoc/)
|
||||
* [Repository](https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13)
|
||||
|
||||
## Developer Resources
|
||||
* [Maven Repo](http://ci.athion.net/job/FastAsyncWorldEdit/ws/mvn/)
|
||||
* [API Documentation](https://github.com/boy0001/FastAsyncWorldedit/wiki/API)
|
||||
|
||||
## Building
|
||||
FAWE uses gradle to build
|
||||
@ -22,4 +44,4 @@ $ gradlew build
|
||||
Have an idea for an optimization, or a cool feature?
|
||||
- I'll accept most PR's
|
||||
- Let me know what you've tested / what may need further testing
|
||||
- If you need any help, create a ticket or discuss on Discord
|
||||
- If you need any help, create a ticket or discuss on [Discord](https://discord.gg/ngZCzbU)
|
||||
|
43
build.gradle
43
build.gradle
@ -34,7 +34,7 @@ ext {
|
||||
date = git.head().date.format("yy.MM.dd")
|
||||
revision = "-${git.head().abbreviatedId}"
|
||||
parents = git.head().parentIds;
|
||||
index = -96; // Offset to match CI
|
||||
index = -67; // Offset to match CI
|
||||
int major, minor, patch;
|
||||
major = minor = patch = 0;
|
||||
for (; parents != null && !parents.isEmpty(); index++) {
|
||||
@ -75,7 +75,7 @@ ext {
|
||||
|
||||
version = date + revision + buildNumber + semver
|
||||
if ( project.hasProperty("lzNoVersion") ) { // gradle build -PlzNoVersion
|
||||
version = "unknown";
|
||||
version = "unknown"
|
||||
}
|
||||
description = """FastAsyncWorldEdit"""
|
||||
|
||||
@ -94,21 +94,42 @@ subprojects {
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {url "https://mvnrepository.com/artifact/"}
|
||||
mavenCentral()
|
||||
maven {url "http://repo.dmulloy2.net/content/groups/public/"}
|
||||
maven {url "https://repo.destroystokyo.com/repository/maven-public//"}
|
||||
maven { url = "https://mvnrepository.com/artifact/"}
|
||||
maven {url "http://ci.emc.gs/nexus/content/groups/aikar/" }
|
||||
maven {url "http://ci.mengcraft.com:8080/plugin/repository/everything"}
|
||||
maven {url "http://ci.athion.net/job/PlotSquared/ws/mvn/"}
|
||||
maven {url "http://empcraft.com/maven2"}
|
||||
//maven {url "http://ci.emc.gs/nexus/content/groups/aikar/" }
|
||||
maven {url "https://ci.athion.net/plugin/repository/tools/"}
|
||||
mavenLocal()
|
||||
maven {url "https://hub.spigotmc.org/nexus/content/groups/public/"}
|
||||
maven {url "http://maven.sk89q.com/repo/"}
|
||||
maven {url "http://nexus.hc.to/content/repositories/pub_releases"}
|
||||
maven {url "http://repo.maven.apache.org/maven2"}
|
||||
maven {url "https://maven.enginehub.org/repo/"}
|
||||
maven {url "https://repo.maven.apache.org/maven2"}
|
||||
maven {url "http://ci.frostcast.net/plugin/repository/everything"}
|
||||
maven {url "http://maven.sk89q.com/artifactory/repo"}
|
||||
maven {url "http://repo.spongepowered.org/maven"}
|
||||
maven {url "http://dl.bintray.com/tastybento/maven-repo"}
|
||||
maven {url "https://repo.inventivetalent.org/content/groups/public/"}
|
||||
maven {url "https://store.ttyh.ru/libraries/"}
|
||||
maven {url "https://repo.dmulloy2.net/nexus/repository/public/"}
|
||||
maven {url "http://maven.elmakers.com/repository/"}
|
||||
maven {url "https://ci.ender.zone/plugin/repository/everything/"}
|
||||
maven {url "https://plotsquared.com/mvn/"}
|
||||
}
|
||||
}
|
||||
task aggregatedJavadocs(type: Javadoc, description: 'Generate javadocs from all child projects as if it was a single project', group: 'Documentation') {
|
||||
destinationDir = file("./docs/javadoc")
|
||||
title = "$project.name $version API"
|
||||
options.author true
|
||||
options.links 'http://docs.spring.io/spring/docs/4.3.x/javadoc-api/', 'http://docs.oracle.com/javase/8/docs/api/', 'http://docs.spring.io/spring-ws/docs/2.3.0.RELEASE/api/', 'http://docs.spring.io/spring-security/site/docs/4.0.4.RELEASE/apidocs/'
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
|
||||
delete "./docs"
|
||||
|
||||
subprojects.each { proj ->
|
||||
proj.tasks.withType(Javadoc).each { javadocTask ->
|
||||
source += javadocTask.source
|
||||
classpath += javadocTask.classpath
|
||||
excludes += javadocTask.excludes
|
||||
includes += javadocTask.includes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,20 +3,21 @@ repositories {
|
||||
}
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'com.sk89q:worldguard:6.0.0-SNAPSHOT'
|
||||
compile('com.destroystokyo.paper:paper-api:1.12-R0.1-SNAPSHOT') {
|
||||
exclude group: 'net.md-5'
|
||||
}
|
||||
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
|
||||
compile 'org.bukkit.craftbukkitv1_11:Craftbukkit:1.11'
|
||||
// compile 'org.bukkit.craftbukkitv1_12:Craftbukkit:1.12'
|
||||
compile 'org.bukkit.craftbukkitv1_12_R1:Craftbukkit:1.12.1'
|
||||
compile 'net.milkbowl.vault:VaultAPI:1.5'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit_1_12:1.12.1'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit_1_11:1.11'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit_1_10:1.10'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit_1_9:1.9.4'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit_1_8:1.8.8'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit_1_7:1.7.10'
|
||||
compile 'net.milkbowl.vault:VaultAPI:1.5.6'
|
||||
compile 'com.massivecraft:factions:2.8.0'
|
||||
compile 'com.drtshock:factions:1.6.9.5'
|
||||
compile 'com.factionsone:FactionsOne:1.2.2'
|
||||
compile 'me.ryanhamshire:GriefPrevention:11.5.2'
|
||||
compile 'com.massivecraft:mcore:7.0.1'
|
||||
compile 'net.sacredlabyrinth.Phaed:PreciousStones:10.0.4-SNAPSHOT'
|
||||
compile 'net.jzx7:regios:5.9.9'
|
||||
compile 'com.bekvon.bukkit.residence:Residence:4.5._13.1'
|
||||
compile 'com.palmergames.bukkit:towny:0.84.0.9'
|
||||
@ -25,12 +26,15 @@ dependencies {
|
||||
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.4-SNAPSHOT'
|
||||
compile 'com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT'
|
||||
compile 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
|
||||
compile 'org.bukkit.craftbukkit.v1_9R2:craftbukkitv1_9R2:1.9.4'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit:1.7.10'
|
||||
compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8'
|
||||
compile 'com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT'
|
||||
compile 'com.comphenix.protocol:ProtocolLib-API:4.4.0'
|
||||
compile 'com.wasteofplastic:askyblock:3.0.8.2'
|
||||
compile('org.inventivetalent:mapmanager:1.7.2-SNAPSHOT') {
|
||||
transitive = false
|
||||
}
|
||||
}
|
||||
|
||||
clean { delete "../target" }
|
||||
|
||||
processResources {
|
||||
from('src/main/resources') {
|
||||
include 'plugin.yml'
|
||||
@ -41,12 +45,46 @@ processResources {
|
||||
}
|
||||
}
|
||||
|
||||
jar.archiveName="fawe-bukkit-${project.parent.version}.jar"
|
||||
jar.destinationDir = file '../mvn/com/boydti/fawe-bukkit/' + project.parent.version
|
||||
task createPom << {
|
||||
pom {
|
||||
project {
|
||||
groupId 'com.boydti'
|
||||
artifactId 'fawe-bukkit'
|
||||
version project.parent.version
|
||||
}
|
||||
}
|
||||
.getEffectivePom()
|
||||
.setDependencies(new ArrayList<>())
|
||||
.writeTo("../mvn/com/boydti/fawe-bukkit/${project.parent.version}/fawe-bukkit-${project.parent.version}.pom")
|
||||
pom {
|
||||
project {
|
||||
groupId 'com.boydti'
|
||||
artifactId 'fawe-bukkit'
|
||||
version 'latest'
|
||||
}
|
||||
}
|
||||
.getEffectivePom()
|
||||
.setDependencies(new ArrayList<>())
|
||||
.writeTo("../mvn/com/boydti/fawe-bukkit/latest/fawe-bukkit-latest.pom")
|
||||
}
|
||||
task copyFiles {
|
||||
doLast {
|
||||
copy {
|
||||
from "../mvn/com/boydti/fawe-bukkit/${project.parent.version}/"
|
||||
into '../mvn/com/boydti/fawe-bukkit/latest/'
|
||||
include('*.jar')
|
||||
rename ("fawe-bukkit-${project.parent.version}.jar", 'fawe-bukkit-latest.jar')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
// We only want the shadow jar produced
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
// include(dependency('org.javassist:javassist:3.22.0-CR1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
}
|
||||
@ -59,4 +97,4 @@ shadowJar.doLast {
|
||||
ant.checksum file: task.archivePath
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar);
|
||||
build.dependsOn(shadowJar);
|
||||
|
@ -29,10 +29,12 @@ public class BukkitMain extends JavaPlugin {
|
||||
pluginsField.set(manager, new ArrayList<Plugin>(plugins) {
|
||||
@Override
|
||||
public boolean add(Plugin plugin) {
|
||||
if (!plugin.getName().startsWith("AsyncWorldEdit")) {
|
||||
return super.add(plugin);
|
||||
} else {
|
||||
if (plugin.getName().startsWith("AsyncWorldEdit")) {
|
||||
Fawe.debug("Disabling `" + plugin.getName() + "` as it is incompatible");
|
||||
} else if (plugin.getName().startsWith("BetterShutdown")) {
|
||||
Fawe.debug("Disabling `" + plugin.getName() + "` as it is incompatible (Improperly shaded classes from com.sk89q.minecraft.util.commands)");
|
||||
} else {
|
||||
return super.add(plugin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -40,10 +42,11 @@ public class BukkitMain extends JavaPlugin {
|
||||
lookupNamesField.set(manager, new ConcurrentHashMap<String, Plugin>(lookupNames) {
|
||||
@Override
|
||||
public Plugin put(String key, Plugin plugin) {
|
||||
if (!plugin.getName().startsWith("AsyncWorldEdit")) {
|
||||
return super.put(key, plugin);
|
||||
if (plugin.getName().startsWith("AsyncWorldEdit") || plugin.getName().startsWith("BetterShutdown")) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return super.put(key, plugin);
|
||||
|
||||
}
|
||||
});
|
||||
} catch (Throwable ignore) {}
|
||||
@ -75,4 +78,9 @@ public class BukkitMain extends JavaPlugin {
|
||||
Bukkit.getPluginManager().enablePlugin(toLoad);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
Fawe.get().onDisable();
|
||||
}
|
||||
}
|
@ -35,6 +35,11 @@ public class BukkitPlayer extends FawePlayer<Player> {
|
||||
return this.parent.hasPermission(perm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSneaking() {
|
||||
return parent.isSneaking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermission(final String perm, final boolean flag) {
|
||||
/*
|
||||
|
@ -4,27 +4,21 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.IFawe;
|
||||
import com.boydti.fawe.bukkit.chat.BukkitChatManager;
|
||||
import com.boydti.fawe.bukkit.listener.BrushListener;
|
||||
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
||||
import com.boydti.fawe.bukkit.listener.CFIPacketListener;
|
||||
import com.boydti.fawe.bukkit.listener.RenderListener;
|
||||
import com.boydti.fawe.bukkit.regions.FactionsFeature;
|
||||
import com.boydti.fawe.bukkit.regions.FactionsOneFeature;
|
||||
import com.boydti.fawe.bukkit.regions.FactionsUUIDFeature;
|
||||
import com.boydti.fawe.bukkit.regions.GriefPreventionFeature;
|
||||
import com.boydti.fawe.bukkit.regions.PlotMeFeature;
|
||||
import com.boydti.fawe.bukkit.regions.PreciousStonesFeature;
|
||||
import com.boydti.fawe.bukkit.regions.ResidenceFeature;
|
||||
import com.boydti.fawe.bukkit.regions.TownyFeature;
|
||||
import com.boydti.fawe.bukkit.regions.Worldguard;
|
||||
import com.boydti.fawe.bukkit.regions.*;
|
||||
import com.boydti.fawe.bukkit.util.BukkitReflectionUtils;
|
||||
import com.boydti.fawe.bukkit.util.BukkitTaskMan;
|
||||
import com.boydti.fawe.bukkit.util.ItemUtil;
|
||||
import com.boydti.fawe.bukkit.util.VaultUtil;
|
||||
import com.boydti.fawe.bukkit.util.cui.CUIListener;
|
||||
import com.boydti.fawe.bukkit.util.cui.StructureCUI;
|
||||
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
||||
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
||||
import com.boydti.fawe.bukkit.v0.ChunkListener;
|
||||
import com.boydti.fawe.bukkit.v0.ChunkListener_8;
|
||||
import com.boydti.fawe.bukkit.v0.ChunkListener_9;
|
||||
import com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10;
|
||||
import com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11;
|
||||
import com.boydti.fawe.bukkit.v1_12.BukkitQueue_1_12;
|
||||
@ -38,10 +32,7 @@ import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.Jars;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
@ -100,13 +91,16 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
public FaweBukkit(BukkitMain plugin) {
|
||||
this.plugin = plugin;
|
||||
try {
|
||||
Settings.IMP.TICK_LIMITER.ENABLED = !Bukkit.hasWhitelist();
|
||||
Fawe.set(this);
|
||||
setupInjector();
|
||||
try {
|
||||
com.sk89q.worldedit.bukkit.BukkitPlayer.inject(); // Fixes
|
||||
BukkitWorld.inject(); // Fixes
|
||||
BukkitPlayerBlockBag.inject(); // features
|
||||
FallbackRegistrationListener.inject(); // Fixes
|
||||
try {
|
||||
FallbackRegistrationListener.inject(); // Fixes
|
||||
} catch (Throwable ignore) {} // Not important at all
|
||||
} catch (Throwable e) {
|
||||
debug("========= INJECTOR FAILED =========");
|
||||
e.printStackTrace();
|
||||
@ -126,7 +120,7 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
debug(" - This is only a recommendation");
|
||||
debug("==============================");
|
||||
}
|
||||
if (Bukkit.getVersion().contains("git-Paper") && Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING) {
|
||||
if (Bukkit.getVersion().contains("git-Paper") && Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING > 1) {
|
||||
new RenderListener(plugin);
|
||||
}
|
||||
try {
|
||||
@ -147,7 +141,12 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
Bukkit.getPluginManager().registerEvents(FaweBukkit.this, FaweBukkit.this.plugin);
|
||||
|
||||
// The tick limiter
|
||||
new ChunkListener();
|
||||
try {
|
||||
Class.forName("sun.misc.SharedSecrets");
|
||||
new ChunkListener_8();
|
||||
} catch (ClassNotFoundException e) {
|
||||
new ChunkListener_9();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -170,15 +169,21 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPacketListener() {
|
||||
PluginManager manager = Bukkit.getPluginManager();
|
||||
if (packetListener == null && manager.getPlugin("ProtocolLib") != null) {
|
||||
packetListener = new CFIPacketListener(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ImageViewer getImageViewer(FawePlayer fp) {
|
||||
if (listeningImages && imageListener == null) return null;
|
||||
try {
|
||||
listeningImages = true;
|
||||
registerPacketListener();
|
||||
PluginManager manager = Bukkit.getPluginManager();
|
||||
if (manager.getPlugin("ProtocolLib") != null) {
|
||||
packetListener = new CFIPacketListener(plugin);
|
||||
}
|
||||
|
||||
if (manager.getPlugin("PacketListenerApi") == null) {
|
||||
File output = new File(plugin.getDataFolder().getParentFile(), "PacketListenerAPI_v3.6.0-SNAPSHOT.jar");
|
||||
@ -343,11 +348,11 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
public String getDebugInfo() {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
List<String> pl = new ArrayList<>();
|
||||
msg.append("server.plugins: \n");
|
||||
msg.append("Server Version: " + Bukkit.getVersion() + "\n");
|
||||
msg.append("Plugins: \n");
|
||||
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
|
||||
msg.append(" - " + p.getName() + ": " + p.getDescription().getVersion() + "\n");
|
||||
}
|
||||
msg.append("server.version: " + Bukkit.getVersion() + " / " + Bukkit.getBukkitVersion() + "\n");
|
||||
return msg.toString();
|
||||
}
|
||||
|
||||
@ -366,7 +371,7 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
public FaweQueue getNewQueue(String world, boolean fast) {
|
||||
if (playerChunk != (playerChunk = true)) {
|
||||
try {
|
||||
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
||||
Field fieldDirtyCount = BukkitReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
||||
fieldDirtyCount.setAccessible(true);
|
||||
int mod = fieldDirtyCount.getModifiers();
|
||||
if ((mod & Modifier.VOLATILE) == 0) {
|
||||
@ -419,7 +424,7 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
if (fast) {
|
||||
if (playerChunk != (playerChunk = true)) {
|
||||
try {
|
||||
Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
||||
Field fieldDirtyCount = BukkitReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField();
|
||||
fieldDirtyCount.setAccessible(true);
|
||||
int mod = fieldDirtyCount.getModifiers();
|
||||
if ((mod & Modifier.VOLATILE) == 0) {
|
||||
@ -512,16 +517,10 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
Fawe.debug("Plugin 'Factions' found. Using it now.");
|
||||
} catch (final Throwable e) {
|
||||
try {
|
||||
managers.add(new FactionsUUIDFeature(factionsPlugin, this));
|
||||
managers.add(new FactionsOneFeature(factionsPlugin, this));
|
||||
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
||||
} catch (Throwable e2) {
|
||||
try {
|
||||
managers.add(new FactionsOneFeature(factionsPlugin, this));
|
||||
Fawe.debug("Plugin 'FactionsUUID' found. Using it now.");
|
||||
} catch (Throwable e3) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
|
||||
} catch (Throwable e3) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -543,15 +542,26 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
final Plugin preciousstonesPlugin = Bukkit.getServer().getPluginManager().getPlugin("PreciousStones");
|
||||
if ((preciousstonesPlugin != null) && preciousstonesPlugin.isEnabled()) {
|
||||
|
||||
final Plugin aSkyBlock = Bukkit.getServer().getPluginManager().getPlugin("ASkyBlock");
|
||||
if ((aSkyBlock != null) && aSkyBlock.isEnabled()) {
|
||||
try {
|
||||
managers.add(new PreciousStonesFeature(preciousstonesPlugin, this));
|
||||
Fawe.debug("Plugin 'PreciousStones' found. Using it now.");
|
||||
managers.add(new ASkyBlockHook(aSkyBlock, this));
|
||||
Fawe.debug("Plugin 'ASkyBlock' found. Using it now.");
|
||||
} catch (final Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.IMP.EXPERIMENTAL.FREEBUILD) {
|
||||
try {
|
||||
managers.add(new FreeBuildRegion());
|
||||
Fawe.debug("Plugin '<internal.freebuild>' found. Using it now.");
|
||||
} catch (final Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return managers;
|
||||
}
|
||||
//
|
||||
@ -572,11 +582,12 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
FawePlayer fp = FawePlayer.wrap(player);
|
||||
String name = player.getName();
|
||||
FawePlayer fp = Fawe.get().getCachedPlayer(name);
|
||||
if (fp != null) {
|
||||
fp.unregister();
|
||||
Fawe.get().unregister(name);
|
||||
}
|
||||
Fawe.get().unregister(event.getPlayer().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -609,6 +620,11 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
return ((BlocksHubBukkit) blocksHubPlugin).getApi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMainThread() {
|
||||
return Bukkit.isPrimaryThread();
|
||||
}
|
||||
|
||||
private Version version = null;
|
||||
|
||||
public Version getVersion() {
|
||||
@ -621,7 +637,7 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
this.version = tmp = v;
|
||||
if (tmp == Version.v1_12_R1) {
|
||||
try {
|
||||
Fawe.debug("Running 1.12 registry dumper!");
|
||||
System.out.println("Running 1.12 registry dumper!");
|
||||
NMSRegistryDumper dumper = new NMSRegistryDumper(MainUtil.getFile(plugin.getDataFolder(), "extrablocks.json"));
|
||||
dumper.run();
|
||||
} catch (Throwable e) {
|
||||
|
@ -49,17 +49,29 @@ public class BrushBoundBaseBlock extends BaseBlock implements BrushHolder {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
private static final ThreadLocal<Boolean> RECURSION = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public BrushTool getTool() {
|
||||
if (tool == null && hasNbtData()) {
|
||||
StringTag json = (StringTag) getNbtData().getValue().get("weBrushJson");
|
||||
if (json != null) {
|
||||
try {
|
||||
if (RECURSION.get() != null) return null;
|
||||
RECURSION.set(true);
|
||||
|
||||
this.tool = BrushTool.fromString(player, session, json.getValue());
|
||||
this.tool.setHolder(this);
|
||||
brushCache.put(getKey(item), tool);
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
Fawe.debug("Invalid brush for " + player + " holding " + item.getType() + ": " + json.getValue());
|
||||
if (item != null) {
|
||||
item = Fawe.<FaweBukkit>imp().getItemUtil().setNBT(item, null);
|
||||
brushCache.remove(getKey(item));
|
||||
}
|
||||
} finally {
|
||||
RECURSION.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class BukkitChatManager implements ChatManager<FancyMessage> {
|
||||
|
||||
@Override
|
||||
public void send(Message Message, FawePlayer player) {
|
||||
if (player == FakePlayer.getConsole().toFawePlayer()) {
|
||||
if (!(player instanceof BukkitPlayer)) {
|
||||
player.sendMessage(Message.$(this).toOldMessageFormat());
|
||||
} else {
|
||||
Message.$(this).send(((BukkitPlayer) player).parent);
|
||||
|
@ -2,11 +2,11 @@ package com.boydti.fawe.bukkit.listener;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.command.CFICommands;
|
||||
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal3;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
@ -42,7 +42,7 @@ import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* The CFIPacketListener handles packets for editing the HeightMapMCAGenerator
|
||||
* The CFIPacketListener handles packets for editing the VirtualWorld
|
||||
* The generator is a virtual world which only the creator can see
|
||||
* - The virtual world is displayed inside the current world
|
||||
* - Block/Chunk/Movement packets need to be handled properly
|
||||
@ -57,9 +57,9 @@ public class CFIPacketListener implements Listener {
|
||||
this.protocolmanager = ProtocolLibrary.getProtocolManager();
|
||||
|
||||
// Direct digging to the virtual world
|
||||
registerBlockEvent(PacketType.Play.Client.BLOCK_DIG, false, new RunnableVal3<PacketEvent, HeightMapMCAGenerator, Vector>() {
|
||||
registerBlockEvent(PacketType.Play.Client.BLOCK_DIG, false, new RunnableVal3<PacketEvent, VirtualWorld, Vector>() {
|
||||
@Override
|
||||
public void run(PacketEvent event, HeightMapMCAGenerator gen, Vector pt) {
|
||||
public void run(PacketEvent event, VirtualWorld gen, Vector pt) {
|
||||
try {
|
||||
Player plr = event.getPlayer();
|
||||
Vector realPos = pt.add(gen.getOrigin());
|
||||
@ -73,9 +73,9 @@ public class CFIPacketListener implements Listener {
|
||||
});
|
||||
|
||||
// Direct placing to the virtual world
|
||||
RunnableVal3<PacketEvent, HeightMapMCAGenerator, Vector> placeTask = new RunnableVal3<PacketEvent, HeightMapMCAGenerator, Vector>() {
|
||||
RunnableVal3<PacketEvent, VirtualWorld, Vector> placeTask = new RunnableVal3<PacketEvent, VirtualWorld, Vector>() {
|
||||
@Override
|
||||
public void run(PacketEvent event, HeightMapMCAGenerator gen, Vector pt) {
|
||||
public void run(PacketEvent event, VirtualWorld gen, Vector pt) {
|
||||
try {
|
||||
Player plr = event.getPlayer();
|
||||
List<EnumWrappers.Hand> hands = event.getPacket().getHands().getValues();
|
||||
@ -99,9 +99,9 @@ public class CFIPacketListener implements Listener {
|
||||
registerBlockEvent(PacketType.Play.Client.USE_ITEM, true, placeTask);
|
||||
|
||||
// Cancel block change packets where the real world overlaps with the virtual one
|
||||
registerBlockEvent(PacketType.Play.Server.BLOCK_CHANGE, false, new RunnableVal3<PacketEvent, HeightMapMCAGenerator, Vector>() {
|
||||
registerBlockEvent(PacketType.Play.Server.BLOCK_CHANGE, false, new RunnableVal3<PacketEvent, VirtualWorld, Vector>() {
|
||||
@Override
|
||||
public void run(PacketEvent event, HeightMapMCAGenerator gen, Vector pt) {
|
||||
public void run(PacketEvent event, VirtualWorld gen, Vector pt) {
|
||||
// Do nothing
|
||||
}
|
||||
});
|
||||
@ -112,7 +112,7 @@ public class CFIPacketListener implements Listener {
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
if (!event.isServerPacket()) return;
|
||||
|
||||
HeightMapMCAGenerator gen = getGenerator(event);
|
||||
VirtualWorld gen = getGenerator(event);
|
||||
if (gen != null) {
|
||||
Vector origin = gen.getOrigin();
|
||||
PacketContainer packet = event.getPacket();
|
||||
@ -123,7 +123,7 @@ public class CFIPacketListener implements Listener {
|
||||
int ocx = origin.getBlockX() >> 4;
|
||||
int ocz = origin.getBlockZ() >> 4;
|
||||
|
||||
if (gen.contain(new Vector((cx - ocx) << 4, 0, (cz - ocz) << 4))) {
|
||||
if (gen.contains(new Vector((cx - ocx) << 4, 0, (cz - ocz) << 4))) {
|
||||
event.setCancelled(true);
|
||||
|
||||
Player plr = event.getPlayer();
|
||||
@ -147,7 +147,7 @@ public class CFIPacketListener implements Listener {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Location pos = player.getLocation();
|
||||
HeightMapMCAGenerator gen = getGenerator(event);
|
||||
VirtualWorld gen = getGenerator(event);
|
||||
if (gen != null) {
|
||||
Vector origin = gen.getOrigin();
|
||||
Vector pt = new Vector(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||
@ -158,7 +158,7 @@ public class CFIPacketListener implements Listener {
|
||||
int my = ints.read(2);
|
||||
int mz = ints.read(3);
|
||||
|
||||
if (gen.contain(pt.subtract(origin)) && mx == 0 && my == 0 && mz == 0) {
|
||||
if (gen.contains(pt.subtract(origin)) && mx == 0 && my == 0 && mz == 0) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -172,7 +172,7 @@ public class CFIPacketListener implements Listener {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Location pos = player.getLocation();
|
||||
HeightMapMCAGenerator gen = getGenerator(event);
|
||||
VirtualWorld gen = getGenerator(event);
|
||||
if (gen != null) {
|
||||
Vector origin = gen.getOrigin();
|
||||
Vector from = new Vector(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||
@ -180,7 +180,7 @@ public class CFIPacketListener implements Listener {
|
||||
PacketContainer packet = event.getPacket();
|
||||
StructureModifier<Double> doubles = packet.getDoubles();
|
||||
Vector to = new Vector(doubles.read(0), doubles.read(1), doubles.read(2));
|
||||
if (gen.contain(to.subtract(origin)) && from.distanceSq(to) < 8) {
|
||||
if (gen.contains(to.subtract(origin)) && from.distanceSq(to) < 8) {
|
||||
int id = packet.getIntegers().read(0);
|
||||
PacketContainer reply = new PacketContainer(PacketType.Play.Client.TELEPORT_ACCEPT);
|
||||
reply.getIntegers().write(0, id);
|
||||
@ -202,14 +202,14 @@ public class CFIPacketListener implements Listener {
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
if (!event.isServerPacket()) return;
|
||||
|
||||
HeightMapMCAGenerator gen = getGenerator(event);
|
||||
VirtualWorld gen = getGenerator(event);
|
||||
if (gen != null) {
|
||||
PacketContainer packet = event.getPacket();
|
||||
ChunkCoordIntPair chunk = packet.getChunkCoordIntPairs().read(0);
|
||||
Vector origin = gen.getOrigin();
|
||||
int cx = chunk.getChunkX() - (origin.getBlockX() >> 4);
|
||||
int cz = chunk.getChunkZ() - (origin.getBlockX() >> 4);
|
||||
if (gen.contain(new Vector(cx << 4, 0, cz << 4))) {
|
||||
if (gen.contains(new Vector(cx << 4, 0, cz << 4))) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -220,7 +220,7 @@ public class CFIPacketListener implements Listener {
|
||||
@EventHandler
|
||||
public void onTeleport(PlayerTeleportEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
HeightMapMCAGenerator gen = getGenerator(player);
|
||||
VirtualWorld gen = getGenerator(player);
|
||||
if (gen != null) {
|
||||
Location from = event.getFrom();
|
||||
Location to = event.getTo();
|
||||
@ -232,7 +232,7 @@ public class CFIPacketListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean sendBlockChange(Player plr, HeightMapMCAGenerator gen, Vector pt, Interaction action) {
|
||||
private boolean sendBlockChange(Player plr, VirtualWorld gen, Vector pt, Interaction action) {
|
||||
PlatformManager platform = WorldEdit.getInstance().getPlatformManager();
|
||||
com.sk89q.worldedit.entity.Player actor = FawePlayer.wrap(plr).getPlayer();
|
||||
com.sk89q.worldedit.util.Location location = new com.sk89q.worldedit.util.Location(actor.getWorld(), pt);
|
||||
@ -261,19 +261,22 @@ public class CFIPacketListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private HeightMapMCAGenerator getGenerator(PacketEvent event) {
|
||||
private VirtualWorld getGenerator(PacketEvent event) {
|
||||
return getGenerator(event.getPlayer());
|
||||
}
|
||||
|
||||
private HeightMapMCAGenerator getGenerator(Player player) {
|
||||
CFICommands.CFISettings settings = FawePlayer.wrap(player).getMeta("CFISettings");
|
||||
private VirtualWorld getGenerator(Player player) {
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
VirtualWorld vw = fp.getSession().getVirtualWorld();
|
||||
if (vw != null) return vw;
|
||||
CFICommands.CFISettings settings = fp.getMeta("CFISettings");
|
||||
if (settings != null && settings.hasGenerator() && settings.getGenerator().hasPacketViewer()) {
|
||||
return settings.getGenerator();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Vector getRelPos(PacketEvent event, HeightMapMCAGenerator generator) {
|
||||
private Vector getRelPos(PacketEvent event, VirtualWorld generator) {
|
||||
PacketContainer packet = event.getPacket();
|
||||
StructureModifier<BlockPosition> position = packet.getBlockPositionModifier();
|
||||
BlockPosition loc = position.readSafely(0);
|
||||
@ -283,13 +286,13 @@ public class CFIPacketListener implements Listener {
|
||||
return pt;
|
||||
}
|
||||
|
||||
private void handleBlockEvent(PacketEvent event, boolean relative, RunnableVal3<PacketEvent, HeightMapMCAGenerator, Vector> task) {
|
||||
HeightMapMCAGenerator gen = getGenerator(event);
|
||||
private void handleBlockEvent(PacketEvent event, boolean relative, RunnableVal3<PacketEvent, VirtualWorld, Vector> task) {
|
||||
VirtualWorld gen = getGenerator(event);
|
||||
if (gen != null) {
|
||||
Vector pt = getRelPos(event, gen);
|
||||
if (pt != null) {
|
||||
if (relative) pt = getRelative(event, pt);
|
||||
if (gen.contain(pt)) {
|
||||
if (gen.contains(pt)) {
|
||||
event.setCancelled(true);
|
||||
task.run(event, gen, pt);
|
||||
}
|
||||
@ -297,7 +300,7 @@ public class CFIPacketListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private void registerBlockEvent(PacketType type, boolean relative, RunnableVal3<PacketEvent, HeightMapMCAGenerator, Vector> task) {
|
||||
private void registerBlockEvent(PacketType type, boolean relative, RunnableVal3<PacketEvent, VirtualWorld, Vector> task) {
|
||||
protocolmanager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, type) {
|
||||
@Override
|
||||
public void onPacketReceiving(final PacketEvent event) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.bukkit.listener;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import java.util.Iterator;
|
||||
@ -76,7 +77,7 @@ public class RenderListener implements Listener {
|
||||
|
||||
public void setViewDistance(Player player, int value) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (value == 10) {
|
||||
if (value == Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING) {
|
||||
views.remove(uuid);
|
||||
} else {
|
||||
int[] val = views.get(uuid);
|
||||
@ -100,7 +101,7 @@ public class RenderListener implements Listener {
|
||||
|
||||
public int getViewDistance(Player player) {
|
||||
int[] value = views.get(player.getUniqueId());
|
||||
return value == null ? 10 : value[0];
|
||||
return value == null ? Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING : value[0];
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.boydti.fawe.bukkit.regions;
|
||||
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.regions.FaweMask;
|
||||
import com.wasteofplastic.askyblock.ASkyBlockAPI;
|
||||
import com.wasteofplastic.askyblock.Island;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class ASkyBlockHook extends BukkitMaskManager implements Listener {
|
||||
FaweBukkit plugin;
|
||||
Plugin aSkyBlock;
|
||||
|
||||
public ASkyBlockHook(final Plugin aSkyBlock, final FaweBukkit p3) {
|
||||
super(aSkyBlock.getName());
|
||||
this.aSkyBlock = aSkyBlock;
|
||||
this.plugin = p3;
|
||||
|
||||
}
|
||||
|
||||
public boolean isAllowed(Player player, Island island, MaskType type) {
|
||||
return island != null && (player.getUniqueId().equals(island.getOwner()) || (type == MaskType.MEMBER && island.getMembers().contains(player.getUniqueId()) && hasMemberPermission(player)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweMask getMask(final FawePlayer<Player> fp, MaskType type) {
|
||||
final Player player = fp.parent;
|
||||
final Location location = player.getLocation();
|
||||
|
||||
Island island = ASkyBlockAPI.getInstance().getIslandAt(location);
|
||||
if (island != null && isAllowed(player, island, type)) {
|
||||
int minX = island.getMinProtectedX();
|
||||
int minZ = island.getMinProtectedZ();
|
||||
|
||||
World world = location.getWorld();
|
||||
Location center = island.getCenter();
|
||||
Location pos1 = new Location(world, island.getMinProtectedX(), 0, island.getMinProtectedZ());
|
||||
Location pos2 = center.add(center.subtract(pos1));
|
||||
pos2.setY(255);
|
||||
|
||||
return new BukkitMask(pos1, pos2, "ISLAND: " + minX + "," + minZ) {
|
||||
@Override
|
||||
public boolean isValid(FawePlayer player, MaskType type) {
|
||||
return isAllowed((Player) player.parent, island, type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -7,6 +7,10 @@ import org.bukkit.Location;
|
||||
public class BukkitMask extends FaweMask {
|
||||
|
||||
public BukkitMask(Location pos1, Location pos2) {
|
||||
super(new BlockVector(pos1.getBlockX(), pos1.getBlockY(), pos1.getBlockZ()), new BlockVector(pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ()));
|
||||
this(pos1, pos2, null);
|
||||
}
|
||||
|
||||
public BukkitMask(Location pos1, Location pos2, String name) {
|
||||
super(new BlockVector(pos1.getBlockX(), pos1.getBlockY(), pos1.getBlockZ()), new BlockVector(pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ()), name);
|
||||
}
|
||||
}
|
@ -8,4 +8,8 @@ public abstract class BukkitMaskManager extends FaweMaskManager<Player> {
|
||||
public BukkitMaskManager(final String plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
public boolean hasMemberPermission(Player player) {
|
||||
return player.hasPermission("fawe." + getKey() + ".member");
|
||||
}
|
||||
}
|
||||
|
@ -1,104 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.regions;
|
||||
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.util.Perm;
|
||||
import com.massivecraft.factions.Board;
|
||||
import com.massivecraft.factions.FLocation;
|
||||
import com.massivecraft.factions.Faction;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class FactionsUUIDFeature extends BukkitMaskManager implements Listener {
|
||||
private final Board instance;
|
||||
|
||||
public FactionsUUIDFeature(final Plugin factionsPlugin, final FaweBukkit p3) {
|
||||
super(factionsPlugin.getName());
|
||||
this.instance = Board.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitMask getMask(final FawePlayer<Player> fp, MaskType type) {
|
||||
final Player player = fp.parent;
|
||||
final Chunk chunk = player.getLocation().getChunk();
|
||||
final boolean perm = Perm.hasPermission(FawePlayer.wrap(player), "fawe.factions.wilderness");
|
||||
final World world = player.getWorld();
|
||||
|
||||
RegionWrapper locs = new RegionWrapper(chunk.getX(), chunk.getX(), chunk.getZ(), chunk.getZ());
|
||||
|
||||
int count = 32;
|
||||
|
||||
if (this.isAdded(locs, world, player, perm, type)) {
|
||||
boolean hasPerm = true;
|
||||
|
||||
RegionWrapper chunkSelection;
|
||||
while (hasPerm && (count > 0)) {
|
||||
count--;
|
||||
|
||||
hasPerm = false;
|
||||
|
||||
chunkSelection = new RegionWrapper(locs.maxX + 1, locs.maxX + 1, locs.minZ, locs.maxZ);
|
||||
|
||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
||||
locs = new RegionWrapper(locs.minX, locs.maxX + 1, locs.minZ, locs.maxZ);
|
||||
hasPerm = true;
|
||||
}
|
||||
|
||||
chunkSelection = new RegionWrapper(locs.minX - 1, locs.minX - 1, locs.minZ, locs.maxZ);
|
||||
|
||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
||||
locs = new RegionWrapper(locs.minX - 1, locs.maxX, locs.minZ, locs.maxZ);
|
||||
hasPerm = true;
|
||||
}
|
||||
|
||||
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.maxZ + 1, locs.maxZ + 1);
|
||||
|
||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
||||
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ, locs.maxZ + 1);
|
||||
hasPerm = true;
|
||||
}
|
||||
|
||||
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.minZ - 1);
|
||||
|
||||
if (this.isAdded(chunkSelection, world, player, perm, type)) {
|
||||
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.maxZ);
|
||||
hasPerm = true;
|
||||
}
|
||||
}
|
||||
|
||||
final Location pos1 = new Location(world, locs.minX << 4, 1, locs.minZ << 4);
|
||||
final Location pos2 = new Location(world, 15 + (locs.maxX << 4), 256, 15 + (locs.maxZ << 4));
|
||||
return new BukkitMask(pos1, pos2) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "CHUNK:" + pos1.getChunk().getX() + "," + pos1.getChunk().getZ();
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isAdded(final RegionWrapper locs, final World world, final Player player, final boolean perm, MaskType type) {
|
||||
for (int x = locs.minX; x <= locs.maxX; x++) {
|
||||
for (int z = locs.minZ; z <= locs.maxZ; z++) {
|
||||
final Faction fac = this.instance.getFactionAt(new FLocation(world.getName(), x, z));
|
||||
if (fac == null) {
|
||||
return false;
|
||||
}
|
||||
// TODO types
|
||||
if (!fac.getOnlinePlayers().contains(player)) {
|
||||
return false;
|
||||
}
|
||||
if (fac.isWilderness() && !perm) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.boydti.fawe.bukkit.regions;
|
||||
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.queue.NullFaweQueue;
|
||||
import com.boydti.fawe.regions.FaweMask;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FreeBuildRegion extends BukkitMaskManager {
|
||||
private final ArrayList<RegisteredListener> listeners;
|
||||
|
||||
public FreeBuildRegion() {
|
||||
super("freebuild");
|
||||
this.listeners = new ArrayList<>();
|
||||
RegisteredListener[] listeners = BlockBreakEvent.getHandlerList().getRegisteredListeners();
|
||||
for (RegisteredListener listener : listeners) {
|
||||
if (listener.getPriority() == EventPriority.MONITOR) continue;
|
||||
if (!listener.isIgnoringCancelled()) continue;
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweMask getMask(FawePlayer<Player> player, MaskType type) {
|
||||
if (type != MaskType.MEMBER) return null;
|
||||
ArrayList<RegisteredListener> currRegList = new ArrayList<>();
|
||||
for (RegisteredListener listener : this.listeners) {
|
||||
String name = listener.getPlugin().getName();
|
||||
if (!player.hasPermission("fawe.freebuild." + name.toLowerCase())) continue;
|
||||
currRegList.add(listener);
|
||||
}
|
||||
if (currRegList.isEmpty()) return null;
|
||||
RegisteredListener[] listeners = currRegList.toArray(new RegisteredListener[currRegList.size()]);
|
||||
|
||||
World bukkitWorld = player.parent.getWorld();
|
||||
AsyncWorld asyncWorld = AsyncWorld.wrap(bukkitWorld);
|
||||
|
||||
Vector vec1 = new Vector(0, 0, 0);
|
||||
Vector vec2 = vec1;
|
||||
Location pos1 = BukkitUtil.toLocation(bukkitWorld, vec1);
|
||||
Location pos2 = BukkitUtil.toLocation(bukkitWorld, vec2);
|
||||
|
||||
AsyncBlock block = new AsyncBlock(asyncWorld, new NullFaweQueue(asyncWorld.getWorldName()), 0, 0, 0);
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player.parent);
|
||||
|
||||
return new BukkitMask(pos1, pos2) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "freebuild-global";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(FawePlayer player, MaskType type) {
|
||||
return bukkitWorld == ((FawePlayer<Player>)player).parent.getWorld() && type == MaskType.MEMBER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region getRegion() {
|
||||
return new CuboidRegion(vec1, vec2) {
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int z) {
|
||||
return contains(x, 127, z);
|
||||
}
|
||||
|
||||
private int lastX = Integer.MIN_VALUE, lastZ = Integer.MIN_VALUE;
|
||||
private boolean lastResult;
|
||||
|
||||
@Override
|
||||
public boolean contains(int x, int y, int z) {
|
||||
if (x == lastX && z == lastZ) return lastResult;
|
||||
lastX = x;
|
||||
lastZ = z;
|
||||
event.setCancelled(false);
|
||||
block.setPosition(x, y, z);
|
||||
try {
|
||||
synchronized (Bukkit.getPluginManager()) {
|
||||
for (RegisteredListener listener : listeners) {
|
||||
listener.callEvent(event);
|
||||
}
|
||||
}
|
||||
} catch (EventException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return lastResult = !event.isCancelled();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.regions;
|
||||
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.regions.FaweMask;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import java.util.List;
|
||||
import net.sacredlabyrinth.Phaed.PreciousStones.PreciousStones;
|
||||
import net.sacredlabyrinth.Phaed.PreciousStones.field.Field;
|
||||
import net.sacredlabyrinth.Phaed.PreciousStones.field.FieldFlag;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class PreciousStonesFeature extends BukkitMaskManager implements Listener {
|
||||
FaweBukkit plugin;
|
||||
Plugin preciousstones;
|
||||
|
||||
public PreciousStonesFeature(final Plugin preciousstonesPlugin, final FaweBukkit p3) {
|
||||
super(preciousstonesPlugin.getName());
|
||||
this.preciousstones = preciousstonesPlugin;
|
||||
this.plugin = p3;
|
||||
|
||||
}
|
||||
|
||||
public boolean isAllowed(Player player, Field field, MaskType type, boolean allowMember) {
|
||||
return field != null && (field.isOwner(player.getName()) || (type == MaskType.MEMBER && allowMember && field.getAllAllowed().contains(player.getName())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweMask getMask(final FawePlayer<Player> fp, MaskType type) {
|
||||
final Player player = fp.parent;
|
||||
final Location location = player.getLocation();
|
||||
final List<Field> fields = PreciousStones.API().getFieldsProtectingArea(FieldFlag.ALL, location);
|
||||
if (fields.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String name = player.getName();
|
||||
boolean member = fp.hasPermission("fawe.preciousstones.member");
|
||||
for (final Field myField : fields) {
|
||||
if (isAllowed(player, myField, type, member)) {
|
||||
BlockVector pos1 = new BlockVector(myField.getMinx(), myField.getMiny(), myField.getMinz());
|
||||
BlockVector pos2 = new BlockVector(myField.getMaxx(), myField.getMaxy(), myField.getMaxz());
|
||||
return new FaweMask(pos1, pos2, "FIELD: " + myField) {
|
||||
@Override
|
||||
public boolean isValid(FawePlayer player, MaskType type) {
|
||||
return isAllowed((Player) player.parent, myField, type, fp.hasPermission("fawe.preciousstones.member"));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -4,10 +4,7 @@ import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.palmergames.bukkit.towny.Towny;
|
||||
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
||||
import com.palmergames.bukkit.towny.object.PlayerCache;
|
||||
import com.palmergames.bukkit.towny.object.TownBlock;
|
||||
import com.palmergames.bukkit.towny.object.TownyUniverse;
|
||||
import com.palmergames.bukkit.towny.object.WorldCoord;
|
||||
import com.palmergames.bukkit.towny.object.*;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -28,18 +25,30 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
Resident resident;
|
||||
try {
|
||||
if (block.getResident().getName().equals(player.getName())) {
|
||||
resident = TownyUniverse.getDataSource().getResident(player.getName());
|
||||
try {
|
||||
if (block.getResident().equals(resident)) {
|
||||
return true;
|
||||
}
|
||||
} catch (NotRegisteredException ignore) {}
|
||||
Town town = block.getTown();
|
||||
if (town.isMayor(resident)) {
|
||||
return true;
|
||||
}
|
||||
} catch (final Exception ignore) {}
|
||||
if (player.hasPermission("fawe.towny.*")) {
|
||||
return true;
|
||||
} else try {
|
||||
if (block.getTown().isMayor(TownyUniverse.getDataSource().getResident(player.getName()))) {
|
||||
if (!town.hasResident(resident)) return false;
|
||||
if (player.hasPermission("fawe.towny.*")) {
|
||||
return true;
|
||||
}
|
||||
} catch (NotRegisteredException ignore) {}
|
||||
for (String rank : resident.getTownRanks()) {
|
||||
if (player.hasPermission("fawe.towny." + rank)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (NotRegisteredException e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -57,21 +66,7 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
|
||||
if (myplot == null) {
|
||||
return null;
|
||||
} else {
|
||||
boolean isMember = false;
|
||||
try {
|
||||
if (myplot.getResident().getName().equals(player.getName())) {
|
||||
isMember = true;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
|
||||
}
|
||||
if (!isMember) {
|
||||
if (player.hasPermission("fawe.towny.*")) {
|
||||
isMember = true;
|
||||
} else if (myplot.getTown().isMayor(TownyUniverse.getDataSource().getResident(player.getName()))) {
|
||||
isMember = true;
|
||||
}
|
||||
}
|
||||
boolean isMember = isAllowed(player, myplot);
|
||||
if (isMember) {
|
||||
final Chunk chunk = location.getChunk();
|
||||
final Location pos1 = new Location(location.getWorld(), chunk.getX() * 16, 0, chunk.getZ() * 16);
|
||||
|
@ -3,11 +3,22 @@ package com.boydti.fawe.bukkit.regions;
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.bukkit.filter.WorldGuardFilter;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.regions.FaweMask;
|
||||
import com.boydti.fawe.regions.general.RegionFilter;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.regions.AbstractRegion;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Polygonal2DRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@ -81,7 +92,7 @@ public class Worldguard extends BukkitMaskManager implements Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitMask getMask(final FawePlayer<Player> fp) {
|
||||
public FaweMask getMask(FawePlayer<Player> fp, MaskType type) {
|
||||
final Player player = fp.parent;
|
||||
final com.sk89q.worldguard.LocalPlayer localplayer = this.worldguard.wrapPlayer(player);
|
||||
final Location location = player.getLocation();
|
||||
@ -93,8 +104,17 @@ public class Worldguard extends BukkitMaskManager implements Listener {
|
||||
pos1 = new Location(location.getWorld(), Integer.MIN_VALUE, 0, Integer.MIN_VALUE);
|
||||
pos2 = new Location(location.getWorld(), Integer.MAX_VALUE, 255, Integer.MAX_VALUE);
|
||||
} else {
|
||||
pos1 = new Location(location.getWorld(), myregion.getMinimumPoint().getBlockX(), myregion.getMinimumPoint().getBlockY(), myregion.getMinimumPoint().getBlockZ());
|
||||
pos2 = new Location(location.getWorld(), myregion.getMaximumPoint().getBlockX(), myregion.getMaximumPoint().getBlockY(), myregion.getMaximumPoint().getBlockZ());
|
||||
if (myregion instanceof ProtectedCuboidRegion) {
|
||||
pos1 = new Location(location.getWorld(), myregion.getMinimumPoint().getBlockX(), myregion.getMinimumPoint().getBlockY(), myregion.getMinimumPoint().getBlockZ());
|
||||
pos2 = new Location(location.getWorld(), myregion.getMaximumPoint().getBlockX(), myregion.getMaximumPoint().getBlockY(), myregion.getMaximumPoint().getBlockZ());
|
||||
} else {
|
||||
return new FaweMask(adapt(myregion), myregion.getId()) {
|
||||
@Override
|
||||
public boolean isValid(FawePlayer player, MaskType type) {
|
||||
return isAllowed(worldguard.wrapPlayer((Player) player.parent), myregion);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return new BukkitMask(pos1, pos2) {
|
||||
@Override
|
||||
@ -116,4 +136,54 @@ public class Worldguard extends BukkitMaskManager implements Listener {
|
||||
public RegionFilter getFilter(String world) {
|
||||
return new WorldGuardFilter(Bukkit.getWorld(world));
|
||||
}
|
||||
|
||||
private static class AdaptedRegion extends AbstractRegion {
|
||||
private final ProtectedRegion region;
|
||||
|
||||
public AdaptedRegion(ProtectedRegion region) {
|
||||
super(null);
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getMinimumPoint() {
|
||||
return region.getMinimumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getMaximumPoint() {
|
||||
return region.getMaximumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expand(Vector... changes) {
|
||||
throw new UnsupportedOperationException("Region is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contract(Vector... changes) {
|
||||
throw new UnsupportedOperationException("Region is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Vector position) {
|
||||
return region.contains(position);
|
||||
}
|
||||
}
|
||||
|
||||
private static Region adapt(ProtectedRegion region) {
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
return new CuboidRegion(region.getMinimumPoint(), region.getMaximumPoint());
|
||||
}
|
||||
if (region instanceof GlobalProtectedRegion) {
|
||||
return RegionWrapper.GLOBAL();
|
||||
}
|
||||
if (region instanceof ProtectedPolygonalRegion) {
|
||||
ProtectedPolygonalRegion casted = (ProtectedPolygonalRegion) region;
|
||||
BlockVector max = region.getMaximumPoint();
|
||||
BlockVector min = region.getMinimumPoint();
|
||||
return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY());
|
||||
}
|
||||
return new AdaptedRegion(region);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
package com.boydti.fawe.bukkit.util;
|
||||
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import java.lang.reflect.Method;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
public class BukkitReflectionUtils {
|
||||
/**
|
||||
* prefix of bukkit classes
|
||||
*/
|
||||
private static volatile String preClassB = null;
|
||||
/**
|
||||
* prefix of minecraft classes
|
||||
*/
|
||||
private static volatile String preClassM = null;
|
||||
/**
|
||||
* boolean value, TRUE if server uses forge or MCPC+
|
||||
*/
|
||||
private static boolean forge = false;
|
||||
|
||||
/**
|
||||
* check server version and class names
|
||||
*/
|
||||
public static void init() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
if (Bukkit.getVersion().contains("MCPC") || Bukkit.getVersion().contains("Forge")) {
|
||||
forge = true;
|
||||
}
|
||||
final Server server = Bukkit.getServer();
|
||||
final Class<?> bukkitServerClass = server.getClass();
|
||||
String[] pas = bukkitServerClass.getName().split("\\.");
|
||||
if (pas.length == 5) {
|
||||
final String verB = pas[3];
|
||||
preClassB = "org.bukkit.craftbukkit." + verB;
|
||||
}
|
||||
try {
|
||||
final Method getHandle = bukkitServerClass.getDeclaredMethod("getHandle");
|
||||
final Object handle = getHandle.invoke(server);
|
||||
final Class handleServerClass = handle.getClass();
|
||||
pas = handleServerClass.getName().split("\\.");
|
||||
if (pas.length == 5) {
|
||||
final String verM = pas[3];
|
||||
preClassM = "net.minecraft.server." + verM;
|
||||
}
|
||||
} catch (final Exception ignored) {
|
||||
MainUtil.handleError(ignored);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if server has forge classes
|
||||
*/
|
||||
public static boolean isForge() {
|
||||
return forge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class for name. Replace {nms} to net.minecraft.server.V*. Replace {cb} to org.bukkit.craftbukkit.V*. Replace
|
||||
* {nm} to net.minecraft
|
||||
*
|
||||
* @param classes possible class paths
|
||||
* @return RefClass object
|
||||
* @throws RuntimeException if no class found
|
||||
*/
|
||||
public static ReflectionUtils.RefClass getRefClass(final String... classes) throws RuntimeException {
|
||||
if (preClassM == null) {
|
||||
init();
|
||||
}
|
||||
for (String className : classes) {
|
||||
try {
|
||||
className = className.replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft");
|
||||
return ReflectionUtils.getRefClass(Class.forName(className));
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("no class found: " + classes[0].replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft"));
|
||||
}
|
||||
|
||||
public static Class<?> getNmsClass(final String name) {
|
||||
final String className = "net.minecraft.server." + getVersion() + "." + name;
|
||||
return ReflectionUtils.getClass(className);
|
||||
}
|
||||
|
||||
public static Class<?> getCbClass(final String name) {
|
||||
final String className = "org.bukkit.craftbukkit." + getVersion() + "." + name;
|
||||
return ReflectionUtils.getClass(className);
|
||||
}
|
||||
|
||||
public static Class<?> getUtilClass(final String name) {
|
||||
try {
|
||||
return Class.forName(name); //Try before 1.8 first
|
||||
} catch (final ClassNotFoundException ex) {
|
||||
try {
|
||||
return Class.forName("net.minecraft.util." + name); //Not 1.8
|
||||
} catch (final ClassNotFoundException ex2) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getVersion() {
|
||||
final String packageName = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return packageName.substring(packageName.lastIndexOf('.') + 1);
|
||||
}
|
||||
}
|
@ -25,13 +25,13 @@ public class ItemUtil {
|
||||
private SoftReference<Int2ObjectOpenHashMap<WeakReference<Tag>>> hashToNMSTag = new SoftReference(new Int2ObjectOpenHashMap<>());
|
||||
|
||||
public ItemUtil() throws Exception {
|
||||
this.classCraftItemStack = ReflectionUtils.getCbClass("inventory.CraftItemStack");
|
||||
this.classNMSItem = ReflectionUtils.getNmsClass("ItemStack");
|
||||
this.classCraftItemStack = BukkitReflectionUtils.getCbClass("inventory.CraftItemStack");
|
||||
this.classNMSItem = BukkitReflectionUtils.getNmsClass("ItemStack");
|
||||
this.methodAsNMSCopy = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredMethod("asNMSCopy", ItemStack.class));
|
||||
this.methodHasTag = ReflectionUtils.setAccessible(classNMSItem.getDeclaredMethod("hasTag"));
|
||||
this.methodGetTag = ReflectionUtils.setAccessible(classNMSItem.getDeclaredMethod("getTag"));
|
||||
this.fieldHandle = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredField("handle"));
|
||||
Class<?> classNBTTagCompound = ReflectionUtils.getNmsClass("NBTTagCompound");
|
||||
Class<?> classNBTTagCompound = BukkitReflectionUtils.getNmsClass("NBTTagCompound");
|
||||
this.methodSetTag = ReflectionUtils.setAccessible(classNMSItem.getDeclaredMethod("setTag", classNBTTagCompound));
|
||||
this.methodAsBukkitCopy = ReflectionUtils.setAccessible(classCraftItemStack.getDeclaredMethod("asBukkitCopy", classNMSItem));
|
||||
}
|
||||
|
@ -162,9 +162,9 @@ public class StructureCUI extends CUI {
|
||||
double rotX = playerLoc.getYaw();
|
||||
double rotY = playerLoc.getPitch();
|
||||
double xz = Math.cos(Math.toRadians(rotY));
|
||||
int x = (int) (playerLoc.getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 3);
|
||||
int z = (int) (playerLoc.getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 3);
|
||||
int y = Math.min(Math.min(255, max.getBlockY() + 32), playerLoc.getBlockY() + 3);
|
||||
int x = (int) (playerLoc.getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12);
|
||||
int z = (int) (playerLoc.getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12);
|
||||
int y = Math.max(0, Math.min(Math.min(255, max.getBlockY() + 32), playerLoc.getBlockY() + 3));
|
||||
int minX = Math.max(Math.min(32, min.getBlockX() - x), -32);
|
||||
int maxX = Math.max(Math.min(32, max.getBlockX() - x + 1), -32);
|
||||
int minY = Math.max(Math.min(32, min.getBlockY() - y), -32);
|
||||
|
@ -58,7 +58,7 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
copy.biomes = biomes;
|
||||
} else {
|
||||
copy = new BukkitChunk_All(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
}
|
||||
copy.chunk = chunk;
|
||||
return copy;
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.BukkitPlayer;
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.bukkit.util.BukkitReflectionUtils;
|
||||
import com.boydti.fawe.bukkit.v1_12.packet.FaweChunkPacket;
|
||||
import com.boydti.fawe.bukkit.v1_12.packet.MCAChunkPacket;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
@ -36,7 +37,6 @@ import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
@ -59,7 +59,7 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
private static Method methodGetHandle;
|
||||
|
||||
static {
|
||||
Class<?> classCraftChunk = ReflectionUtils.getCbClass("CraftChunk");
|
||||
Class<?> classCraftChunk = BukkitReflectionUtils.getCbClass("CraftChunk");
|
||||
try {
|
||||
methodGetHandle = ReflectionUtils.setAccessible(classCraftChunk.getDeclaredMethod("getHandle"));
|
||||
} catch (NoSuchMethodException e) {
|
||||
@ -95,6 +95,18 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
return super.supports(capability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(FaweChunk fc) {
|
||||
if (!Fawe.isMainThread()) {
|
||||
startSet(true);
|
||||
try {
|
||||
super.sendChunk(fc);
|
||||
} finally {
|
||||
endSet(true);
|
||||
}
|
||||
} else super.sendChunk(fc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunkUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
if (supports(Capability.CHUNK_PACKETS)) {
|
||||
@ -217,7 +229,7 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
public void relightSky(int x, int y, int z) {}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(CHUNKSECTIONS sections, RelightMode mode, boolean hasSky) {
|
||||
public boolean removeSectionLighting(SECTION sections, int layer, boolean hasSky) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.bukkit.v0;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.util.BukkitReflectionUtils;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.NullRelighter;
|
||||
import com.boydti.fawe.example.Relighter;
|
||||
@ -101,17 +102,17 @@ public class BukkitQueue_All extends BukkitQueue_0<ChunkSnapshot, ChunkSnapshot,
|
||||
|
||||
static {
|
||||
try {
|
||||
ReflectionUtils.init();
|
||||
classRegionFileCache = ReflectionUtils.getNmsClass("RegionFileCache");
|
||||
classRegionFile = ReflectionUtils.getNmsClass("RegionFile");
|
||||
classCraftChunk = ReflectionUtils.getCbClass("CraftChunk");
|
||||
classNMSChunk = ReflectionUtils.getNmsClass("Chunk");
|
||||
classCraftWorld = ReflectionUtils.getCbClass("CraftWorld");
|
||||
classNMSWorld = ReflectionUtils.getNmsClass("World");
|
||||
classChunkProviderServer = ReflectionUtils.getNmsClass("ChunkProviderServer");
|
||||
classIChunkProvider = ReflectionUtils.getNmsClass("IChunkProvider");
|
||||
classIChunkLoader = ReflectionUtils.getNmsClass("IChunkLoader");
|
||||
classChunkRegionLoader = ReflectionUtils.getNmsClass("ChunkRegionLoader");
|
||||
BukkitReflectionUtils.init();
|
||||
classRegionFileCache = BukkitReflectionUtils.getNmsClass("RegionFileCache");
|
||||
classRegionFile = BukkitReflectionUtils.getNmsClass("RegionFile");
|
||||
classCraftChunk = BukkitReflectionUtils.getCbClass("CraftChunk");
|
||||
classNMSChunk = BukkitReflectionUtils.getNmsClass("Chunk");
|
||||
classCraftWorld = BukkitReflectionUtils.getCbClass("CraftWorld");
|
||||
classNMSWorld = BukkitReflectionUtils.getNmsClass("World");
|
||||
classChunkProviderServer = BukkitReflectionUtils.getNmsClass("ChunkProviderServer");
|
||||
classIChunkProvider = BukkitReflectionUtils.getNmsClass("IChunkProvider");
|
||||
classIChunkLoader = BukkitReflectionUtils.getNmsClass("IChunkLoader");
|
||||
classChunkRegionLoader = BukkitReflectionUtils.getNmsClass("ChunkRegionLoader");
|
||||
|
||||
methodGetHandleChunk = ReflectionUtils.setAccessible(classCraftChunk.getDeclaredMethod("getHandle"));
|
||||
methodGetHandleWorld = ReflectionUtils.setAccessible(classCraftWorld.getDeclaredMethod("getHandle"));
|
||||
|
@ -3,32 +3,60 @@ package com.boydti.fawe.bukkit.v0;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockCanBuildEvent;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockDispenseEvent;
|
||||
import org.bukkit.event.block.BlockExpEvent;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.BlockFadeEvent;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockGrowEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import org.bukkit.event.block.NotePlayEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.inventory.FurnaceBurnEvent;
|
||||
import org.bukkit.event.inventory.FurnaceSmeltEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class ChunkListener implements Listener {
|
||||
public abstract class ChunkListener implements Listener {
|
||||
|
||||
private int rateLimit = 0;
|
||||
private int[] badLimit = new int[]{Settings.IMP.TICK_LIMITER.PHYSICS, Settings.IMP.TICK_LIMITER.FALLING, Settings.IMP.TICK_LIMITER.ITEMS};
|
||||
protected int rateLimit = 0;
|
||||
private int[] badLimit = new int[]{Settings.IMP.TICK_LIMITER.PHYSICS_MS, Settings.IMP.TICK_LIMITER.FALLING, Settings.IMP.TICK_LIMITER.ITEMS};
|
||||
|
||||
public ChunkListener() {
|
||||
if (Settings.IMP.TICK_LIMITER.ENABLED) {
|
||||
Bukkit.getPluginManager().registerEvents(ChunkListener.this, Fawe.<FaweBukkit>imp().getPlugin());
|
||||
PluginManager plm = Bukkit.getPluginManager();
|
||||
Plugin plugin = Fawe.<FaweBukkit>imp().getPlugin();
|
||||
plm.registerEvents(this, plugin);
|
||||
try {
|
||||
Fawe.debug("Detected " + BlockExplodeEvent.class);
|
||||
plm.registerEvents(new ChunkListener_8Plus(this), plugin);
|
||||
} catch (Throwable ignore) {}
|
||||
TaskManager.IMP.repeat(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -36,6 +64,9 @@ public class ChunkListener implements Listener {
|
||||
physicsFreeze = false;
|
||||
itemFreeze = false;
|
||||
lastZ = Integer.MIN_VALUE;
|
||||
physSkip = 0;
|
||||
physCancelPair = Long.MIN_VALUE;
|
||||
physCancel = false;
|
||||
|
||||
counter.clear();
|
||||
for (Long2ObjectMap.Entry<Boolean> entry : badChunks.long2ObjectEntrySet()) {
|
||||
@ -50,10 +81,13 @@ public class ChunkListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int getDepth(Exception ex);
|
||||
protected abstract StackTraceElement getElement(Exception ex, int index);
|
||||
|
||||
public static boolean physicsFreeze = false;
|
||||
public static boolean itemFreeze = false;
|
||||
|
||||
private Long2ObjectOpenHashMap<Boolean> badChunks = new Long2ObjectOpenHashMap<>();
|
||||
protected final Long2ObjectOpenHashMap<Boolean> badChunks = new Long2ObjectOpenHashMap<>();
|
||||
private Long2ObjectOpenHashMap<int[]> counter = new Long2ObjectOpenHashMap<>();
|
||||
private int lastX = Integer.MIN_VALUE, lastZ = Integer.MIN_VALUE;
|
||||
private int[] lastCount;
|
||||
@ -82,120 +116,166 @@ public class ChunkListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
private int lastPhysY = 0;
|
||||
protected int physSkip;
|
||||
protected boolean physCancel;
|
||||
protected long physCancelPair;
|
||||
|
||||
protected long physStart;
|
||||
protected long physTick;
|
||||
|
||||
public final void reset() {
|
||||
physSkip = 0;
|
||||
physStart = System.currentTimeMillis();
|
||||
physCancel = false;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockBurnEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockCanBuildEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockDamageEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockDispenseEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockExpEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockFadeEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockFromToEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockGrowEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockIgniteEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockPlaceEvent event) { reset(); }
|
||||
|
||||
// @EventHandler(priority = EventPriority.LOWEST)
|
||||
// public void event(BrewEvent event) { reset(); }
|
||||
//
|
||||
// @EventHandler(priority = EventPriority.LOWEST)
|
||||
// public void event(BrewingStandFuelEvent event) { reset(); }
|
||||
//
|
||||
// @EventHandler(priority = EventPriority.LOWEST)
|
||||
// public void event(CauldronLevelChangeEvent event ) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(FurnaceBurnEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(FurnaceSmeltEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(LeavesDecayEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(NotePlayEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(SignChangeEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockRedstoneEvent event) { reset(); }
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPhysics(BlockPhysicsEvent event) {
|
||||
if (physCancel) {
|
||||
Block block = event.getBlock();
|
||||
long pair = MathMan.pairInt(block.getX() >> 4, block.getZ() >> 4);
|
||||
if (physCancelPair == pair) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (badChunks.containsKey(pair)) {
|
||||
physCancelPair = pair;
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ((++physSkip & 1023) != 0) return;
|
||||
FaweTimer timer = Fawe.get().getTimer();
|
||||
if (timer.getTick() != physTick) {
|
||||
physTick = timer.getTick();
|
||||
physStart = System.currentTimeMillis();
|
||||
return;
|
||||
} else if (System.currentTimeMillis() - physStart < Settings.IMP.TICK_LIMITER.PHYSICS_MS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (physicsFreeze) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
Block block = event.getBlock();
|
||||
int x = block.getX();
|
||||
int z = block.getZ();
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int[] count = getCount(cx, cz);
|
||||
if (count[0] >= Settings.IMP.TICK_LIMITER.PHYSICS) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
int blockId = block.getTypeId();
|
||||
if (event.getChangedTypeId() == blockId) {
|
||||
int y = block.getY();
|
||||
int tmpLastY = lastPhysY;
|
||||
lastPhysY = y;
|
||||
int amount;
|
||||
switch (blockId) {
|
||||
case BlockID.REDSTONE_BLOCK:
|
||||
case BlockID.REDSTONE_LAMP_OFF:
|
||||
case BlockID.REDSTONE_LAMP_ON:
|
||||
case BlockID.REDSTONE_ORE:
|
||||
case BlockID.REDSTONE_REPEATER_OFF:
|
||||
case BlockID.REDSTONE_REPEATER_ON:
|
||||
case BlockID.REDSTONE_TORCH_OFF:
|
||||
case BlockID.REDSTONE_TORCH_ON:
|
||||
case BlockID.REDSTONE_WIRE:
|
||||
case BlockID.GLOWING_REDSTONE_ORE:
|
||||
case BlockID.TRIPWIRE:
|
||||
case BlockID.TRIPWIRE_HOOK:
|
||||
case 218: // Observer
|
||||
case BlockID.PISTON_BASE:
|
||||
case BlockID.PISTON_STICKY_BASE:
|
||||
case BlockID.IRON_DOOR:
|
||||
case BlockID.ACACIA_DOOR:
|
||||
case BlockID.BIRCH_DOOR:
|
||||
case BlockID.DARK_OAK_DOOR:
|
||||
case BlockID.IRON_TRAP_DOOR:
|
||||
case BlockID.JUNGLE_DOOR:
|
||||
case BlockID.SPRUCE_DOOR:
|
||||
case BlockID.TRAP_DOOR:
|
||||
case BlockID.WOODEN_DOOR:
|
||||
case BlockID.FENCE_GATE:
|
||||
case BlockID.ACACIA_FENCE_GATE:
|
||||
case BlockID.BIRCH_FENCE_GATE:
|
||||
case BlockID.DARK_OAK_FENCE_GATE:
|
||||
case BlockID.JUNGLE_FENCE_GATE:
|
||||
case BlockID.SPRUCE_FENCE_GATE:
|
||||
case BlockID.LEVER:
|
||||
case BlockID.WOODEN_BUTTON:
|
||||
case BlockID.STONE_BUTTON:
|
||||
case BlockID.STONE_PRESSURE_PLATE:
|
||||
case BlockID.WOODEN_PRESSURE_PLATE:
|
||||
case BlockID.PRESSURE_PLATE_HEAVY:
|
||||
case BlockID.PRESSURE_PLATE_LIGHT:
|
||||
case BlockID.POWERED_RAIL:
|
||||
case BlockID.ACTIVATOR_RAIL:
|
||||
case BlockID.DETECTOR_RAIL:
|
||||
case BlockID.WATER:
|
||||
case BlockID.STATIONARY_WATER:
|
||||
case BlockID.LAVA:
|
||||
case BlockID.STATIONARY_LAVA:
|
||||
if (y == tmpLastY) {
|
||||
return;
|
||||
if (event.getChangedTypeId() == 0) return;
|
||||
Exception e = new Exception();
|
||||
int depth = getDepth(e);
|
||||
if (depth >= 256) {
|
||||
if (containsSetAir(e, event)) {
|
||||
Block block = event.getBlock();
|
||||
int cx = block.getX() >> 4;
|
||||
int cz = block.getZ() >> 4;
|
||||
physCancelPair = MathMan.pairInt(cx, cz);
|
||||
if (rateLimit <= 0) {
|
||||
rateLimit = 20;
|
||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled physics lag source at " + block.getLocation());
|
||||
}
|
||||
// Should cancel if excess, but need to be careful
|
||||
amount = 1;
|
||||
break;
|
||||
case BlockID.SAND:
|
||||
case BlockID.GRAVEL:
|
||||
case BlockID.DRAGON_EGG:
|
||||
case BlockID.ANVIL:
|
||||
case BlockID.FIRE:
|
||||
case BlockID.TORCH:
|
||||
// If there's lots of this, it's usually from abuse
|
||||
amount = 16;
|
||||
break;
|
||||
default:
|
||||
// Uncategorized, but not redstone
|
||||
amount = 4;
|
||||
break;
|
||||
}
|
||||
if ((count[0] += amount) >= Settings.IMP.TICK_LIMITER.PHYSICS) {
|
||||
cancelNearby(cx, cz);
|
||||
if (rateLimit <= 0) {
|
||||
rateLimit = 20;
|
||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled physics lag source at " + block.getLocation());
|
||||
}
|
||||
event.setCancelled(true);
|
||||
physCancel = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
physSkip = 1;
|
||||
physCancel = false;
|
||||
}
|
||||
|
||||
private void cancelNearby(int cx, int cz) {
|
||||
protected boolean containsSetAir(Exception e, BlockPhysicsEvent event) {
|
||||
for (int frame = 25; frame < 35; frame++) {
|
||||
StackTraceElement elem = getElement(e, frame);
|
||||
if (elem != null) {
|
||||
String methodName = elem.getMethodName();
|
||||
// setAir | setTypeAndData (hacky, but this needs to be efficient)
|
||||
if (methodName.charAt(0) == 's' && methodName.length() == 6 || methodName.length() == 14) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void cancelNearby(int cx, int cz) {
|
||||
cancel(cx, cz);
|
||||
cancel(cx + 1, cz);
|
||||
cancel(cx - 1, cz);
|
||||
cancel(cx, cz + 1);
|
||||
cancel(cx, cz - 1);
|
||||
cancel(cx - 1, cz - 1);
|
||||
cancel(cx - 1, cz + 1);
|
||||
cancel(cx + 1, cz - 1);
|
||||
cancel(cx + 1, cz + 1);
|
||||
}
|
||||
|
||||
private void cancel(int cx, int cz) {
|
||||
long key = MathMan.pairInt(cx, cz);
|
||||
badChunks.put(key, (Boolean) true);
|
||||
counter.put(key, badLimit);
|
||||
int[] count = getCount(cx, cz);
|
||||
count[0] = Integer.MAX_VALUE;
|
||||
count[1] = Integer.MAX_VALUE;
|
||||
count[2] = Integer.MAX_VALUE;
|
||||
|
||||
}
|
||||
|
||||
// Falling
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onBlockChange(EntityChangeBlockEvent event) {
|
||||
if (physicsFreeze) {
|
||||
@ -214,13 +294,58 @@ public class ChunkListener implements Listener {
|
||||
}
|
||||
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
|
||||
if (++count[1] >= Settings.IMP.TICK_LIMITER.FALLING) {
|
||||
cancelNearby(cx, cz);
|
||||
if (rateLimit <= 0) {
|
||||
rateLimit = 20;
|
||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled falling block lag source at " + block.getLocation());
|
||||
|
||||
// Only cancel falling blocks when it's lagging
|
||||
if (Fawe.get().getTimer().getTPS() < 18) {
|
||||
cancelNearby(cx, cz);
|
||||
if (rateLimit <= 0) {
|
||||
rateLimit = 20;
|
||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled falling block lag source at " + block.getLocation());
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
} else {
|
||||
count[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent FireWorks from loading chunks
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
if (!Settings.IMP.TICK_LIMITER.FIREWORKS_LOAD_CHUNKS) {
|
||||
Chunk chunk = event.getChunk();
|
||||
Entity[] entities = chunk.getEntities();
|
||||
World world = chunk.getWorld();
|
||||
|
||||
Exception e = new Exception();
|
||||
int start = 14;
|
||||
int end = 22;
|
||||
int depth = Math.min(end, getDepth(e));
|
||||
|
||||
for (int frame = start; frame < depth; frame++) {
|
||||
StackTraceElement elem = getElement(e, frame);
|
||||
if (elem == null) return;
|
||||
String className = elem.getClassName();
|
||||
int len = className.length();
|
||||
if (className != null) {
|
||||
if (len > 15 && className.charAt(len - 15) == 'E' && className.endsWith("EntityFireworks")) {
|
||||
for (Entity ent : world.getEntities()) {
|
||||
if (ent.getType() == EntityType.FIREWORK) {
|
||||
Vector velocity = ent.getVelocity();
|
||||
double vertical = Math.abs(velocity.getY());
|
||||
if (Math.abs(velocity.getX()) > vertical || Math.abs(velocity.getZ()) > vertical) {
|
||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled rogue FireWork at " + ent.getLocation());
|
||||
ent.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package com.boydti.fawe.bukkit.v0;
|
||||
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
public class ChunkListener_8 extends ChunkListener {
|
||||
|
||||
@Override
|
||||
protected int getDepth(Exception ex) {
|
||||
return SharedSecrets.getJavaLangAccess().getStackTraceDepth(ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackTraceElement getElement(Exception ex, int index) {
|
||||
return SharedSecrets.getJavaLangAccess().getStackTraceElement(ex, index);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.boydti.fawe.bukkit.v0;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockExplodeEvent;
|
||||
|
||||
public class ChunkListener_8Plus implements Listener {
|
||||
private final ChunkListener listener;
|
||||
|
||||
public ChunkListener_8Plus(ChunkListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void event(BlockExplodeEvent event) {
|
||||
listener.reset();
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.boydti.fawe.bukkit.v0;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
|
||||
public class ChunkListener_9 extends ChunkListener {
|
||||
|
||||
private Exception exception;
|
||||
private StackTraceElement[] elements;
|
||||
|
||||
public ChunkListener_9() {
|
||||
super();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
@Override
|
||||
public void onPhysics(BlockPhysicsEvent event) {
|
||||
if (physicsFreeze) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (physCancel) {
|
||||
Block block = event.getBlock();
|
||||
long pair = MathMan.pairInt(block.getX() >> 4, block.getZ() >> 4);
|
||||
if (physCancelPair == pair) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (badChunks.containsKey(pair)) {
|
||||
physCancelPair = pair;
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (System.currentTimeMillis() - physStart > Settings.IMP.TICK_LIMITER.PHYSICS_MS) {
|
||||
physCancelPair = pair;
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
FaweTimer timer = Fawe.get().getTimer();
|
||||
if (timer.getTick() != physTick) {
|
||||
physTick = timer.getTick();
|
||||
physStart = System.currentTimeMillis();
|
||||
physSkip = 0;
|
||||
physCancel = false;
|
||||
return;
|
||||
}
|
||||
if ((++physSkip & 1023) == 0) {
|
||||
if (System.currentTimeMillis() - physStart > Settings.IMP.TICK_LIMITER.PHYSICS_MS) {
|
||||
Block block = event.getBlock();
|
||||
int cx = block.getX() >> 4;
|
||||
int cz = block.getZ() >> 4;
|
||||
physCancelPair = MathMan.pairInt(cx, cz);
|
||||
if (rateLimit <= 0) {
|
||||
rateLimit = 20;
|
||||
Fawe.debug("[FAWE `tick-limiter`] Detected and cancelled physics lag source at " + block.getLocation());
|
||||
}
|
||||
cancelNearby(cx, cz);
|
||||
event.setCancelled(true);
|
||||
physCancel = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StackTraceElement[] getElements(Exception ex) {
|
||||
if (elements == null || ex != exception) {
|
||||
exception = ex;
|
||||
elements = ex.getStackTrace();
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDepth(Exception ex) {
|
||||
return getElements(ex).length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackTraceElement getElement(Exception ex, int i) {
|
||||
StackTraceElement[] elems = getElements(ex);
|
||||
return elems.length > i ? elems[i] : null;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.bukkit.v0;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.util.BukkitReflectionUtils;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
@ -82,13 +83,13 @@ public class FaweAdapter_All implements BukkitImplAdapter {
|
||||
private Map<Class<? extends Tag>, Integer> TagToId = new ConcurrentHashMap<>();
|
||||
|
||||
public FaweAdapter_All() throws Throwable {
|
||||
ReflectionUtils.init();
|
||||
classCraftWorld = ReflectionUtils.getCbClass("CraftWorld");
|
||||
classCraftBlock = ReflectionUtils.getCbClass("block.CraftBlock");
|
||||
classCraftEntity = ReflectionUtils.getCbClass("entity.CraftEntity");
|
||||
classBiomeBase = ReflectionUtils.getNmsClass("BiomeBase");
|
||||
classWorld = ReflectionUtils.getNmsClass("World");
|
||||
classTileEntity = ReflectionUtils.getNmsClass("TileEntity");
|
||||
BukkitReflectionUtils.init();
|
||||
classCraftWorld = BukkitReflectionUtils.getCbClass("CraftWorld");
|
||||
classCraftBlock = BukkitReflectionUtils.getCbClass("block.CraftBlock");
|
||||
classCraftEntity = BukkitReflectionUtils.getCbClass("entity.CraftEntity");
|
||||
classBiomeBase = BukkitReflectionUtils.getNmsClass("BiomeBase");
|
||||
classWorld = BukkitReflectionUtils.getNmsClass("World");
|
||||
classTileEntity = BukkitReflectionUtils.getNmsClass("TileEntity");
|
||||
|
||||
biomeToBiomeBase = ReflectionUtils.setAccessible(classCraftBlock.getDeclaredMethod("biomeToBiomeBase", Biome.class));
|
||||
biomeBaseToBiome = ReflectionUtils.setAccessible(classCraftBlock.getDeclaredMethod("biomeBaseToBiome", classBiomeBase));
|
||||
@ -97,7 +98,7 @@ public class FaweAdapter_All implements BukkitImplAdapter {
|
||||
getHandleWorld = ReflectionUtils.setAccessible(classCraftWorld.getDeclaredMethod("getHandle"));
|
||||
getHandleEntity = ReflectionUtils.setAccessible(classCraftEntity.getDeclaredMethod("getHandle"));
|
||||
try {
|
||||
classBlockPosition = ReflectionUtils.getNmsClass("BlockPosition");
|
||||
classBlockPosition = BukkitReflectionUtils.getNmsClass("BlockPosition");
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
if (classBlockPosition != null) {
|
||||
@ -109,9 +110,9 @@ public class FaweAdapter_All implements BukkitImplAdapter {
|
||||
getTileEntity2 = ReflectionUtils.setAccessible(classWorld.getDeclaredMethod("getTileEntity", int.class, int.class, int.class));
|
||||
}
|
||||
|
||||
classNBTTagCompound = ReflectionUtils.getNmsClass("NBTTagCompound");
|
||||
classNBTBase = ReflectionUtils.getNmsClass("NBTBase");
|
||||
classNBTTagInt = ReflectionUtils.getNmsClass("NBTTagInt");
|
||||
classNBTTagCompound = BukkitReflectionUtils.getNmsClass("NBTTagCompound");
|
||||
classNBTBase = BukkitReflectionUtils.getNmsClass("NBTBase");
|
||||
classNBTTagInt = BukkitReflectionUtils.getNmsClass("NBTTagInt");
|
||||
newNBTTagInt = ReflectionUtils.setAccessible(classNBTTagInt.getConstructor(int.class));
|
||||
setNBTTagCompound = ReflectionUtils.setAccessible(classNBTTagCompound.getDeclaredMethod("set", String.class, classNBTBase));
|
||||
newNBTTagCompound = ReflectionUtils.setAccessible(classNBTTagCompound.getConstructor());
|
||||
@ -139,7 +140,7 @@ public class FaweAdapter_All implements BukkitImplAdapter {
|
||||
int noMods = Modifier.STATIC;
|
||||
int hasMods = 0;
|
||||
for (int i = 0; i < nmsClasses.size(); i++) {
|
||||
Class<?> nmsClass = ReflectionUtils.getNmsClass(nmsClasses.get(i));
|
||||
Class<?> nmsClass = BukkitReflectionUtils.getNmsClass(nmsClasses.get(i));
|
||||
Class<? extends Tag> weClass = weClasses.get(i);
|
||||
TagToId.put(weClass, ids[i]);
|
||||
|
||||
@ -217,15 +218,15 @@ public class FaweAdapter_All implements BukkitImplAdapter {
|
||||
}
|
||||
}
|
||||
try {
|
||||
classEntity = ReflectionUtils.getNmsClass("Entity");
|
||||
classEntityTypes = ReflectionUtils.getNmsClass("EntityTypes");
|
||||
classEntity = BukkitReflectionUtils.getNmsClass("Entity");
|
||||
classEntityTypes = BukkitReflectionUtils.getNmsClass("EntityTypes");
|
||||
|
||||
getBukkitEntity = ReflectionUtils.setAccessible(classEntity.getDeclaredMethod("getBukkitEntity"));
|
||||
addEntity = ReflectionUtils.setAccessible(classWorld.getDeclaredMethod("addEntity", classEntity, CreatureSpawnEvent.SpawnReason.class));
|
||||
setLocation = ReflectionUtils.setAccessible(classEntity.getDeclaredMethod("setLocation", double.class, double.class, double.class, float.class, float.class));
|
||||
|
||||
try {
|
||||
classMinecraftKey = ReflectionUtils.getNmsClass("MinecraftKey");
|
||||
classMinecraftKey = BukkitReflectionUtils.getNmsClass("MinecraftKey");
|
||||
newMinecraftKey = classMinecraftKey.getConstructor(String.class);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
|
@ -10,36 +10,13 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_10_R1.Block;
|
||||
import net.minecraft.server.v1_10_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_10_R1.DataBits;
|
||||
import net.minecraft.server.v1_10_R1.DataPalette;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteGlobal;
|
||||
import net.minecraft.server.v1_10_R1.Entity;
|
||||
import net.minecraft.server.v1_10_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_10_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_10_R1.IBlockData;
|
||||
import net.minecraft.server.v1_10_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_10_R1.NBTTagInt;
|
||||
import net.minecraft.server.v1_10_R1.TileEntity;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_10_R1.*;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
@ -72,9 +49,7 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
@ -256,18 +231,24 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
}
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
if (copy != null) {
|
||||
for (net.minecraft.server.v1_10_R1.Entity entity : ents) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
}
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
ents.clear();
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -335,42 +316,6 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> tile = iterator.next();
|
||||
net.minecraft.server.v1_10_R1.BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> entry : toRemove.entrySet()) {
|
||||
net.minecraft.server.v1_10_R1.BlockPosition bp = entry.getKey();
|
||||
net.minecraft.server.v1_10_R1.TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.y();
|
||||
nmsWorld.s(bp);
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
@ -452,6 +397,42 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> tile = iterator.next();
|
||||
net.minecraft.server.v1_10_R1.BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> entry : toRemove.entrySet()) {
|
||||
net.minecraft.server.v1_10_R1.BlockPosition bp = entry.getKey();
|
||||
net.minecraft.server.v1_10_R1.TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.s(bp);
|
||||
tile.y();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
if (copy != null) {
|
||||
@ -459,8 +440,10 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
}
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,8 +140,8 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
getEntitySlices = net.minecraft.server.v1_10_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
|
||||
Fawe.debug("Using adapter: " + getAdapter());
|
||||
Fawe.debug("=========================================");
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
@ -232,6 +232,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
@ -648,19 +649,15 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode != RelightMode.NONE) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray()); // Emitted
|
||||
if (sky) {
|
||||
section.b(new NibbleArray()); // Skylight
|
||||
}
|
||||
}
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.v1_11;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
@ -110,9 +111,7 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
@ -220,6 +219,7 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
BukkitChunk_1_11_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_11_Copy(getParent(), getX(), getZ()) : null;
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
Settings settings = getParent().getSettings();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
@ -254,18 +254,24 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
if (count == 0 || settings.EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
if (copy != null) {
|
||||
for (Entity entity : ents) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
}
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
ents.clear();
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -345,42 +351,7 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
}
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.z();
|
||||
nmsWorld.s(bp);
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
@ -462,6 +433,42 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.s(bp);
|
||||
tile.z();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
if (copy != null) {
|
||||
@ -469,8 +476,10 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,8 +138,8 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<net.minecraft.server.v1_11_R
|
||||
getEntitySlices = net.minecraft.server.v1_11_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_11.FaweAdapter_1_11());
|
||||
Fawe.debug("Using adapter: " + getAdapter());
|
||||
Fawe.debug("=========================================");
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
@ -230,6 +230,7 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<net.minecraft.server.v1_11_R
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
@ -650,19 +651,15 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<net.minecraft.server.v1_11_R
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode != RelightMode.NONE) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray()); // Emitted
|
||||
if (sky) {
|
||||
section.b(new NibbleArray()); // Skylight
|
||||
}
|
||||
}
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,49 +3,26 @@ package com.boydti.fawe.bukkit.v1_12;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_12_R1.Block;
|
||||
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_12_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_12_R1.DataBits;
|
||||
import net.minecraft.server.v1_12_R1.DataPalette;
|
||||
import net.minecraft.server.v1_12_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_12_R1.DataPaletteGlobal;
|
||||
import net.minecraft.server.v1_12_R1.Entity;
|
||||
import net.minecraft.server.v1_12_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_12_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_12_R1.IBlockData;
|
||||
import net.minecraft.server.v1_12_R1.MinecraftKey;
|
||||
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_12_R1.NBTTagInt;
|
||||
import net.minecraft.server.v1_12_R1.TileEntity;
|
||||
import net.minecraft.server.v1_12_R1.*;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.CraftChunk;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
|
||||
public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
|
||||
public DataPaletteBlock[] sectionPalettes;
|
||||
@ -110,9 +87,7 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_12(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
@ -128,6 +103,7 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
current.a(128, null);
|
||||
}
|
||||
|
||||
DataPaletteBlock paletteBlock = newDataPaletteBlock();
|
||||
currentPalette = (DataPalette) BukkitQueue_1_12.fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
@ -220,6 +196,7 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
BukkitChunk_1_12_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_12_Copy(getParent(), getX(), getZ()) : null;
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
Settings settings = getParent().getSettings();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
@ -245,8 +222,10 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
iter.remove();
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,18 +233,24 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
}
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
if (count == 0 || settings.EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
if (copy != null) {
|
||||
for (Entity entity : ents) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
}
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
ents.clear();
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -290,7 +275,9 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
iter.remove();
|
||||
removeEntity(entity);
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,7 +285,7 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
}
|
||||
// Set entities
|
||||
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||
Set<UUID> createdEntities = new HashSet<>();
|
||||
// Set<UUID> createdEntities = new HashSet<>();
|
||||
if (!entitiesToSpawn.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (CompoundTag nativeTag : entitiesToSpawn) {
|
||||
@ -321,8 +308,9 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
for (MinecraftKey key : EntityTypes.a()) {
|
||||
String currentId = EntityTypes.a(key);
|
||||
Class<? extends Entity> clazz = EntityTypes.b.get(key);
|
||||
entityKeys.put(currentId, clazz);
|
||||
entityKeys.put(key.getKey(), clazz);
|
||||
entityKeys.putIfAbsent(currentId, clazz);
|
||||
entityKeys.putIfAbsent(key.getKey(), clazz);
|
||||
entityKeys.put(key.b() + ":" + key.getKey(), clazz);
|
||||
}
|
||||
}
|
||||
Class<? extends Entity> clazz = entityKeys.get(id);
|
||||
@ -340,49 +328,15 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
entity.f(tag);
|
||||
}
|
||||
entity.setLocation(x, y, z, yaw, pitch);
|
||||
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
createdEntities.add(entity.getUniqueID());
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
}
|
||||
// createdEntities.add(entity.getUniqueID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.z();
|
||||
nmsWorld.s(bp);
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
@ -464,6 +418,47 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
|
||||
// Trim tiles
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
if (!tiles.isEmpty()) {
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
nmsWorld.s(bp);
|
||||
tiles.remove(bp);
|
||||
tile.z();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
if (copy != null) {
|
||||
@ -471,30 +466,38 @@ public class BukkitChunk_1_12 extends CharFaweChunk<Chunk, BukkitQueue_1_12> {
|
||||
}
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
BlockPosition pos = new BlockPosition(x, y, z); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_12.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
if (BukkitQueue_1_12.methodTileEntityLoad != null) {
|
||||
BukkitQueue_1_12.methodTileEntityLoad.invoke(tileEntity, tag); // ReadTagIntoTile
|
||||
} else {
|
||||
tileEntity.load(tag);
|
||||
if (!tilesToSpawn.isEmpty()) {
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
BlockPosition pos = new BlockPosition(x, y, z); // Set pos
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_12.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
|
||||
|
||||
if (BukkitQueue_1_12.methodTileEntityLoad != null) {
|
||||
BukkitQueue_1_12.methodTileEntityLoad.invoke(tileEntity, tag); // ReadTagIntoTile
|
||||
} else {
|
||||
tileEntity.load(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,7 @@ import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.queue.LazyFaweChunk;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
@ -36,49 +32,9 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import net.minecraft.server.v1_12_R1.BiomeBase;
|
||||
import net.minecraft.server.v1_12_R1.BiomeCache;
|
||||
import net.minecraft.server.v1_12_R1.Block;
|
||||
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_12_R1.ChunkProviderGenerate;
|
||||
import net.minecraft.server.v1_12_R1.ChunkProviderServer;
|
||||
import net.minecraft.server.v1_12_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_12_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_12_R1.Entity;
|
||||
import net.minecraft.server.v1_12_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_12_R1.EntityTracker;
|
||||
import net.minecraft.server.v1_12_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_12_R1.EnumDifficulty;
|
||||
import net.minecraft.server.v1_12_R1.EnumGamemode;
|
||||
import net.minecraft.server.v1_12_R1.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_12_R1.IBlockData;
|
||||
import net.minecraft.server.v1_12_R1.IDataManager;
|
||||
import net.minecraft.server.v1_12_R1.MinecraftServer;
|
||||
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_12_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_12_R1.PacketDataSerializer;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutMapChunk;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutMultiBlockChange;
|
||||
import net.minecraft.server.v1_12_R1.PlayerChunk;
|
||||
import net.minecraft.server.v1_12_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_12_R1.RegionFile;
|
||||
import net.minecraft.server.v1_12_R1.RegionFileCache;
|
||||
import net.minecraft.server.v1_12_R1.ServerNBTManager;
|
||||
import net.minecraft.server.v1_12_R1.TileEntity;
|
||||
import net.minecraft.server.v1_12_R1.WorldChunkManager;
|
||||
import net.minecraft.server.v1_12_R1.WorldData;
|
||||
import net.minecraft.server.v1_12_R1.WorldManager;
|
||||
import net.minecraft.server.v1_12_R1.WorldServer;
|
||||
import net.minecraft.server.v1_12_R1.WorldSettings;
|
||||
import net.minecraft.server.v1_12_R1.WorldType;
|
||||
import net.minecraft.server.v1_12_R1.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@ -170,8 +126,8 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
getEntitySlices = net.minecraft.server.v1_12_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
setupAdapter(new FaweAdapter_1_12());
|
||||
Fawe.debug("Using adapter: " + getAdapter());
|
||||
Fawe.debug("=========================================");
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
@ -202,7 +158,7 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
|
||||
methodSaveChunk.invoke(cps, chunk, false);
|
||||
} else {
|
||||
cps.saveChunk(chunk);
|
||||
cps.saveChunk(chunk, false);
|
||||
}
|
||||
cps.saveChunkNOP(chunk);
|
||||
return true;
|
||||
@ -284,7 +240,13 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
net.minecraft.server.v1_12_R1.Chunk nmsChunk = getCachedChunk(world, x, z);
|
||||
if (nmsChunk != null) {
|
||||
nmsChunk.f(true); // Set Modified
|
||||
nmsChunk.mustSave = true;
|
||||
}
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
|
||||
@ -583,6 +545,7 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
CraftPlayer bukkitPlayer = ((CraftPlayer) ((BukkitPlayer) players[i]).parent);
|
||||
EntityPlayer player = bukkitPlayer.getHandle();
|
||||
|
||||
if (playerManager.a(player, chunk.getX(), chunk.getZ())) {
|
||||
if (packet == null) {
|
||||
byte[] data;
|
||||
@ -662,6 +625,15 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
sendChunk(fc.getX(), fc.getZ(), fc.getBitMask());
|
||||
}
|
||||
|
||||
public void sendPacket(int cx, int cz, Packet packet) {
|
||||
PlayerChunk chunk = getPlayerChunk(nmsWorld, cx, cz);
|
||||
if (chunk != null) {
|
||||
for (EntityPlayer player : chunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PlayerChunk getPlayerChunk(WorldServer w, int cx, int cz) {
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
PlayerChunk playerChunk = chunkMap.getChunk(cx, cz);
|
||||
@ -730,19 +702,18 @@ public class BukkitQueue_1_12 extends BukkitQueue_0<net.minecraft.server.v1_12_R
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode != RelightMode.NONE) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray()); // Emitted
|
||||
if (sky) {
|
||||
section.b(new NibbleArray()); // Skylight
|
||||
}
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
if (sky) {
|
||||
byte[] light = section.getSkyLightArray().asBytes();
|
||||
if (light != null) {
|
||||
Arrays.fill(light, (byte) 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,24 +13,8 @@ import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_7_R4.ChunkPosition;
|
||||
import net.minecraft.server.v1_7_R4.ChunkSection;
|
||||
import net.minecraft.server.v1_7_R4.Entity;
|
||||
import net.minecraft.server.v1_7_R4.EntityPlayer;
|
||||
import net.minecraft.server.v1_7_R4.EntityTypes;
|
||||
import net.minecraft.server.v1_7_R4.NBTTagCompound;
|
||||
import net.minecraft.server.v1_7_R4.NBTTagInt;
|
||||
import net.minecraft.server.v1_7_R4.NibbleArray;
|
||||
import net.minecraft.server.v1_7_R4.TileEntity;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_7_R4.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@ -68,9 +52,7 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone(), (byte[][]) MainUtil.copyNd(byteIds), datas.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
return copy;
|
||||
@ -170,13 +152,21 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
// Remove entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
ents.clear();
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -256,39 +246,6 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<ChunkPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<ChunkPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<ChunkPosition, TileEntity> tile = iterator.next();
|
||||
ChunkPosition pos = tile.getKey();
|
||||
int lx = pos.x & 15;
|
||||
int ly = pos.y;
|
||||
int lz = pos.z & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<ChunkPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
ChunkPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.s();
|
||||
nmsWorld.p(bp.x, bp.y, bp.z);
|
||||
tile.u();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
@ -423,13 +380,47 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
}
|
||||
getParent().setCount(0, solid, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<ChunkPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<ChunkPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<ChunkPosition, TileEntity> tile = iterator.next();
|
||||
ChunkPosition pos = tile.getKey();
|
||||
int lx = pos.x & 15;
|
||||
int ly = pos.y;
|
||||
int lz = pos.z & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<ChunkPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
ChunkPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.p(bp.x, bp.y, bp.z);
|
||||
tile.s();
|
||||
tile.u();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.m();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,8 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
||||
|
||||
@Override
|
||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
throw new UnsupportedOperationException();
|
||||
/*TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
@ -239,7 +240,7 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
return true;*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -271,6 +272,7 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = generator;
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = existingGenerator;
|
||||
@ -515,13 +517,12 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
||||
}
|
||||
}
|
||||
for (EntityPlayer player : players) {
|
||||
int currentVersion = player.playerConnection.networkManager.getVersion();
|
||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280, currentVersion);
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280);
|
||||
player.playerConnection.sendPacket(packet);
|
||||
mask = 255;
|
||||
}
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, mask, currentVersion);
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, mask);
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
if (empty) {
|
||||
@ -549,19 +550,15 @@ public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Ch
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.setEmittedLightArray(null);
|
||||
if (sky) {
|
||||
section.setSkyLightArray(null);
|
||||
}
|
||||
}
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.setEmittedLightArray(null);
|
||||
if (sky) {
|
||||
section.setSkyLightArray(null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,21 +13,8 @@ import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_8_R3.BlockPosition;
|
||||
import net.minecraft.server.v1_8_R3.ChunkSection;
|
||||
import net.minecraft.server.v1_8_R3.Entity;
|
||||
import net.minecraft.server.v1_8_R3.EntityPlayer;
|
||||
import net.minecraft.server.v1_8_R3.EntityTypes;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagCompound;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagInt;
|
||||
import net.minecraft.server.v1_8_R3.TileEntity;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@ -59,9 +46,7 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
return copy;
|
||||
@ -97,13 +82,21 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
// Remove entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
ents.clear();
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -186,39 +179,6 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.y();
|
||||
nmsWorld.t(bp);
|
||||
tile.E();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
@ -287,13 +247,47 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + solid, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.t(bp);
|
||||
tile.y();
|
||||
tile.E();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import net.minecraft.server.v1_8_R3.Chunk;
|
||||
import net.minecraft.server.v1_8_R3.ChunkSection;
|
||||
import net.minecraft.server.v1_8_R3.Entity;
|
||||
import net.minecraft.server.v1_8_R3.EntityPlayer;
|
||||
import net.minecraft.server.v1_8_R3.EntitySlice;
|
||||
import net.minecraft.server.v1_8_R3.EntityTracker;
|
||||
import net.minecraft.server.v1_8_R3.EntityTypes;
|
||||
import net.minecraft.server.v1_8_R3.EnumDifficulty;
|
||||
@ -130,7 +131,8 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
||||
|
||||
@Override
|
||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, final boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
throw new UnsupportedOperationException();
|
||||
/*TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
@ -239,7 +241,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
return true;*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -271,6 +273,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = generator;
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = existingGenerator;
|
||||
@ -533,7 +536,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
||||
|
||||
public boolean hasEntities(net.minecraft.server.v1_8_R3.Chunk nmsChunk) {
|
||||
for (int i = 0; i < nmsChunk.entitySlices.length; i++) {
|
||||
List<Entity> slice = nmsChunk.entitySlices[i];
|
||||
EntitySlice<Entity> slice = nmsChunk.entitySlices[i];
|
||||
if (slice != null && !slice.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
@ -542,19 +545,15 @@ public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
}
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,35 +9,12 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_9_R2.Block;
|
||||
import net.minecraft.server.v1_9_R2.BlockPosition;
|
||||
import net.minecraft.server.v1_9_R2.ChunkSection;
|
||||
import net.minecraft.server.v1_9_R2.DataBits;
|
||||
import net.minecraft.server.v1_9_R2.DataPalette;
|
||||
import net.minecraft.server.v1_9_R2.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_9_R2.DataPaletteGlobal;
|
||||
import net.minecraft.server.v1_9_R2.Entity;
|
||||
import net.minecraft.server.v1_9_R2.EntityPlayer;
|
||||
import net.minecraft.server.v1_9_R2.EntityTypes;
|
||||
import net.minecraft.server.v1_9_R2.IBlockData;
|
||||
import net.minecraft.server.v1_9_R2.NBTTagCompound;
|
||||
import net.minecraft.server.v1_9_R2.NBTTagInt;
|
||||
import net.minecraft.server.v1_9_R2.TileEntity;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_9_R2.*;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftChunk;
|
||||
@ -71,9 +48,7 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
@ -197,13 +172,21 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
// Remove entities
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
ents.clear();
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -289,39 +272,6 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.y();
|
||||
nmsWorld.s(bp);
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
@ -405,6 +355,39 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.s(bp);
|
||||
tile.y();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
byte[] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
|
@ -124,8 +124,8 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<net.minecraft.server.v1_9_
|
||||
fieldBits.setAccessible(true);
|
||||
if (getAdapter() == null) {
|
||||
setupAdapter(new FaweAdapter_1_9());
|
||||
Fawe.debug("Using adapter: " + getAdapter());
|
||||
Fawe.debug("=========================================");
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -177,6 +177,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<net.minecraft.server.v1_9_
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
@ -593,19 +594,15 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<net.minecraft.server.v1_9_
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode == RelightMode.ALL) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
}
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,9 +21,9 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class AsyncBlock implements Block {
|
||||
|
||||
public final int z;
|
||||
public final int y;
|
||||
public final int x;
|
||||
public int z;
|
||||
public int y;
|
||||
public int x;
|
||||
public final FaweQueue queue;
|
||||
public final AsyncWorld world;
|
||||
|
||||
@ -284,4 +284,10 @@ public class AsyncBlock implements Block {
|
||||
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
|
||||
|
||||
}
|
||||
|
||||
public void setPosition(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
|
@ -68,19 +68,19 @@ public class AsyncChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
if (Thread.currentThread() == Fawe.get().getMainThread()) {
|
||||
if (Fawe.isMainThread()) {
|
||||
return world.getChunkAt(x, z).getChunkSnapshot(includeMaxblocky, includeBiome, includeBiomeTempRain);
|
||||
}
|
||||
return whenLoaded(new RunnableVal<ChunkSnapshot>() {
|
||||
@Override
|
||||
public void run(ChunkSnapshot value) {
|
||||
this.value = world.getChunkAt(x, z).getChunkSnapshot(includeBiome, includeBiome, includeBiomeTempRain);
|
||||
this.value = world.getBukkitWorld().getChunkAt(x, z).getChunkSnapshot(includeBiome, includeBiome, includeBiomeTempRain);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private <T> T whenLoaded(RunnableVal<T> task) {
|
||||
if (Thread.currentThread() == Fawe.get().getMainThread()) {
|
||||
if (Fawe.isMainThread()) {
|
||||
task.run();
|
||||
return task.value;
|
||||
}
|
||||
@ -112,7 +112,7 @@ public class AsyncChunk implements Chunk {
|
||||
return whenLoaded(new RunnableVal<Entity[]>() {
|
||||
@Override
|
||||
public void run(Entity[] value) {
|
||||
world.getChunkAt(x, z).getEntities();
|
||||
world.getBukkitWorld().getChunkAt(x, z).getEntities();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -125,7 +125,7 @@ public class AsyncChunk implements Chunk {
|
||||
return TaskManager.IMP.sync(new RunnableVal<BlockState[]>() {
|
||||
@Override
|
||||
public void run(BlockState[] value) {
|
||||
this.value = world.getChunkAt(x, z).getTileEntities();
|
||||
this.value = world.getBukkitWorld().getChunkAt(x, z).getTileEntities();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.boydti.fawe.bukkit.wrapper.state;
|
||||
|
||||
import com.boydti.fawe.bukkit.chat.FancyMessage;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlockState;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -20,16 +21,26 @@ public class AsyncSign extends AsyncBlockState implements Sign {
|
||||
String[] data = new String[4];
|
||||
if (nbt != null) {
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
data[i - 1] = nbt.getString("Text" + i);
|
||||
data[i - 1] = fromJson(nbt.getString("Text" + i));
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private String fromJson(String jsonInput) {
|
||||
if (jsonInput == null || jsonInput.isEmpty()) return "";
|
||||
return FancyMessage.deserialize(jsonInput).toOldMessageFormat();
|
||||
}
|
||||
|
||||
private String toJson(String oldInput) {
|
||||
if (oldInput == null || oldInput.isEmpty()) return "";
|
||||
return new FancyMessage("").color(oldInput).toJSONString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLine(int index) throws IndexOutOfBoundsException {
|
||||
CompoundTag nbt = getNbtData();
|
||||
return nbt == null ? null : nbt.getString("Text" + (index + 1));
|
||||
return nbt == null ? null : fromJson(nbt.getString("Text" + (index + 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,7 +48,7 @@ public class AsyncSign extends AsyncBlockState implements Sign {
|
||||
CompoundTag nbt = getNbtData();
|
||||
if (nbt != null) {
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nbt.getValue());
|
||||
map.put("Text" + (index + 1), new StringTag(line));
|
||||
map.put("Text" + (index + 1), new StringTag(toJson(line)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,33 +24,25 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.bukkit.block.BrushBoundBaseBlock;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.ServerInterface;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.WorldVector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.blocks.ItemID;
|
||||
import com.sk89q.worldedit.blocks.SkullBlock;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.*;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.material.Dye;
|
||||
@ -141,7 +133,24 @@ public class BukkitPlayer extends LocalPlayer {
|
||||
final ItemStack item = player.getItemInHand();
|
||||
player.setItemInHand(newItem);
|
||||
if (item != null) {
|
||||
inv.addItem(item);
|
||||
HashMap<Integer, ItemStack> overflow = inv.addItem(item);
|
||||
if (overflow != null && !overflow.isEmpty()) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
for (Map.Entry<Integer, ItemStack> entry : overflow.entrySet()) {
|
||||
ItemStack stack = entry.getValue();
|
||||
if (stack.getType() != Material.AIR && stack.getAmount() > 0) {
|
||||
Item dropped = player.getWorld().dropItem(player.getLocation(), stack);
|
||||
PlayerDropItemEvent event = new PlayerDropItemEvent(player, dropped);
|
||||
if (event.isCancelled()) {
|
||||
dropped.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
player.updateInventory();
|
||||
}
|
||||
|
@ -22,13 +22,8 @@ package com.sk89q.worldedit.bukkit;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.blocks.LazyBlock;
|
||||
@ -41,20 +36,10 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
@ -68,9 +53,10 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class BukkitWorld extends LocalWorld {
|
||||
|
||||
private static final Logger logger = WorldEdit.logger;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
|
||||
public class BukkitWorld extends LocalWorld {
|
||||
|
||||
private static final Map<Integer, Effect> effects = new HashMap<Integer, Effect>();
|
||||
static {
|
||||
@ -257,7 +243,7 @@ public class BukkitWorld extends LocalWorld {
|
||||
try {
|
||||
getWorld().regenerateChunk(chunk.getBlockX(), chunk.getBlockZ());
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.WARNING, "Chunk generation via Bukkit raised an error", t);
|
||||
WorldEdit.logger.log(Level.WARNING, "Chunk generation via Bukkit raised an error", t);
|
||||
}
|
||||
|
||||
// Then restore
|
||||
|
@ -3,7 +3,7 @@ main: com.boydti.fawe.bukkit.BukkitMain
|
||||
version: ${version}
|
||||
description: Fast Async WorldEdit plugin
|
||||
authors: [Empire92]
|
||||
loadbefore: [WorldEdit,AsyncWorldEdit,AsyncWorldEditInjector]
|
||||
loadbefore: [WorldEdit,AsyncWorldEdit,AsyncWorldEditInjector,WorldGuard]
|
||||
load: STARTUP
|
||||
database: false
|
||||
#softdepend: [WorldGuard, PlotSquared, MCore, Factions, GriefPrevention, Residence, Towny, PlotMe, PreciousStones]
|
||||
@ -13,11 +13,18 @@ commands:
|
||||
aliases: [fawecancel,/fcancel,/cancel,/fawecancel]
|
||||
permissions:
|
||||
fawe.plotsquared:
|
||||
default: true
|
||||
default: true
|
||||
children:
|
||||
fawe.plotsquared.trusted: true
|
||||
fawe.plotme:
|
||||
default: true
|
||||
fawe.bypass.regions:
|
||||
default: false
|
||||
fawe.bypass:
|
||||
default: false
|
||||
children:
|
||||
fawe.bypass.regions: true
|
||||
fawe.limit.*: true
|
||||
fawe.tips:
|
||||
default: false
|
||||
fawe.admin:
|
||||
|
@ -6,8 +6,7 @@ dependencies {
|
||||
compile 'org.yaml:snakeyaml:1.16'
|
||||
compile 'com.google.code.gson:gson:2.2.4'
|
||||
compile 'net.fabiozumbi12:redprotect:1.9.6'
|
||||
compile 'com.sk89q:worldguard:6.0.0-SNAPSHOT'
|
||||
compile group: "com.plotsquared", name: "plotsquared-api", version: "latest"
|
||||
compile 'com.plotsquared:plotsquared-api:3.1'
|
||||
compile 'org.primesoft:BlocksHub:2.0'
|
||||
compile 'com.github.luben:zstd-jni:1.1.1'
|
||||
// compile 'org.javassist:javassist:3.22.0-CR1'
|
||||
@ -15,7 +14,6 @@ dependencies {
|
||||
compile(group: 'com.sk89q.worldedit', name: 'worldedit-core', version:'6.1.3-SNAPSHOT') {
|
||||
exclude(module: 'bukkit-classloader-check')
|
||||
}
|
||||
compile 'org.inventivetalent:mapmanager:1.4.0-SNAPSHOT'
|
||||
}
|
||||
|
||||
processResources {
|
||||
@ -65,4 +63,4 @@ task copyFiles {
|
||||
}
|
||||
|
||||
build.finalizedBy(copyFiles)
|
||||
copyFiles.dependsOn(createPom)
|
||||
copyFiles.dependsOn(createPom)
|
||||
|
@ -7,64 +7,20 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualQueue;
|
||||
import com.boydti.fawe.regions.general.plot.PlotSquaredFeature;
|
||||
import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
import com.boydti.fawe.util.FaweTimer;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.Updater;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.boydti.fawe.util.chat.ChatManager;
|
||||
import com.boydti.fawe.util.chat.PlainChatManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTagBuilder;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockWorldVector;
|
||||
import com.sk89q.worldedit.CuboidClipboard;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.PlayerDirection;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BlockData;
|
||||
import com.sk89q.worldedit.command.BiomeCommands;
|
||||
import com.sk89q.worldedit.command.BrushCommands;
|
||||
import com.sk89q.worldedit.command.BrushOptionsCommands;
|
||||
import com.sk89q.worldedit.command.ChunkCommands;
|
||||
import com.sk89q.worldedit.command.ClipboardCommands;
|
||||
import com.sk89q.worldedit.command.FlattenedClipboardTransform;
|
||||
import com.sk89q.worldedit.command.GenerationCommands;
|
||||
import com.sk89q.worldedit.command.HistoryCommands;
|
||||
import com.sk89q.worldedit.command.NavigationCommands;
|
||||
import com.sk89q.worldedit.command.OptionsCommands;
|
||||
import com.sk89q.worldedit.command.RegionCommands;
|
||||
import com.sk89q.worldedit.command.SchematicCommands;
|
||||
import com.sk89q.worldedit.command.ScriptingCommands;
|
||||
import com.sk89q.worldedit.command.SnapshotCommands;
|
||||
import com.sk89q.worldedit.command.SnapshotUtilCommands;
|
||||
import com.sk89q.worldedit.command.SuperPickaxeCommands;
|
||||
import com.sk89q.worldedit.command.ToolCommands;
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.command.WorldEditCommands;
|
||||
import com.sk89q.worldedit.command.*;
|
||||
import com.sk89q.worldedit.command.composition.SelectionCommand;
|
||||
import com.sk89q.worldedit.command.tool.AreaPickaxe;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.command.tool.FloodFillTool;
|
||||
import com.sk89q.worldedit.command.tool.LongRangeBuildTool;
|
||||
import com.sk89q.worldedit.command.tool.RecursivePickaxe;
|
||||
import com.sk89q.worldedit.command.tool.SinglePickaxe;
|
||||
import com.sk89q.worldedit.command.tool.*;
|
||||
import com.sk89q.worldedit.command.tool.brush.GravityBrush;
|
||||
import com.sk89q.worldedit.command.util.EntityRemover;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
@ -72,11 +28,7 @@ import com.sk89q.worldedit.extension.factory.DefaultBlockParser;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformManager;
|
||||
import com.sk89q.worldedit.extension.platform.PlayerProxy;
|
||||
import com.sk89q.worldedit.extension.platform.*;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.MaskingExtent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
@ -85,56 +37,29 @@ import com.sk89q.worldedit.extent.clipboard.io.SchematicReader;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.SchematicWriter;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
|
||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
import com.sk89q.worldedit.function.CombinedRegionFunction;
|
||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
|
||||
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
|
||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.FuzzyBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.MaskUnion;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.mask.OffsetMask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.*;
|
||||
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.function.visitor.BreadthFirstSearch;
|
||||
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.LayerVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.NonRisingVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||
import com.sk89q.worldedit.function.pattern.*;
|
||||
import com.sk89q.worldedit.function.visitor.*;
|
||||
import com.sk89q.worldedit.history.change.EntityCreate;
|
||||
import com.sk89q.worldedit.history.change.EntityRemove;
|
||||
import com.sk89q.worldedit.internal.LocalWorldAdapter;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.For;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.Functions;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.SimpleFor;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.While;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.*;
|
||||
import com.sk89q.worldedit.math.convolution.HeightMap;
|
||||
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CylinderRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.SphereRegionSelector;
|
||||
import com.sk89q.worldedit.regions.CylinderRegion;
|
||||
import com.sk89q.worldedit.regions.EllipsoidRegion;
|
||||
import com.sk89q.worldedit.regions.selector.*;
|
||||
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
@ -144,9 +69,7 @@ import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.command.SimpleCommandMapping;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.fluent.DispatcherNode;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
|
||||
import com.sk89q.worldedit.util.command.parametric.*;
|
||||
import com.sk89q.worldedit.util.formatting.Fragment;
|
||||
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
||||
import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
|
||||
@ -161,11 +84,7 @@ import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nullable;
|
||||
@ -231,6 +150,8 @@ public class Fawe {
|
||||
private DefaultTransformParser transformParser;
|
||||
private ChatManager chatManager = new PlainChatManager();
|
||||
|
||||
private BStats stats;
|
||||
|
||||
/**
|
||||
* Get the implementation specific class
|
||||
*
|
||||
@ -270,7 +191,7 @@ public class Fawe {
|
||||
if (INSTANCE != null) {
|
||||
INSTANCE.IMP.debug(s);
|
||||
} else {
|
||||
System.out.println(s);
|
||||
System.out.println(BBC.stripColor(BBC.color(s)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,6 +201,15 @@ public class Fawe {
|
||||
* @param s
|
||||
*/
|
||||
public static void debug(Object s) {
|
||||
if (INSTANCE != null) // Fix of issue 1123 - Didn't check the whole code, but WorldEdit should be loaded when an INSTANCE of FAWE is set. (Since this is a core class, I didn't use the Bukkit API)
|
||||
{
|
||||
Actor actor = Request.request().getActor();
|
||||
if (actor != null && actor.isPlayer()) {
|
||||
actor.print(BBC.color(BBC.PREFIX.original() + " " + s));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
debugPlain(BBC.PREFIX.original() + " " + s);
|
||||
}
|
||||
|
||||
@ -297,13 +227,20 @@ public class Fawe {
|
||||
* Implementation dependent stuff
|
||||
*/
|
||||
this.setupConfigs();
|
||||
MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.IMP.PATHS.HISTORY), TimeUnit.DAYS.toMillis(Settings.IMP.HISTORY.DELETE_AFTER_DAYS));
|
||||
MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.IMP.PATHS.CLIPBOARD), TimeUnit.DAYS.toMillis(Settings.IMP.CLIPBOARD.DELETE_AFTER_DAYS));
|
||||
|
||||
TaskManager.IMP = this.IMP.getTaskManager();
|
||||
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.IMP.PATHS.HISTORY), TimeUnit.DAYS.toMillis(Settings.IMP.HISTORY.DELETE_AFTER_DAYS), false);
|
||||
MainUtil.deleteOlder(MainUtil.getFile(IMP.getDirectory(), Settings.IMP.PATHS.CLIPBOARD), TimeUnit.DAYS.toMillis(Settings.IMP.CLIPBOARD.DELETE_AFTER_DAYS), false);
|
||||
}
|
||||
});
|
||||
|
||||
if (Settings.IMP.METRICS) {
|
||||
try {
|
||||
BStats stats = new BStats();
|
||||
this.stats = new BStats();
|
||||
this.IMP.startMetrics();
|
||||
TaskManager.IMP.later(new Runnable() {
|
||||
@Override
|
||||
@ -323,44 +260,50 @@ public class Fawe {
|
||||
this.timer = new FaweTimer();
|
||||
Fawe.this.IMP.setupVault();
|
||||
|
||||
// Delayed worldedit setup
|
||||
TaskManager.IMP.later(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
File jar = MainUtil.getJarFile();
|
||||
File extraBlocks = MainUtil.copyFile(jar, "extrablocks.json", null);
|
||||
if (extraBlocks != null && extraBlocks.exists()) {
|
||||
TaskManager.IMP.task(() -> {
|
||||
try {
|
||||
transformParser = new DefaultTransformParser(getWorldEdit());
|
||||
visualQueue = new VisualQueue();
|
||||
WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers());
|
||||
WEManager.IMP.managers.add(new PlotSquaredFeature());
|
||||
Fawe.debug("Plugin 'PlotSquared' found. Using it now.");
|
||||
} catch (Throwable e) {
|
||||
BundledBlockData.getInstance().loadFromResource();
|
||||
BundledBlockData.getInstance().add(extraBlocks.toURI().toURL(), true);
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
Fawe.debug("Invalid format: extrablocks.json");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Delayed worldedit setup
|
||||
TaskManager.IMP.later(() -> {
|
||||
try {
|
||||
transformParser = new DefaultTransformParser(getWorldEdit());
|
||||
visualQueue = new VisualQueue(3);
|
||||
WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers());
|
||||
WEManager.IMP.managers.add(new PlotSquaredFeature());
|
||||
Fawe.debug("Plugin 'PlotSquared' found. Using it now.");
|
||||
} catch (Throwable e) {}
|
||||
}, 0);
|
||||
|
||||
TaskManager.IMP.repeat(timer, 1);
|
||||
|
||||
if (Settings.IMP.UPDATE) {
|
||||
if (!Settings.IMP.UPDATE.equalsIgnoreCase("false")) {
|
||||
// Delayed updating
|
||||
updater = new Updater();
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
update();
|
||||
}
|
||||
});
|
||||
TaskManager.IMP.repeatAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
update();
|
||||
}
|
||||
}, 36000);
|
||||
TaskManager.IMP.async(() -> update());
|
||||
TaskManager.IMP.repeatAsync(() -> update(), 36000);
|
||||
}
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
if (stats != null) {
|
||||
stats.close();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean update() {
|
||||
if (updater != null) {
|
||||
updater.update(IMP.getPlatform(), getVersion());
|
||||
updater.getUpdate(IMP.getPlatform(), getVersion());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -484,6 +427,13 @@ public class Fawe {
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "de/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "ru/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "ru/commands.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "tr/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "es/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "es/commands.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "nl/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "fr/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "cn/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "it/message.yml", null);
|
||||
// Setting up config.yml
|
||||
File file = new File(this.IMP.getDirectory(), "config.yml");
|
||||
Settings.IMP.PLATFORM = IMP.getPlatform().replace("\"", "");
|
||||
@ -525,6 +475,9 @@ public class Fawe {
|
||||
Request.inject(); // Custom pattern extent
|
||||
// Commands
|
||||
Commands.load(new File(INSTANCE.IMP.getDirectory(), "commands.yml"));
|
||||
ArgumentStack.inject0(); // Mark/reset
|
||||
ContextArgumentStack.inject();
|
||||
StringArgumentStack.inject();
|
||||
Commands.inject(); // Translations
|
||||
BiomeCommands.inject(); // Translations + Optimizations
|
||||
ChunkCommands.inject(); // Translations + Optimizations
|
||||
@ -598,6 +551,8 @@ public class Fawe {
|
||||
ClipboardHolder.inject(); // Closeable
|
||||
// Regions
|
||||
CuboidRegion.inject(); // Optimizations
|
||||
CylinderRegion.inject(); // Optimizations
|
||||
EllipsoidRegion.inject(); // Optimizations
|
||||
// Extents
|
||||
MaskingExtent.inject(); // Features
|
||||
BlockTransformExtent.inject(); // Fix for cache not being mutable
|
||||
@ -643,6 +598,7 @@ public class Fawe {
|
||||
ExtentBlockCopy.inject(); // Optimizations
|
||||
BlockReplace.inject(); // Optimizations + Features
|
||||
ForwardExtentCopy.inject(); // Fixes + optimizations
|
||||
CombinedRegionFunction.inject(); // Optimizations
|
||||
ChangeSetExecutor.inject(); // Optimizations
|
||||
// Expression
|
||||
ExpressionEnvironment.inject(); // Optimizations + features
|
||||
@ -655,16 +611,6 @@ public class Fawe {
|
||||
// BlockData
|
||||
BlockData.inject(); // Temporary fix for 1.9.4
|
||||
BundledBlockData.inject(); // Add custom rotation
|
||||
File jar = MainUtil.getJarFile();
|
||||
File extraBlocks = MainUtil.copyFile(jar, "extrablocks.json", null);
|
||||
if (extraBlocks != null && extraBlocks.exists()) {
|
||||
try {
|
||||
BundledBlockData.getInstance().loadFromResource();
|
||||
BundledBlockData.getInstance().add(extraBlocks.toURI().toURL(), true);
|
||||
} catch (Throwable ignore) {
|
||||
Fawe.debug("Invalid format: extrablocks.json");
|
||||
}
|
||||
}
|
||||
// NBT
|
||||
NBTInputStream.inject(); // Add actual streaming + Optimizations + New methods
|
||||
NBTOutputStream.inject(); // New methods
|
||||
@ -697,34 +643,36 @@ public class Fawe {
|
||||
debug(" - AsyncWorldEdit/WorldEditRegions isn't installed");
|
||||
debug(" - Any other errors in the startup log");
|
||||
debug("Contact Empire92 if you need assistance:");
|
||||
debug(" - Send me a PM or ask on IRC/Discord");
|
||||
debug(" - http://webchat.esper.net/?nick=&channels=IntellectualCrafters");
|
||||
debug(" - Send me a PM or ask on Discord");
|
||||
debug(" - https://discord.gg/ngZCzbU");
|
||||
debug("=======================================");
|
||||
}
|
||||
try {
|
||||
com.github.luben.zstd.util.Native.load();
|
||||
} catch (Throwable e) {
|
||||
if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL > 6 || Settings.IMP.HISTORY.COMPRESSION_LEVEL > 6) {
|
||||
Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL = Math.min(6, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
||||
Settings.IMP.HISTORY.COMPRESSION_LEVEL = Math.min(6, Settings.IMP.HISTORY.COMPRESSION_LEVEL);
|
||||
debug("====== ZSTD COMPRESSION BINDING NOT FOUND ======");
|
||||
if (!Settings.IMP.EXPERIMENTAL.DISABLE_NATIVES) {
|
||||
try {
|
||||
com.github.luben.zstd.util.Native.load();
|
||||
} catch (Throwable e) {
|
||||
if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL > 6 || Settings.IMP.HISTORY.COMPRESSION_LEVEL > 6) {
|
||||
Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL = Math.min(6, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
||||
Settings.IMP.HISTORY.COMPRESSION_LEVEL = Math.min(6, Settings.IMP.HISTORY.COMPRESSION_LEVEL);
|
||||
debug("====== ZSTD COMPRESSION BINDING NOT FOUND ======");
|
||||
debug(e);
|
||||
debug("===============================================");
|
||||
debug("FAWE will work but won't compress data as much");
|
||||
debug("===============================================");
|
||||
}
|
||||
}
|
||||
try {
|
||||
net.jpountz.util.Native.load();
|
||||
} catch (Throwable e) {
|
||||
debug("====== LZ4 COMPRESSION BINDING NOT FOUND ======");
|
||||
debug(e);
|
||||
debug("===============================================");
|
||||
debug("FAWE will work but won't compress data as much");
|
||||
debug("FAWE will work but compression will be slower");
|
||||
debug(" - Try updating your JVM / OS");
|
||||
debug(" - Report this issue if you cannot resolve it");
|
||||
debug("===============================================");
|
||||
}
|
||||
}
|
||||
try {
|
||||
net.jpountz.util.Native.load();
|
||||
} catch (Throwable e) {
|
||||
debug("====== LZ4 COMPRESSION BINDING NOT FOUND ======");
|
||||
debug(e);
|
||||
debug("===============================================");
|
||||
debug("FAWE will work but compression will be slower");
|
||||
debug(" - Try updating your JVM / OS");
|
||||
debug(" - Report this issue if you cannot resolve it");
|
||||
debug("===============================================");
|
||||
}
|
||||
try {
|
||||
String arch = System.getenv("PROCESSOR_ARCHITECTURE");
|
||||
String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432");
|
||||
@ -792,7 +740,7 @@ public class Fawe {
|
||||
}
|
||||
|
||||
public static boolean isMainThread() {
|
||||
return INSTANCE != null ? INSTANCE.thread == Thread.currentThread() : true;
|
||||
return INSTANCE != null ? imp().isMainThread() : true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -810,6 +758,7 @@ public class Fawe {
|
||||
public <T> void register(FawePlayer<T> player) {
|
||||
players.put(player.getName(), player);
|
||||
playersUUID.put(player.getUUID(), player);
|
||||
|
||||
}
|
||||
|
||||
public <T> void unregister(String name) {
|
||||
|
@ -267,7 +267,7 @@ public class FaweAPI {
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public static RegionWrapper[] getRegions(FawePlayer player) {
|
||||
public static Region[] getRegions(FawePlayer player) {
|
||||
return WEManager.IMP.getMask(player);
|
||||
}
|
||||
|
||||
|
@ -544,8 +544,6 @@ public class FaweCache {
|
||||
case 185:
|
||||
case 186:
|
||||
case 187:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
@ -658,6 +656,8 @@ public class FaweCache {
|
||||
case 142:
|
||||
case 27:
|
||||
case 137:
|
||||
case 188:
|
||||
case 189:
|
||||
case 52:
|
||||
case 154:
|
||||
case 84:
|
||||
@ -710,8 +710,204 @@ public class FaweCache {
|
||||
case 233:
|
||||
case 234:
|
||||
return true;
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 24:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 34:
|
||||
case 35:
|
||||
case 36:
|
||||
case 37:
|
||||
case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 50:
|
||||
case 51:
|
||||
case 53:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 59:
|
||||
case 60:
|
||||
case 64:
|
||||
case 65:
|
||||
case 67:
|
||||
case 69:
|
||||
case 70:
|
||||
case 71:
|
||||
case 72:
|
||||
case 73:
|
||||
case 74:
|
||||
case 75:
|
||||
case 76:
|
||||
case 77:
|
||||
case 78:
|
||||
case 79:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
case 85:
|
||||
case 86:
|
||||
case 87:
|
||||
case 88:
|
||||
case 89:
|
||||
case 90:
|
||||
case 91:
|
||||
case 92:
|
||||
case 93:
|
||||
case 94:
|
||||
case 95:
|
||||
case 96:
|
||||
case 97:
|
||||
case 98:
|
||||
case 99:
|
||||
case 100:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 104:
|
||||
case 105:
|
||||
case 106:
|
||||
case 107:
|
||||
case 108:
|
||||
case 109:
|
||||
case 110:
|
||||
case 111:
|
||||
case 112:
|
||||
case 113:
|
||||
case 114:
|
||||
case 115:
|
||||
case 118:
|
||||
case 120:
|
||||
case 121:
|
||||
case 122:
|
||||
case 125:
|
||||
case 126:
|
||||
case 127:
|
||||
case 128:
|
||||
case 129:
|
||||
case 131:
|
||||
case 132:
|
||||
case 133:
|
||||
case 134:
|
||||
case 135:
|
||||
case 136:
|
||||
case 139:
|
||||
case 141:
|
||||
case 143:
|
||||
case 145:
|
||||
case 147:
|
||||
case 148:
|
||||
case 152:
|
||||
case 153:
|
||||
case 155:
|
||||
case 156:
|
||||
case 159:
|
||||
case 160:
|
||||
case 161:
|
||||
case 162:
|
||||
case 163:
|
||||
case 164:
|
||||
case 165:
|
||||
case 166:
|
||||
case 167:
|
||||
case 168:
|
||||
case 169:
|
||||
case 170:
|
||||
case 171:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 175:
|
||||
case 179:
|
||||
case 180:
|
||||
case 181:
|
||||
case 182:
|
||||
case 183:
|
||||
case 184:
|
||||
case 185:
|
||||
case 186:
|
||||
case 187:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
case 193:
|
||||
case 194:
|
||||
case 195:
|
||||
case 196:
|
||||
case 197:
|
||||
case 198:
|
||||
case 199:
|
||||
case 200:
|
||||
case 201:
|
||||
case 202:
|
||||
case 203:
|
||||
case 204:
|
||||
case 205:
|
||||
case 206:
|
||||
case 207:
|
||||
case 208:
|
||||
case 212:
|
||||
case 213:
|
||||
case 214:
|
||||
case 215:
|
||||
case 216:
|
||||
case 217:
|
||||
case 235:
|
||||
case 236:
|
||||
case 237:
|
||||
case 238:
|
||||
case 239:
|
||||
case 240:
|
||||
case 241:
|
||||
case 242:
|
||||
case 243:
|
||||
case 244:
|
||||
case 245:
|
||||
case 246:
|
||||
case 247:
|
||||
case 248:
|
||||
case 249:
|
||||
case 250:
|
||||
case 251:
|
||||
case 252:
|
||||
return false;
|
||||
default:
|
||||
return id > 256;
|
||||
return id > 252;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.gui.FormBuilder;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.File;
|
||||
@ -39,6 +40,8 @@ public interface IFawe {
|
||||
|
||||
default ImageViewer getImageViewer(FawePlayer player) { return null; }
|
||||
|
||||
public default void registerPacketListener() {}
|
||||
|
||||
default int getPlayerCount() {
|
||||
return Fawe.get().getCachedPlayers().size();
|
||||
}
|
||||
@ -58,4 +61,12 @@ public interface IFawe {
|
||||
public default String getDebugInfo() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public default FormBuilder getFormBuilder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default boolean isMainThread() {
|
||||
return Fawe.get().getMainThread() == Thread.currentThread();
|
||||
}
|
||||
}
|
||||
|
@ -4,23 +4,8 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAClipboard;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAQueue;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.CountFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.CountIdFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.DeleteOldFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.DeleteUnclaimedFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.DeleteUninhabitedFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.MappedReplacePatternFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.PlotTrimFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.RemapFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.RemoveLayerFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.ReplacePatternFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.ReplaceSimpleFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.TrimAirFilter;
|
||||
import com.boydti.fawe.jnbt.anvil.*;
|
||||
import com.boydti.fawe.jnbt.anvil.filters.*;
|
||||
import com.boydti.fawe.jnbt.anvil.history.IAnvilHistory;
|
||||
import com.boydti.fawe.jnbt.anvil.history.NullAnvilHistory;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
@ -35,11 +20,8 @@ import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
@ -51,13 +33,11 @@ import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
@ -90,6 +70,12 @@ public class AnvilCommands {
|
||||
*/
|
||||
@Deprecated
|
||||
public static <G, T extends MCAFilter<G>> T runWithWorld(Player player, String folder, T filter, boolean force) {
|
||||
return runWithWorld(player, folder, filter, force, false);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public static <G, T extends MCAFilter<G>> T runWithWorld(Player player, String folder, T filter, boolean force, boolean unsafe) {
|
||||
boolean copy = false;
|
||||
if (FaweAPI.getWorld(folder) != null) {
|
||||
if (!force) {
|
||||
@ -100,7 +86,7 @@ public class AnvilCommands {
|
||||
}
|
||||
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
|
||||
MCAQueue queue = new MCAQueue(defaultQueue);
|
||||
if (copy) {
|
||||
if (copy && !unsafe) {
|
||||
return queue.filterCopy(filter, RegionWrapper.GLOBAL());
|
||||
} else {
|
||||
return queue.filterWorld(filter);
|
||||
@ -294,7 +280,21 @@ public class AnvilCommands {
|
||||
String folder = Fawe.imp().getWorldName(player.getWorld());
|
||||
int visitTime = deleteUnvisited ? 1 : -1;
|
||||
PlotTrimFilter filter = new PlotTrimFilter(player.getWorld(), 0, visitTime, 600000);
|
||||
PlotTrimFilter result = runWithWorld(player, folder, filter, true);
|
||||
// PlotTrimFilter result = runWithWorld(player, folder, filter, true);
|
||||
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
|
||||
MCAQueue queue = new MCAQueue(defaultQueue);
|
||||
PlotTrimFilter result = queue.filterWorld(filter);
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"deletebiomechunks", },
|
||||
desc = "Delete chunks matching a specific biome"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.trimallair")
|
||||
public void deleteBiome(Player player, String folder, BaseBiome biome, @Switch('u') boolean unsafe) {
|
||||
DeleteBiomeFilterSimple filter = new DeleteBiomeFilterSimple(biome);
|
||||
DeleteBiomeFilterSimple result = runWithWorld(player, folder, filter, true, unsafe);
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
@ -303,12 +303,47 @@ public class AnvilCommands {
|
||||
desc = "Trim all air in the world"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.trimallair")
|
||||
public void trimAllAir(Player player, String folder) throws WorldEditException {
|
||||
public void trimAllAir(Player player, String folder, @Switch('u') boolean unsafe) throws WorldEditException {
|
||||
TrimAirFilter filter = new TrimAirFilter();
|
||||
TrimAirFilter result = runWithWorld(player, folder, filter, true);
|
||||
TrimAirFilter result = runWithWorld(player, folder, filter, true, unsafe);
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = {"trimallflat", },
|
||||
desc = "Trim all flat chunks"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.trimallflat")
|
||||
public void trimFlatFilter(Player player, String folder, @Switch('u') boolean unsafe) throws WorldEditException {
|
||||
TrimFlatFilter filter = new TrimFlatFilter();
|
||||
TrimFlatFilter result = runWithWorld(player, folder, filter, true, unsafe);
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = {"debugfixair", },
|
||||
desc = "debug - do not use"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.debugfixair")
|
||||
public void debugfixair(Player player, String folder) throws WorldEditException {
|
||||
DebugFixAir filter = new DebugFixAir();
|
||||
DebugFixAir result = runWithWorld(player, folder, filter, true, true);
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
// @Command(
|
||||
// aliases = {"debugfixroads", },
|
||||
// desc = "debug - do not use"
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.debugfixroads")
|
||||
// public void debugfixroads(Player player, String folder) throws WorldEditException {
|
||||
// DebugFixP2Roads filter = new DebugFixP2Roads();
|
||||
// DebugFixP2Roads result = runWithWorld(player, folder, filter, true, true);
|
||||
// if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
// }
|
||||
|
||||
@Command(
|
||||
aliases = {"replaceallpattern", "reap", "repallpat"},
|
||||
usage = "<folder> [from-block] <to-pattern>",
|
||||
@ -571,6 +606,21 @@ public class AnvilCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"set"},
|
||||
usage = "<to-pattern>",
|
||||
desc = "Set all blocks in the selection with a pattern"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.set")
|
||||
// Player player, String folder, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap
|
||||
public void set(Player player, EditSession editSession, @Selection Region selection, final Pattern to) throws WorldEditException {
|
||||
MCAFilterCounter filter = new SetPatternFilter(to);
|
||||
MCAFilterCounter result = runWithSelection(player, editSession, selection, filter);
|
||||
if (result != null) {
|
||||
player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"removelayers"},
|
||||
usage = "<id>",
|
||||
|
@ -8,12 +8,8 @@ import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
import com.boydti.fawe.util.FilteredTextureUtil;
|
||||
import com.boydti.fawe.util.ImgurUtility;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.object.pattern.PatternExtent;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.boydti.fawe.util.chat.Message;
|
||||
import com.boydti.fawe.util.image.ImageUtil;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
@ -33,12 +29,9 @@ import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EmptyClipboardException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.command.MethodCommands;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
@ -46,6 +39,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
@ -58,15 +52,18 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@Command(aliases = {"/cfi"}, desc = "Create a world from images: [More Info](https://git.io/v5iDy)")
|
||||
@ -94,8 +91,22 @@ public class CFICommands extends MethodCommands {
|
||||
desc = "Start CFI with a height map as a base"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void heightmap(FawePlayer fp, BufferedImage image) {
|
||||
HeightMapMCAGenerator generator = new HeightMapMCAGenerator(image, getFolder("CFI-" + UUID.randomUUID()));
|
||||
public void heightmap(FawePlayer fp, BufferedImage image, @Optional("1") double yscale) {
|
||||
if (yscale != 0) {
|
||||
int[] raw = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
int[] table = new int[256];
|
||||
for (int i = 0; i < table.length; i++) {
|
||||
table[i] = Math.min(255, (int) (i * yscale));
|
||||
}
|
||||
for (int i = 0; i < raw.length; i++) {
|
||||
int color = raw[i];
|
||||
int red = table[(color >> 16) & 0xFF];
|
||||
int green = table[(color >> 8) & 0xFF];
|
||||
int blue = table[(color >> 0) & 0xFF];
|
||||
raw[i] = (red << 16) + (green << 8) + (blue << 0);
|
||||
}
|
||||
}
|
||||
HeightMapMCAGenerator generator = new HeightMapMCAGenerator(image, getFolder(generateName()));
|
||||
setup(generator, fp);
|
||||
}
|
||||
|
||||
@ -106,14 +117,20 @@ public class CFICommands extends MethodCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void heightmap(FawePlayer fp, int width, int length) {
|
||||
HeightMapMCAGenerator generator = new HeightMapMCAGenerator(width, length, getFolder("CFI-" + UUID.randomUUID()));
|
||||
HeightMapMCAGenerator generator = new HeightMapMCAGenerator(width, length, getFolder(generateName()));
|
||||
setup(generator, fp);
|
||||
}
|
||||
|
||||
private String generateName() {
|
||||
DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH.mm.ss");
|
||||
String data = df.format(new Date());
|
||||
return data;
|
||||
}
|
||||
|
||||
private void setup(HeightMapMCAGenerator generator, FawePlayer fp) {
|
||||
CFISettings settings = getSettings(fp);
|
||||
settings.remove().setGenerator(generator).bind();
|
||||
CFISettings settings = getSettings(fp).remove();
|
||||
generator.setPacketViewer(fp);
|
||||
settings.setGenerator(generator).bind();
|
||||
generator.setImageViewer(Fawe.imp().getImageViewer(fp));
|
||||
generator.update();
|
||||
mainMenu(fp);
|
||||
@ -367,7 +384,7 @@ public class CFICommands extends MethodCommands {
|
||||
"`#clipboard` will only use the blocks present in your clipboard."
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void paletteblocks(FawePlayer fp, @Optional String arg) throws ParameterException, EmptyClipboardException, InputParseException, FileNotFoundException {
|
||||
public void paletteblocks(FawePlayer fp, Player player, LocalSession session, @Optional String arg) throws ParameterException, EmptyClipboardException, InputParseException, FileNotFoundException {
|
||||
if (arg == null) {
|
||||
msg("What blocks do you want to color with?").newline()
|
||||
.text("&7[&aAll&7]").cmdTip(alias() + " PaletteBlocks *").text(" - All available blocks")
|
||||
@ -392,6 +409,7 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
Set<BaseBlock> blocks;
|
||||
switch (arg.toLowerCase()) {
|
||||
case "true":
|
||||
case "*": {
|
||||
generator.setTextureUtil(Fawe.get().getTextureUtil());
|
||||
return;
|
||||
@ -410,7 +428,23 @@ public class CFICommands extends MethodCommands {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
blocks = worldEdit.getBlockFactory().parseFromListInput(arg, context);
|
||||
blocks = new HashSet<>();
|
||||
BlockPattern pattern = new BlockPattern(new BaseBlock(BlockID.AIR));
|
||||
PatternExtent extent = new PatternExtent(pattern);
|
||||
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(player);
|
||||
parserContext.setWorld(player.getWorld());
|
||||
parserContext.setSession(session);
|
||||
parserContext.setExtent(extent);
|
||||
Request.request().setExtent(extent);
|
||||
Mask mask = worldEdit.getMaskFactory().parseFromInput(arg, parserContext);
|
||||
TextureUtil tu = Fawe.get().getTextureUtil();
|
||||
for (int combinedId : tu.getValidBlockIds()) {
|
||||
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
||||
pattern.setBlock(block);
|
||||
if (mask.test(Vector.ZERO)) blocks.add(block);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -582,15 +616,28 @@ public class CFICommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"thickness", "width", "floorthickness"},
|
||||
aliases = {"worldthickness", "width", "thickness"},
|
||||
usage = "<height>",
|
||||
desc = "Set the thickness of the generated world from the floor\n" +
|
||||
desc = "Set the thickness of the generated world\n" +
|
||||
" - A value of 0 is the default and will not modify the height"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void worldthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setWorldThickness(height);
|
||||
msg("Set world thickness!").send(fp);
|
||||
component(fp);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"floorthickness", "floorheight", "floorwidth"},
|
||||
usage = "<height>",
|
||||
desc = "Set the thickness of the top layer\n" +
|
||||
" - A value of 0 is the default and will only set the top block"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void floorthickness(FawePlayer fp, int height) throws ParameterException, WorldEditException {
|
||||
assertSettings(fp).getGenerator().setFloorThickness(height);
|
||||
msg("Set world thickness!").send(fp);
|
||||
msg("Set floor thickness!").send(fp);
|
||||
component(fp);
|
||||
}
|
||||
|
||||
@ -639,6 +686,7 @@ public class CFICommands extends MethodCommands {
|
||||
usage = "<url>",
|
||||
desc = "Color terrain using glass"
|
||||
)
|
||||
// ![79,174,212,5:3,5:4,18,161,20]
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void glass(FawePlayer fp, BufferedImage image, @Optional BufferedImage imageMask, @Optional Mask mask, @Switch('w') boolean disableWhiteOnly) throws ParameterException, WorldEditException {
|
||||
CFISettings settings = assertSettings(fp);
|
||||
@ -855,7 +903,7 @@ public class CFICommands extends MethodCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.cfi")
|
||||
public void image(FawePlayer fp, @Optional BufferedImage image, CommandContext context) throws ParameterException, CommandException {
|
||||
CFISettings settings = getSettings(fp).bind();
|
||||
CFISettings settings = getSettings(fp);
|
||||
String[] split = getArguments(context).split(" ");
|
||||
int index = 2;
|
||||
|
||||
@ -944,6 +992,8 @@ public class CFICommands extends MethodCommands {
|
||||
.newline()
|
||||
.text("&7[&aFloorThickness&7]").suggestTip(alias() + " " + alias("floorthickness") + " 60").text(" - Floor thickness of entire map")
|
||||
.newline()
|
||||
.text("&7[&aWorldThickness&7]").suggestTip(alias() + " " + alias("worldthickness") + " 60").text(" - World thickness of entire map")
|
||||
.newline()
|
||||
.text("&7[&aSnow&7]").suggestTip(alias() + " " + alias("snow") + maskArgs).text(" - Set snow in the masked areas")
|
||||
.newline();
|
||||
|
||||
@ -1006,6 +1056,8 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
protected String category;
|
||||
|
||||
private boolean bound;
|
||||
|
||||
public CFISettings(FawePlayer player) {
|
||||
this.fp = player;
|
||||
}
|
||||
@ -1063,10 +1115,13 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
public CFISettings setGenerator(HeightMapMCAGenerator generator) {
|
||||
this.generator = generator;
|
||||
if (bound) fp.getSession().setVirtualWorld(generator);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CFISettings bind() {
|
||||
if (generator != null) fp.getSession().setVirtualWorld(generator);
|
||||
bound = true;
|
||||
fp.setMeta("CFISettings", this);
|
||||
return this;
|
||||
}
|
||||
@ -1084,11 +1139,10 @@ public class CFICommands extends MethodCommands {
|
||||
fp.deleteMeta("CFISettings");
|
||||
HeightMapMCAGenerator gen = this.generator;
|
||||
if (gen != null) {
|
||||
gen.close();
|
||||
LocalSession session = fp.getSession();
|
||||
session.clearHistory();
|
||||
fp.getSession().setVirtualWorld(null);
|
||||
}
|
||||
popMessages(fp);
|
||||
bound = false;
|
||||
generator = null;
|
||||
image = null;
|
||||
imageArg = null;
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import java.util.Collection;
|
||||
@ -20,21 +21,7 @@ public class Cancel extends FaweCommand {
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
UUID uuid = player.getUUID();
|
||||
Collection<FaweQueue> queues = SetQueue.IMP.getAllQueues();
|
||||
int cancelled = 0;
|
||||
player.clearActions();
|
||||
for (FaweQueue queue : queues) {
|
||||
Collection<EditSession> sessions = queue.getEditSessions();
|
||||
for (EditSession session : sessions) {
|
||||
FawePlayer currentPlayer = session.getPlayer();
|
||||
if (currentPlayer == player) {
|
||||
if (session.cancel()) {
|
||||
cancelled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int cancelled = player.cancel(false);
|
||||
BBC.WORLDEDIT_CANCEL_COUNT.send(player, cancelled);
|
||||
return true;
|
||||
}
|
||||
|
@ -5,11 +5,9 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class FaweParser<T> extends InputParser<T> {
|
||||
protected FaweParser(WorldEdit worldEdit) {
|
||||
@ -25,27 +23,15 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> suggestRemaining(String input, String... expected) throws InputParseException {
|
||||
List<String> remainder = StringMan.split(input, ':');
|
||||
int len = remainder.size();
|
||||
if (len != expected.length - 1) {
|
||||
if (len <= expected.length - 1 && len != 0) {
|
||||
if (remainder.get(len - 1).endsWith(":")) {
|
||||
throw new SuggestInputParseException(null, StringMan.join(expected, ":"));
|
||||
}
|
||||
throw new SuggestInputParseException(null, expected[0] + ":" + input + ":" + StringMan.join(Arrays.copyOfRange(expected, len + 1, 3), ":"));
|
||||
} else {
|
||||
throw new SuggestInputParseException(null, StringMan.join(expected, ":"));
|
||||
}
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
public abstract Dispatcher getDispatcher();
|
||||
|
||||
protected static class ParseEntry {
|
||||
public boolean and;
|
||||
public String input;
|
||||
public String full;
|
||||
|
||||
public ParseEntry(String input, boolean type) {
|
||||
public ParseEntry(String full, String input, boolean type) {
|
||||
this.full = full;
|
||||
this.input = input;
|
||||
this.and = type;
|
||||
}
|
||||
@ -56,66 +42,54 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public List<Map.Entry<ParseEntry, List<String>>> parse(String command) throws InputParseException {
|
||||
public static List<Map.Entry<ParseEntry, List<String>>> parse(String toParse) throws InputParseException {
|
||||
List<Map.Entry<ParseEntry, List<String>>> keys = new ArrayList<>();
|
||||
List<String> args = new ArrayList<>();
|
||||
int len = command.length();
|
||||
String current = null;
|
||||
int end = -1;
|
||||
boolean newEntry = true;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int prefix = 0;
|
||||
boolean or = false;
|
||||
char c = command.charAt(i);
|
||||
if (i < end) continue;
|
||||
List<String> inputs = new ArrayList<>();
|
||||
List<Boolean> and = new ArrayList<>();
|
||||
int last = 0;
|
||||
outer:
|
||||
for (int i = 0; i < toParse.length(); i++) {
|
||||
char c = toParse.charAt(i);
|
||||
switch (c) {
|
||||
case ',':
|
||||
case '&':
|
||||
or = true;
|
||||
case ',': {
|
||||
prefix = 1;
|
||||
if (current == null) {
|
||||
throw new InputParseException("Duplicate separator");
|
||||
String result = toParse.substring(last, i);
|
||||
if (!result.isEmpty()) {
|
||||
inputs.add(result);
|
||||
and.add(c == '&');
|
||||
} else {
|
||||
throw new InputParseException("Invalid dangling character " + c);
|
||||
}
|
||||
newEntry = true;
|
||||
break;
|
||||
}
|
||||
case '[': {
|
||||
int depth = 0;
|
||||
end = len;
|
||||
loop:
|
||||
for (int j = i + 1; j < len; j++) {
|
||||
char c2 = command.charAt(j);
|
||||
switch (c2) {
|
||||
case '[':
|
||||
depth++;
|
||||
continue;
|
||||
case ']':
|
||||
if (depth-- <= 0) {
|
||||
end = j;
|
||||
break loop;
|
||||
}
|
||||
last = i + 1;
|
||||
continue outer;
|
||||
default:
|
||||
if (c == '[') {
|
||||
int next = StringMan.findMatchingBracket(toParse, i);
|
||||
if (next != -1) {
|
||||
i = next;
|
||||
} else {
|
||||
toParse += "]";
|
||||
i = toParse.length();
|
||||
}
|
||||
continue outer;
|
||||
}
|
||||
String arg = command.substring(i + 1, end);
|
||||
args.add(arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newEntry) {
|
||||
newEntry = false;
|
||||
int index = StringMan.indexOf(command, Math.max(i, end) + prefix, '[', '&', ',');
|
||||
if (index < 0) index = len;
|
||||
end = index;
|
||||
current = command.substring(i + prefix, end);
|
||||
if (prefix == 1) args = new ArrayList<>();
|
||||
ParseEntry entry = new ParseEntry(current, or);
|
||||
keys.add(new AbstractMap.SimpleEntry<>(entry, args));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < keys.size() - 1; i++) { // Apply greedy and
|
||||
if (keys.get(i + 1).getKey().and) {
|
||||
keys.get(i).getKey().and = true;
|
||||
inputs.add(toParse.substring(last, toParse.length()));
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
String full = inputs.get(i);
|
||||
String command = full;
|
||||
List<String> args = new ArrayList<>();
|
||||
while (!command.isEmpty() && command.charAt(command.length() - 1) == ']') {
|
||||
int startPos = StringMan.findMatchingBracket(command, command.length() - 1);
|
||||
if (startPos == -1) break;
|
||||
String arg = command.substring(startPos + 1, command.length() - 1);
|
||||
args.add(arg);
|
||||
command = full.substring(0, startPos);
|
||||
}
|
||||
Collections.reverse(args);
|
||||
ParseEntry entry = new ParseEntry(full, command, i > 0 ? and.get(i - 1) : false);
|
||||
keys.add(new AbstractMap.SimpleEntry<>(entry, args));
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.image.ImageUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -70,12 +71,26 @@ public class FawePrimitiveBinding extends BindingHelper {
|
||||
}
|
||||
@BindingMatch(
|
||||
type = {BufferedImage.class},
|
||||
behavior = BindingBehavior.CONSUMES
|
||||
behavior = BindingBehavior.CONSUMES,
|
||||
consumedCount = 1,
|
||||
provideModifiers = true
|
||||
)
|
||||
public BufferedImage getImage(ArgumentStack context) throws ParameterException {
|
||||
public BufferedImage getImage(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
|
||||
return ImageUtil.getImage(context.next());
|
||||
}
|
||||
|
||||
@BindingMatch(
|
||||
type = {TextureUtil.class},
|
||||
behavior = BindingBehavior.PROVIDES
|
||||
)
|
||||
public TextureUtil getTexture(ArgumentStack context) {
|
||||
Actor actor = context.getContext().getLocals().get(Actor.class);
|
||||
if (actor == null) return Fawe.get().getCachedTextureUtil(true, 0, 100);
|
||||
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
|
||||
return session.getTextureUtil();
|
||||
}
|
||||
|
||||
|
||||
@BindingMatch(
|
||||
type = {Extent.class},
|
||||
behavior = BindingBehavior.PROVIDES
|
||||
@ -161,6 +176,28 @@ public class FawePrimitiveBinding extends BindingHelper {
|
||||
return v;
|
||||
}
|
||||
|
||||
@BindingMatch(type = { Expression.class },
|
||||
behavior = BindingBehavior.CONSUMES,
|
||||
consumedCount = 1)
|
||||
public Expression getExpression(ArgumentStack context) throws ParameterException, ExpressionException {
|
||||
String input = context.next();
|
||||
try {
|
||||
return new Expression(Double.parseDouble(input));
|
||||
} catch (NumberFormatException e1) {
|
||||
try {
|
||||
Expression expression = Expression.compile(input);
|
||||
expression.optimize();
|
||||
return expression;
|
||||
} catch (EvaluationException e) {
|
||||
throw new ParameterException(String.format(
|
||||
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
|
||||
} catch (ExpressionException e) {
|
||||
throw new ParameterException(String.format(
|
||||
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link ArgumentStack}.
|
||||
*
|
||||
|
@ -2,87 +2,87 @@ package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SuggestInputParseException extends InputParseException {
|
||||
|
||||
private final String message;
|
||||
private final InputParseException cause;
|
||||
private final SuggestSupplier<List<String>> getSuggestions;
|
||||
private String prefix;
|
||||
private ArrayList<String> suggestions = new ArrayList<>();
|
||||
|
||||
public SuggestInputParseException(String input, Collection<String> inputs) {
|
||||
super("");
|
||||
this.message = "Suggested input: " + StringMan.join(suggestions = getSuggestions(input, inputs), ", ");
|
||||
this.prefix = "";
|
||||
public SuggestInputParseException(String msg, String prefix, SuggestSupplier<List<String>> getSuggestions) {
|
||||
this(new InputParseException(msg), prefix, getSuggestions);
|
||||
}
|
||||
|
||||
public SuggestInputParseException(String input, String... inputs) {
|
||||
super("");
|
||||
this.message = "Suggested input: " + StringMan.join(suggestions = getSuggestions(input, inputs), ", ");
|
||||
this.prefix = "";
|
||||
public static SuggestInputParseException of(Throwable other, String prefix, SuggestSupplier<List<String>> getSuggestions) {
|
||||
InputParseException e = find(other);
|
||||
if (e != null) return of(e, prefix, getSuggestions);
|
||||
return of(new InputParseException(other.getMessage()), prefix, getSuggestions);
|
||||
}
|
||||
|
||||
public static SuggestInputParseException of(InputParseException other, String prefix, SuggestSupplier<List<String>> getSuggestions) {
|
||||
if (other instanceof SuggestInputParseException) return (SuggestInputParseException) other;
|
||||
return new SuggestInputParseException(other, prefix, getSuggestions);
|
||||
}
|
||||
|
||||
public SuggestInputParseException(InputParseException other, String prefix, SuggestSupplier<List<String>> getSuggestions) {
|
||||
super(other.getMessage());
|
||||
checkNotNull(getSuggestions);
|
||||
checkNotNull(other);
|
||||
this.cause = other;
|
||||
this.getSuggestions = getSuggestions;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public interface SuggestSupplier<T> {
|
||||
T get() throws InputParseException;
|
||||
}
|
||||
|
||||
public static InputParseException find(Throwable e) {
|
||||
do {
|
||||
if (e instanceof InputParseException) return (InputParseException) e;
|
||||
e = e.getCause();
|
||||
}
|
||||
while (e != null);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SuggestInputParseException get(Throwable e) {
|
||||
Throwable t = e;
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
if (t instanceof SuggestInputParseException) return (SuggestInputParseException) t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Throwable getCause() {
|
||||
return cause.getCause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return cause.getMessage();
|
||||
}
|
||||
|
||||
public List<String> getSuggestions() {
|
||||
return MainUtil.prepend(prefix, suggestions);
|
||||
|
||||
public List<String> getSuggestions() throws InputParseException {
|
||||
return getSuggestions.get();
|
||||
}
|
||||
|
||||
public SuggestInputParseException prepend(String input) {
|
||||
this.prefix = input + prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static SuggestInputParseException get(Throwable e) {
|
||||
if (e instanceof SuggestInputParseException) {
|
||||
return (SuggestInputParseException) e;
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause == null) {
|
||||
return null;
|
||||
}
|
||||
return get(cause);
|
||||
}
|
||||
|
||||
private static ArrayList<String> getSuggestions(String input, Collection<String> inputs) {
|
||||
ArrayList<String> suggestions = new ArrayList<>();
|
||||
if (input != null) {
|
||||
String tmp = input.toLowerCase();
|
||||
for (String s : inputs) {
|
||||
if (s.startsWith(tmp)) {
|
||||
suggestions.add(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (suggestions.isEmpty()) {
|
||||
suggestions.addAll(inputs);
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
private static ArrayList<String> getSuggestions(String input, String... inputs) {
|
||||
ArrayList<String> suggestions = new ArrayList<>();
|
||||
if (input != null) {
|
||||
String tmp = input.toLowerCase();
|
||||
for (String s : inputs) {
|
||||
if (s.startsWith(tmp)) {
|
||||
suggestions.add(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (suggestions.isEmpty()) {
|
||||
for (String s : inputs) {
|
||||
suggestions.add(s);
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ public enum BBC {
|
||||
WORLDEDIT_ITERATIONS("&7You cannot iterate %current% times. The maximum number of iterations allowed is %max%.", "Info"),
|
||||
WORLDEDIT_UNSAFE("&7Access to that command has been blocked", "Info"),
|
||||
WORLDEDIT_DANGEROUS_WORLDEDIT("&cProcessed unsafe edit at %s0 by %s1", "Info"),
|
||||
WORLDEDIT_BYPASS("&7&oTo bypass your restrictions use &c/wea", "Info"),
|
||||
WORLDEDIT_EXTEND("&cYour edit may have extended outside your allowed region.", "Error"),
|
||||
WORLDEDIT_TOGGLE_TIPS_ON("&7Disabled FAWE tips.", "Info"),
|
||||
WORLDEDIT_TOGGLE_TIPS_OFF("&7Enabled FAWE tips.", "Info"),
|
||||
@ -63,6 +62,8 @@ public enum BBC {
|
||||
|
||||
MASK_DISABLED("Global mask disabled", "WorldEdit.General"),
|
||||
MASK("Global mask set", "WorldEdit.General"),
|
||||
TEXTURE_DISABLED("Texturing reset", "WorldEdit.General"),
|
||||
TEXTURE_SET("Set texturing to %s1", "WorldEdit.General"),
|
||||
SOURCE_MASK_DISABLED("Global source mask disabled", "WorldEdit.General"),
|
||||
SOURCE_MASK("Global source mask set", "WorldEdit.General"),
|
||||
TRANSFORM_DISABLED("Global transform disabled", "WorldEdit.General"),
|
||||
@ -90,9 +91,9 @@ public enum BBC {
|
||||
COMMAND_HISTORY_CLEAR("History cleared", "WorldEdit.History"),
|
||||
COMMAND_REDO_ERROR("Nothing left to redo. (See also `/inspect` and `/frb`)", "WorldEdit.History"),
|
||||
COMMAND_HISTORY_OTHER_ERROR("Unable to find session for %s0.", "WorldEdit.History"),
|
||||
COMMAND_REDO_SUCCESS("Redo successful.", "WorldEdit.History"),
|
||||
COMMAND_REDO_SUCCESS("Redo successful%s0.", "WorldEdit.History"),
|
||||
COMMAND_UNDO_ERROR("Nothing left to undo. (See also `/inspect` and `/frb`)", "WorldEdit.History"),
|
||||
COMMAND_UNDO_SUCCESS("Undo successful.", "WorldEdit.History"),
|
||||
COMMAND_UNDO_SUCCESS("Undo successful%s0.", "WorldEdit.History"),
|
||||
|
||||
OPERATION("Operation queued (%s0)", "WorldEdit.Operation"),
|
||||
|
||||
@ -115,10 +116,10 @@ public enum BBC {
|
||||
|
||||
WORLD_IS_LOADED("The world shouldn't be in use when executing. Unload the world, or use use -f to override (save first)", "WorldEdit.Anvil"),
|
||||
|
||||
BRUSH_RESET("Reset your brush.", "WorldEdit.Brush"),
|
||||
BRUSH_RESET("Reset your brush. (SHIFT + Click)", "WorldEdit.Brush"),
|
||||
BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"),
|
||||
BRUSH_SCROLL_ACTION_SET("Set scroll action to %s0", "WorldEdit.Brush"),
|
||||
BRUSH_SCROLL_ACTION_UNSET("Removed scrol action", "WorldEdit.Brush"),
|
||||
BRUSH_SCROLL_ACTION_UNSET("Removed scroll action", "WorldEdit.Brush"),
|
||||
BRUSH_VISUAL_MODE_SET("Set visual mode to %s0", "WorldEdit.Brush"),
|
||||
BRUSH_TARGET_MODE_SET("Set target mode to %s0", "WorldEdit.Brush"),
|
||||
BRUSH_TARGET_MASK_SET("Set target mask to %s0", "WorldEdit.Brush"),
|
||||
@ -130,6 +131,7 @@ public enum BBC {
|
||||
BRUSH_SMOOTH("Note: Use the blend brush if you want to smooth overhangs or caves.", "WorldEdit.Brush"),
|
||||
BRUSH_SPLINE("Click to add a point, click the same spot to finish", "WorldEdit.Brush"),
|
||||
BRUSH_LINE_PRIMARY("Added point %s0, click another position to create the line", "WorldEdit.Brush"),
|
||||
BRUSH_CATENARY_DIRECTION("Added point %s0, click the direction you want to create the spline", "WorldEdit.Brush"),
|
||||
BRUSH_LINE_SECONDARY("Created spline", "WorldEdit.Brush"),
|
||||
BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
||||
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
||||
@ -144,7 +146,6 @@ public enum BBC {
|
||||
BRUSH_TRANSFORM("Brush transform set", "WorldEdit.Brush"),
|
||||
BRUSH_MATERIAL("Brush material set", "WorldEdit.Brush"),
|
||||
|
||||
|
||||
ROLLBACK_ELEMENT("Undoing %s0", "WorldEdit.Rollback"),
|
||||
|
||||
TOOL_INSPECT("Inspect tool bound to %s0.", "WorldEdit.Tool"),
|
||||
@ -186,7 +187,15 @@ public enum BBC {
|
||||
NOTHING_CONFIRMED("You have no actions pending confirmation.", "WorldEdit.Utility"),
|
||||
|
||||
|
||||
SCHEMATIC_PROMPT_CLEAR("&7You may want to use &c%s0 &7to clear your current clipboard first", "Worldedit.Schematic"),
|
||||
SCHEMATIC_SHOW("&7Displaying &a%s0&7 schematics from &a%s1&7:\n" +
|
||||
"&8 - &aLeft click &7a structure to set your clipboard\n" +
|
||||
"&8 - &aRight click &7to add a structure to your multi-clipboard\n" +
|
||||
"&8 - &7Use &a%s2&7 to go back to the world", "Worldedit.Schematic"),
|
||||
SCHEMATIC_FORMAT("Available formats (Name: Lookup names)", "Worldedit.Schematic"),
|
||||
SCHEMATIC_MOVE_EXISTS("&c%s0 already exists", "Worldedit.Schematic"),
|
||||
SCHEMATIC_MOVE_SUCCESS("&a%s0 -> %s1", "Worldedit.Schematic"),
|
||||
SCHEMATIC_MOVE_FAILED("&a%s0 no moved: %s1", "Worldedit.Schematic"),
|
||||
SCHEMATIC_LOADED("%s0 loaded. Paste it with //paste", "Worldedit.Schematic"),
|
||||
SCHEMATIC_SAVED("%s0 saved.", "Worldedit.Schematic"),
|
||||
SCHEMATIC_PAGE("Page must be %s", "WorldEdit.Schematic"),
|
||||
@ -249,7 +258,7 @@ public enum BBC {
|
||||
WORLDEDIT_SOME_FAILS_BLOCKBAG("&cMissing blocks: %s0", "Error"),
|
||||
|
||||
WORLDEDIT_CANCEL_COUNT("&cCancelled %s0 edits.", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_CONFIRM("&7Your selection is large (%s0 -> %s1). Use &c//confirm &7to execute &c%s2", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_CONFIRM("&7Your selection is large (&c%s0 &7-> &c%s1&7, containing &c%s3&7 blocks). Use &c//confirm &7to execute &c%s2", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON("&cYour WorldEdit action was cancelled:&7 %s0&c.", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_MANUAL("Manual cancellation", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_LOW_MEMORY("Low memory", "Cancel"),
|
||||
@ -258,7 +267,8 @@ public enum BBC {
|
||||
WORLDEDIT_CANCEL_REASON_MAX_TILES("Too many blockstates", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_MAX_ENTITIES("Too many entities", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_MAX_ITERATIONS("Max iterations", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_MAX_FAILS("Outside allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_OUTSIDE_LEVEL("Outside world", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION("Outside allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_NO_REGION("No allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"),
|
||||
WORLDEDIT_FAILED_LOAD_CHUNK("&cSkipped loading chunk: &7%s0;%s1&c. Try increasing chunk-wait.", "Cancel"),
|
||||
|
||||
@ -325,7 +335,7 @@ public enum BBC {
|
||||
TIP_REGEN_0("Tip: Use a biome with /regen [biome]", "Tips"),
|
||||
TIP_REGEN_1("Tip: Use a seed with /regen [biome] [seed]", "Tips"),
|
||||
|
||||
TIP_BIOME_PATTERN("Tip: The &c#biome:forest&7 pattern can be used in any command", "Tips"),
|
||||
TIP_BIOME_PATTERN("Tip: The &c#biome[forest]&7 pattern can be used in any command", "Tips"),
|
||||
TIP_BIOME_MASK("Tip: Restrict to a biome with the `$jungle` mask", "Tips"),;
|
||||
|
||||
|
||||
|
@ -30,6 +30,47 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
|
||||
public static Command fromArgs(String[] aliases, String usage, String desc, int min, int max, String flags, String help, boolean queued /* ignored */) {
|
||||
return new Command() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return Command.class;
|
||||
}
|
||||
@Override
|
||||
public String[] aliases() {
|
||||
return aliases;
|
||||
}
|
||||
@Override
|
||||
public String usage() {
|
||||
return usage;
|
||||
}
|
||||
@Override
|
||||
public String desc() {
|
||||
return desc;
|
||||
}
|
||||
@Override
|
||||
public int min() {
|
||||
return min;
|
||||
}
|
||||
@Override
|
||||
public int max() {
|
||||
return max;
|
||||
}
|
||||
@Override
|
||||
public String flags() {
|
||||
return flags;
|
||||
}
|
||||
@Override
|
||||
public String help() {
|
||||
return help;
|
||||
}
|
||||
@Override
|
||||
public boolean anyFlags() {
|
||||
return !(flags.isEmpty() || flags.matches("[a-z]+"));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Command translate(Class clazz, final Command command) {
|
||||
if (cmdConfig == null || command instanceof TranslatedCommand) {
|
||||
return command;
|
||||
|
@ -3,9 +3,7 @@ package com.boydti.fawe.config;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class Settings extends Config {
|
||||
@Ignore
|
||||
@ -25,21 +23,25 @@ public class Settings extends Config {
|
||||
@Final
|
||||
public String PLATFORM; // These values are set from FAWE before loading
|
||||
|
||||
@Comment({"Options: de",
|
||||
@Comment({"Options: cn, de, es, fr, it, nl, ru, tr",
|
||||
"Create a PR to contribute a translation: https://github.com/boy0001/FastAsyncWorldedit/new/master/core/src/main/resources",})
|
||||
public String LANGUAGE = "";
|
||||
@Comment("Allow the plugin to update")
|
||||
public boolean UPDATE = true;
|
||||
@Comment({"Enable or disable automatic updates",
|
||||
" - true = update automatically in the background",
|
||||
" - confirm = prompt an admin to confirm each update",
|
||||
" - false = do not update the plugin"
|
||||
})
|
||||
public String UPDATE = "confirm";
|
||||
@Comment("Send anonymous usage statistics")
|
||||
public boolean METRICS = true;
|
||||
@Comment("FAWE will skip chunks when there's not enough memory available")
|
||||
public boolean PREVENT_CRASHES = false;
|
||||
@Comment({
|
||||
"Set true to enable WorldEdit restrictions per region (e.g. PlotSquared or WorldGuard).",
|
||||
"To be allowed to WorldEdit in a region, users need the appropriate",
|
||||
"fawe.<plugin> permission. See the Permissions page for supported region plugins."
|
||||
})
|
||||
public boolean REGION_RESTRICTIONS = true;
|
||||
@Comment("FAWE will skip chunks when there's not enough memory available")
|
||||
public boolean PREVENT_CRASHES = false;
|
||||
@Comment({
|
||||
"FAWE will cancel non admin edits when memory consumption exceeds this %",
|
||||
" - Bypass with `/wea` or `//fast` or `fawe.bypass`",
|
||||
@ -65,19 +67,38 @@ public class Settings extends Config {
|
||||
public HISTORY HISTORY;
|
||||
@Create
|
||||
public PATHS PATHS;
|
||||
@Create
|
||||
public TAB_COMPLETION TAB_COMPLETION;
|
||||
@Create
|
||||
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
|
||||
|
||||
@Comment("Paths for various directories")
|
||||
public static final class PATHS {
|
||||
public String TOKENS = "tokens";
|
||||
@Comment({
|
||||
"Put any minecraft or mod jars for FAWE to be aware of block textures",
|
||||
})
|
||||
public String TEXTURES = "textures";
|
||||
public String HEIGHTMAP = "heightmap";
|
||||
public String HISTORY = "history";
|
||||
@Comment("Multiple servers can use the same clipboards")
|
||||
@Comment({
|
||||
"Multiple servers can use the same clipboards",
|
||||
" - Use a shared directory or NFS/Samba"
|
||||
})
|
||||
public String CLIPBOARD = "clipboard";
|
||||
@Comment("Each player has their own sub directory for schematics")
|
||||
public boolean PER_PLAYER_SCHEMATICS = true;
|
||||
public String COMMANDS = "commands";
|
||||
}
|
||||
|
||||
@Comment("Region restriction settings")
|
||||
public static final class REGION_RESTRICTIONS_OPTIONS {
|
||||
@Comment({
|
||||
"What type of users are allowed to WorldEdit in a region",
|
||||
" - MEMBER = Players added to a region",
|
||||
" - OWNER = Players who own the region"
|
||||
})
|
||||
public String MODE = "MEMBER";
|
||||
}
|
||||
|
||||
|
||||
@ -140,6 +161,17 @@ public class Settings extends Config {
|
||||
"Should large edits require confirmation (>16384 chunks)",
|
||||
})
|
||||
public boolean CONFIRM_LARGE = true;
|
||||
@Comment({
|
||||
"List of blocks to strip nbt from",
|
||||
})
|
||||
public List<String> STRIP_NBT = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static class TAB_COMPLETION {
|
||||
@Comment({"Entirely disabled tab completion to completely avoid exploits"})
|
||||
public boolean ENABLED = true;
|
||||
@Comment({"Max time tab-completes can attempt to operate for until being cancelled (ms)"})
|
||||
public int MAX_TIME = 100;
|
||||
}
|
||||
|
||||
public static class HISTORY {
|
||||
@ -303,11 +335,11 @@ public class Settings extends Config {
|
||||
@Comment({
|
||||
"[SAFE] Dynamically increase the number of chunks rendered",
|
||||
" - Requires Paper: ci.destroystokyo.com/job/PaperSpigot/",
|
||||
" - Set your server view distance to 1 (spigot.yml, server.properties)",
|
||||
" - Set your server view distance to 3 (spigot.yml, server.properties)",
|
||||
" - Based on tps and player movement",
|
||||
" - Please provide feedback",
|
||||
})
|
||||
public boolean DYNAMIC_CHUNK_RENDERING = false;
|
||||
public int DYNAMIC_CHUNK_RENDERING = -1;
|
||||
@Comment({
|
||||
"[SAFE] Allows brushes to be persistent",
|
||||
})
|
||||
@ -317,22 +349,51 @@ public class Settings extends Config {
|
||||
})
|
||||
public boolean VANILLA_CUI = false;
|
||||
|
||||
|
||||
@Comment({
|
||||
"Disable using native libraries",
|
||||
})
|
||||
public boolean DISABLE_NATIVES = false;
|
||||
|
||||
@Comment({
|
||||
"[SAFE] Keep entities that are positioned in non-air blocks when editing an area",
|
||||
"Might cause client-side FPS lagg in some situations"
|
||||
})
|
||||
public boolean KEEP_ENTITIES_IN_BLOCKS = false;
|
||||
|
||||
@Comment({
|
||||
"[SAFE] Experimental scripting support for Java 9",
|
||||
" - "
|
||||
})
|
||||
public boolean MODERN_CRAFTSCRIPTS = false;
|
||||
|
||||
@Comment({
|
||||
"[SAFE] Experimental freebuild region restrictions",
|
||||
" - PERM: fawe.freebuild",
|
||||
" - PERM: fawe.freebuild.<plugin>"
|
||||
})
|
||||
public boolean FREEBUILD = false;
|
||||
}
|
||||
|
||||
public static class WEB {
|
||||
@Comment({
|
||||
"Should download urls be shortened?",
|
||||
" - Links are less secure as they could be brute forced"
|
||||
})
|
||||
public boolean SHORTEN_URLS = false;
|
||||
@Comment({
|
||||
"The web interface for clipboards",
|
||||
" - All schematics are anonymous and private",
|
||||
" - Downloads can be deleted by the user",
|
||||
" - Supports clipboard uploads, downloads and saves",
|
||||
})
|
||||
public String URL = "http://empcraft.com/fawe/";
|
||||
public String URL = "https://empcraft.com/fawe/";
|
||||
@Comment({
|
||||
"The web interface for assets",
|
||||
" - All schematics are organized and public",
|
||||
" - Assets can be searched, selected and downloaded",
|
||||
})
|
||||
public String ASSETS = "http://empcraft.com/assetpack/";
|
||||
public String ASSETS = "https://empcraft.com/assetpack/";
|
||||
}
|
||||
|
||||
public static class EXTENT {
|
||||
@ -353,10 +414,16 @@ public class Settings extends Config {
|
||||
public int INTERVAL = 20;
|
||||
@Comment("Max falling blocks per interval (per chunk)")
|
||||
public int FALLING = 64;
|
||||
@Comment("Max physics per interval (per chunk)")
|
||||
public int PHYSICS = 8192;
|
||||
@Comment("Max physics per interval (excluding redstone)")
|
||||
public int PHYSICS_MS = 10;
|
||||
@Comment("Max item spawns per interval (per chunk)")
|
||||
public int ITEMS = 256;
|
||||
@Comment({
|
||||
"Whether fireworks can load chunks",
|
||||
" - Fireworks usually travel vertically so do not load any chunks",
|
||||
" - Horizontal fireworks can be hacked in to crash a server"
|
||||
})
|
||||
public boolean FIREWORKS_LOAD_CHUNKS = false;
|
||||
}
|
||||
|
||||
public static class CLIPBOARD {
|
||||
@ -388,9 +455,11 @@ public class Settings extends Config {
|
||||
"The relighting mode to use:",
|
||||
" - 0 = None (Do no relighting)",
|
||||
" - 1 = Optimal (Relight changed light sources and changed blocks)",
|
||||
" - 2 = All (Slowly relight every blocks)"
|
||||
" - 2 = All (Slowly relight every blocks)",
|
||||
})
|
||||
public int MODE = 1;
|
||||
@Comment({"If existing lighting should be removed before relighting"})
|
||||
public boolean REMOVE_FIRST = false;
|
||||
}
|
||||
|
||||
public void reload(File file) {
|
||||
@ -400,14 +469,18 @@ public class Settings extends Config {
|
||||
|
||||
public FaweLimit getLimit(FawePlayer player) {
|
||||
FaweLimit limit;
|
||||
if (player.hasWorldEditBypass()) {
|
||||
if (player.hasPermission("fawe.limit.*") || player.hasPermission("fawe.bypass")) {
|
||||
limit = FaweLimit.MAX.copy();
|
||||
} else {
|
||||
limit = new FaweLimit();
|
||||
}
|
||||
Collection<String> keys = LIMITS.getSections();
|
||||
ArrayList<String> keys = new ArrayList<>(LIMITS.getSections());
|
||||
if (keys.remove("default")) keys.add("default");
|
||||
|
||||
boolean limitFound = false;
|
||||
for (String key : keys) {
|
||||
if (key.equals("default") || (player != null && player.hasPermission("fawe.limit." + key))) {
|
||||
if ((player != null && player.hasPermission("fawe.limit." + key)) || (!limitFound && key.equals("default"))) {
|
||||
limitFound = true;
|
||||
LIMITS newLimit = LIMITS.get(key);
|
||||
limit.MAX_ACTIONS = Math.max(limit.MAX_ACTIONS, newLimit.MAX_ACTIONS != -1 ? newLimit.MAX_ACTIONS : Integer.MAX_VALUE);
|
||||
limit.MAX_CHANGES = Math.max(limit.MAX_CHANGES, newLimit.MAX_CHANGES != -1 ? newLimit.MAX_CHANGES : Integer.MAX_VALUE);
|
||||
@ -422,8 +495,16 @@ public class Settings extends Config {
|
||||
limit.SPEED_REDUCTION = Math.min(limit.SPEED_REDUCTION, newLimit.SPEED_REDUCTION);
|
||||
limit.FAST_PLACEMENT |= newLimit.FAST_PLACEMENT;
|
||||
limit.CONFIRM_LARGE &= newLimit.CONFIRM_LARGE;
|
||||
if (limit.STRIP_NBT == null) limit.STRIP_NBT = newLimit.STRIP_NBT.isEmpty() ? Collections.emptySet() : new HashSet<>(newLimit.STRIP_NBT);
|
||||
else if (limit.STRIP_NBT.isEmpty() || newLimit.STRIP_NBT.isEmpty()) {
|
||||
limit.STRIP_NBT = Collections.emptySet();
|
||||
} else {
|
||||
limit.STRIP_NBT = new HashSet<>(limit.STRIP_NBT);
|
||||
limit.STRIP_NBT.retainAll(newLimit.STRIP_NBT);
|
||||
if (limit.STRIP_NBT.isEmpty()) limit.STRIP_NBT = Collections.emptySet();
|
||||
}
|
||||
}
|
||||
}
|
||||
return limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.object.task.AsyncNotifyQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@ -22,7 +23,7 @@ import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RollbackDatabase {
|
||||
public class RollbackDatabase extends AsyncNotifyQueue {
|
||||
|
||||
private final String prefix;
|
||||
private final File dbLocation;
|
||||
@ -35,12 +36,14 @@ public class RollbackDatabase {
|
||||
// private String GET_EDITS_POINT;
|
||||
private String GET_EDITS;
|
||||
private String GET_EDITS_USER;
|
||||
private String GET_EDITS_ASC;
|
||||
private String GET_EDITS_USER_ASC;
|
||||
private String DELETE_EDITS_USER;
|
||||
private String DELETE_EDIT_USER;
|
||||
private String PURGE;
|
||||
|
||||
private ConcurrentLinkedQueue<RollbackOptimizedHistory> historyChanges = new ConcurrentLinkedQueue<>();
|
||||
private ConcurrentLinkedQueue<Runnable> notify = new ConcurrentLinkedQueue<>();
|
||||
private final ConcurrentLinkedQueue<Runnable> tasks = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public RollbackDatabase(String world) throws SQLException, ClassNotFoundException {
|
||||
this(FaweAPI.getWorld(world));
|
||||
@ -58,32 +61,30 @@ public class RollbackDatabase {
|
||||
// GET_EDITS_POINT = "SELECT `player`,`id` FROM `" + prefix + "edits` WHERE `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=?";
|
||||
GET_EDITS = "SELECT `player`,`id` FROM `" + prefix + "edits` WHERE `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=? AND `time`>? ORDER BY `time` DESC, `id` DESC";
|
||||
GET_EDITS_USER = "SELECT `player`,`id` FROM `" + prefix + "edits` WHERE `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=? AND `time`>? AND `player`=? ORDER BY `time` DESC, `id` DESC";
|
||||
GET_EDITS_ASC = "SELECT `player`,`id` FROM `" + prefix + "edits` WHERE `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=? AND `time`>? ORDER BY `time` ASC, `id` ASC";
|
||||
GET_EDITS_USER_ASC = "SELECT `player`,`id` FROM `" + prefix + "edits` WHERE `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=? AND `time`>? AND `player`=? ORDER BY `time` ASC, `id` ASC";
|
||||
DELETE_EDITS_USER = "DELETE FROM `" + prefix + "edits` WHERE `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=? AND `time`>? AND `player`=?";
|
||||
DELETE_EDIT_USER = "DELETE FROM `" + prefix + "edits` WHERE `player`=? AND `id`=?";
|
||||
init();
|
||||
purge((int) TimeUnit.DAYS.toMillis(Settings.IMP.HISTORY.DELETE_AFTER_DAYS));
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long last = System.currentTimeMillis();
|
||||
while (true) {
|
||||
if (connection == null) {
|
||||
break;
|
||||
}
|
||||
if (!RollbackDatabase.this.sendBatch()) {
|
||||
try {
|
||||
while (!notify.isEmpty()) {
|
||||
Runnable runnable = notify.poll();
|
||||
runnable.run();
|
||||
}
|
||||
Thread.sleep(50);
|
||||
} catch (final InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasQueued() {
|
||||
return connection != null && (!historyChanges.isEmpty() || !tasks.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate() {
|
||||
synchronized (this) {
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
while (sendBatch()) {
|
||||
// Still processing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
@ -94,10 +95,6 @@ public class RollbackDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public void addFinishTask(Runnable run) {
|
||||
notify.add(run);
|
||||
}
|
||||
|
||||
public void delete(final UUID uuid, final int id) {
|
||||
addTask(new Runnable() {
|
||||
@Override
|
||||
@ -129,12 +126,13 @@ public class RollbackDatabase {
|
||||
});
|
||||
}
|
||||
|
||||
public void getPotentialEdits(final UUID uuid, final long minTime, final Vector pos1, final Vector pos2, final RunnableVal<DiskStorageHistory> onEach, final Runnable whenDone, final boolean delete) {
|
||||
public void getPotentialEdits(final UUID uuid, final long minTime, final Vector pos1, final Vector pos2, final RunnableVal<DiskStorageHistory> onEach, final Runnable whenDone, final boolean delete, final boolean ascending) {
|
||||
final World world = FaweAPI.getWorld(this.worldName);
|
||||
addTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try (PreparedStatement stmt = connection.prepareStatement(uuid == null ? GET_EDITS : GET_EDITS_USER)) {
|
||||
String stmtStr = ascending ? (uuid == null ? GET_EDITS_ASC : GET_EDITS_USER_ASC) : (uuid == null ? GET_EDITS : GET_EDITS_USER);
|
||||
try (PreparedStatement stmt = connection.prepareStatement(stmtStr)) {
|
||||
stmt.setInt(1, pos1.getBlockX());
|
||||
stmt.setInt(2, pos2.getBlockX());
|
||||
stmt.setByte(3, (byte) (pos1.getBlockY() - 128));
|
||||
@ -186,16 +184,14 @@ public class RollbackDatabase {
|
||||
}
|
||||
|
||||
public void logEdit(RollbackOptimizedHistory history) {
|
||||
historyChanges.add(history);
|
||||
queue(() -> historyChanges.add(history));
|
||||
}
|
||||
|
||||
private final ConcurrentLinkedQueue<Runnable> tasks = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public void addTask(Runnable run) {
|
||||
this.tasks.add(run);
|
||||
queue(() -> tasks.add(run));
|
||||
}
|
||||
|
||||
public void runTasks() {
|
||||
private void runTasks() {
|
||||
Runnable task;
|
||||
while ((task = tasks.poll()) != null) {
|
||||
try {
|
||||
@ -321,9 +317,14 @@ public class RollbackDatabase {
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
connection.close();
|
||||
connection = null;
|
||||
return true;
|
||||
synchronized (this) {
|
||||
if (connection == null) {
|
||||
return false;
|
||||
}
|
||||
connection.close();
|
||||
connection = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,11 +5,8 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T> {
|
||||
|
||||
@ -170,7 +167,7 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return entities == null ? new HashSet<CompoundTag>() : entities;
|
||||
return entities == null ? Collections.emptySet() : entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -294,7 +291,6 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 60:
|
||||
case 7:
|
||||
case 73:
|
||||
case 79:
|
||||
@ -319,8 +315,6 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
@ -334,6 +328,9 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
case 10:
|
||||
case 54:
|
||||
case 146:
|
||||
case 137:
|
||||
case 188:
|
||||
case 189:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68: // removed
|
||||
@ -350,10 +347,11 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(final int x, final int z, final byte biome) {
|
||||
public void setBiome(final int x, final int z, byte biome) {
|
||||
if (this.biomes == null) {
|
||||
this.biomes = new byte[256];
|
||||
}
|
||||
if (biome == 0) biome = -1;
|
||||
biomes[((z & 15) << 4) + (x & 15)] = biome;
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,9 @@ import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -72,13 +71,13 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> impl
|
||||
|
||||
public MappedFaweQueue(final String world) {
|
||||
this.world = world;
|
||||
map = Settings.IMP.PREVENT_CRASHES ? new WeakFaweQueueMap(this) : new DefaultFaweQueueMap(this);
|
||||
map = getSettings().PREVENT_CRASHES ? new WeakFaweQueueMap(this) : new DefaultFaweQueueMap(this);
|
||||
}
|
||||
|
||||
public MappedFaweQueue(final String world, IFaweQueueMap map) {
|
||||
this.world = world;
|
||||
if (map == null) {
|
||||
map = Settings.IMP.PREVENT_CRASHES ? new WeakFaweQueueMap(this) : new DefaultFaweQueueMap(this);
|
||||
map = getSettings().PREVENT_CRASHES ? new WeakFaweQueueMap(this) : new DefaultFaweQueueMap(this);
|
||||
}
|
||||
this.map = map;
|
||||
}
|
||||
@ -87,7 +86,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> impl
|
||||
this.weWorld = world;
|
||||
if (world != null) this.world = Fawe.imp().getWorldName(world);
|
||||
if (map == null) {
|
||||
map = Settings.IMP.PREVENT_CRASHES ? new WeakFaweQueueMap(this) : new DefaultFaweQueueMap(this);
|
||||
map = getSettings().PREVENT_CRASHES ? new WeakFaweQueueMap(this) : new DefaultFaweQueueMap(this);
|
||||
}
|
||||
this.map = map;
|
||||
}
|
||||
@ -409,14 +408,14 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> impl
|
||||
if (chunk != null) {
|
||||
return chunk;
|
||||
}
|
||||
boolean sync = Thread.currentThread() == Fawe.get().getMainThread();
|
||||
boolean sync = Fawe.isMainThread();
|
||||
if (sync) {
|
||||
return loadChunk(getWorld(), cx, cz, true);
|
||||
} else if (Settings.IMP.HISTORY.CHUNK_WAIT_MS > 0) {
|
||||
} else if (getSettings().HISTORY.CHUNK_WAIT_MS > 0) {
|
||||
cachedLoadChunk = null;
|
||||
loadChunk.value.x = cx;
|
||||
loadChunk.value.z = cz;
|
||||
TaskManager.IMP.syncWhenFree(loadChunk, Settings.IMP.HISTORY.CHUNK_WAIT_MS);
|
||||
TaskManager.IMP.syncWhenFree(loadChunk, getSettings().HISTORY.CHUNK_WAIT_MS);
|
||||
return cachedLoadChunk;
|
||||
} else {
|
||||
return null;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.boydti.fawe.example;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
@ -42,13 +41,17 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getRelighter().fixLightingSafe(hasSky());
|
||||
if (getSettings().IMP.LIGHTING.REMOVE_FIRST) {
|
||||
getRelighter().removeAndRelight(hasSky());
|
||||
} else {
|
||||
getRelighter().fixLightingSafe(hasSky());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private final Relighter relighter = Settings.IMP.LIGHTING.MODE > 0 ? new NMSRelighter(this) : NullRelighter.INSTANCE;
|
||||
private final Relighter relighter = getSettings().IMP.LIGHTING.MODE > 0 ? new NMSRelighter(this) : NullRelighter.INSTANCE;
|
||||
|
||||
@Override
|
||||
public Relighter getRelighter() {
|
||||
@ -58,14 +61,14 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
@Override
|
||||
public void end(FaweChunk chunk) {
|
||||
super.end(chunk);
|
||||
if (Settings.IMP.LIGHTING.MODE == 0) {
|
||||
if (getSettings().IMP.LIGHTING.MODE == 0) {
|
||||
sendChunk(chunk);
|
||||
return;
|
||||
}
|
||||
if (!Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
if (!getSettings().IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
sendChunk(chunk);
|
||||
}
|
||||
if (Settings.IMP.LIGHTING.MODE == 2) {
|
||||
if (getSettings().IMP.LIGHTING.MODE == 2) {
|
||||
getRelighter().addChunk(chunk.getX(), chunk.getZ(), null, chunk.getBitMask());
|
||||
return;
|
||||
}
|
||||
@ -91,7 +94,7 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
}
|
||||
if (relight) {
|
||||
getRelighter().addChunk(chunk.getX(), chunk.getZ(), fix, chunk.getBitMask());
|
||||
} else if (Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
} else if (getSettings().IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
sendChunk(chunk);
|
||||
}
|
||||
}
|
||||
@ -109,7 +112,18 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
|
||||
public abstract void setFullbright(CHUNKSECTION sections);
|
||||
|
||||
public abstract boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky);
|
||||
public boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky) {
|
||||
boolean result = false;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
SECTION section = getCachedSection(sections, i);
|
||||
if (section != null) {
|
||||
result |= removeSectionLighting(section, i, hasSky);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract boolean removeSectionLighting(SECTION sections, int layer, boolean hasSky);
|
||||
|
||||
public boolean isSurrounded(final char[][] sections, final int x, final int y, final int z) {
|
||||
return this.isSolid(this.getId(sections, x, y + 1, z))
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.IntegerTrio;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
@ -40,6 +41,7 @@ public class NMSRelighter implements Relighter {
|
||||
public final IntegerTrio mutableBlockPos = new IntegerTrio();
|
||||
|
||||
private static final int DISPATCH_SIZE = 64;
|
||||
private boolean removeFirst;
|
||||
|
||||
public NMSRelighter(NMSMappedFaweQueue queue) {
|
||||
this.queue = queue;
|
||||
@ -55,6 +57,13 @@ public class NMSRelighter implements Relighter {
|
||||
return skyToRelight.isEmpty() && lightQueue.isEmpty() && queuedSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeAndRelight(boolean sky) {
|
||||
removeFirst = true;
|
||||
fixLightingSafe(sky);
|
||||
removeFirst = false;
|
||||
}
|
||||
|
||||
private void set(int x, int y, int z, long[][][] map) {
|
||||
long[][] m1 = map[z];
|
||||
if (m1 == null) {
|
||||
@ -92,6 +101,14 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void clear() {
|
||||
queuedSkyToRelight.clear();
|
||||
skyToRelight.clear();
|
||||
chunksToSend.clear();
|
||||
lightQueue.clear();
|
||||
concurrentLightQueue.clear();
|
||||
}
|
||||
|
||||
public boolean addChunk(int cx, int cz, byte[] fix, int bitmask) {
|
||||
RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask);
|
||||
queuedSkyToRelight.add(toPut);
|
||||
@ -372,6 +389,23 @@ public class NMSRelighter implements Relighter {
|
||||
|
||||
private void fixSkyLighting(List<RelightSkyEntry> sorted) {
|
||||
RelightSkyEntry[] chunks = sorted.toArray(new RelightSkyEntry[sorted.size()]);
|
||||
boolean remove = this.removeFirst;
|
||||
BlockVectorSet chunkSet = null;
|
||||
if (remove) {
|
||||
chunkSet = new BlockVectorSet();
|
||||
BlockVectorSet tmpSet = new BlockVectorSet();
|
||||
for (RelightSkyEntry chunk : chunks) {
|
||||
tmpSet.add(chunk.x, 0, chunk.z);
|
||||
}
|
||||
for (RelightSkyEntry chunk : chunks) {
|
||||
int x = chunk.x;
|
||||
int z = chunk.z;
|
||||
if (tmpSet.contains(x + 1, 0, z) && tmpSet.contains(x - 1, 0, z) && tmpSet.contains(x, 0, z + 1) && tmpSet.contains(x, 0, z - 1)) {
|
||||
chunkSet.add(x, 0, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] cacheX = FaweCache.CACHE_X[0];
|
||||
byte[] cacheZ = FaweCache.CACHE_Z[0];
|
||||
for (int y = FaweChunk.HEIGHT - 1; y > 0; y--) {
|
||||
@ -392,6 +426,11 @@ public class NMSRelighter implements Relighter {
|
||||
Object section = queue.getCachedSection(sections, layer);
|
||||
if (section == null) continue;
|
||||
chunk.smooth = false;
|
||||
|
||||
if (remove && (y & 15) == 15 && chunkSet.contains(chunk.x, 0, chunk.z)) {
|
||||
queue.removeSectionLighting(section, y >> 4, true);
|
||||
}
|
||||
|
||||
for (int j = 0; j <= maxY; j++) {
|
||||
int x = cacheX[j];
|
||||
int z = cacheZ[j];
|
||||
|
@ -22,6 +22,16 @@ public class NullRelighter implements Relighter {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLighting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixBlockLighting() {
|
||||
|
||||
|
@ -7,6 +7,15 @@ public interface Relighter {
|
||||
|
||||
void fixLightingSafe(boolean sky);
|
||||
|
||||
default void removeAndRelight(boolean sky) {
|
||||
removeLighting();
|
||||
fixLightingSafe(sky);
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
void removeLighting();
|
||||
|
||||
void fixBlockLighting();
|
||||
|
||||
void fixSkyLighting();
|
||||
@ -18,4 +27,4 @@ public interface Relighter {
|
||||
public static final byte AIR = 1;
|
||||
public static final byte SOLID = 2;
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ public class SimpleCharFaweChunk extends CharFaweChunk {
|
||||
copy.biomes = biomes;
|
||||
} else {
|
||||
copy = new SimpleCharFaweChunk(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes.clone();
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.prefs.Preferences;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
|
||||
public abstract class BrowseButton extends InteractiveButton {
|
||||
private final String id;
|
||||
|
||||
public BrowseButton(String id) {
|
||||
super("Browse");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public abstract void onSelect(File folder);
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Preferences prefs = Preferences.userRoot().node(Fawe.class.getName());
|
||||
String lastUsed = prefs.get("LAST_USED_FOLDER", null);
|
||||
final File lastFile = lastUsed == null ? null : new File(lastUsed).getParentFile();
|
||||
browse(lastFile);
|
||||
}
|
||||
|
||||
public void browse(File from) {
|
||||
DirectoryChooser folderChooser = new DirectoryChooser();
|
||||
folderChooser.setInitialDirectory(from);
|
||||
|
||||
new JFXPanel(); // Init JFX Platform
|
||||
Platform.runLater(() -> {
|
||||
File file = folderChooser.showDialog(null);
|
||||
if (file != null && file.exists()) {
|
||||
File parent = file.getParentFile();
|
||||
if (parent == null) parent = file;
|
||||
Preferences.userRoot().node(Fawe.class.getName()).put("LAST_USED_FOLDER" + id, parent.getPath());
|
||||
onSelect(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class CloseButton extends InteractiveButton {
|
||||
public CloseButton() {
|
||||
super("X");
|
||||
setColor(new Color(0x66, 0x33, 0x33));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class ImagePanel extends JPanel {
|
||||
|
||||
private BufferedImage image;
|
||||
|
||||
public ImagePanel(BufferedImage image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(
|
||||
RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setComposite(AlphaComposite.getInstance(
|
||||
AlphaComposite.SRC_OVER, 0.6f));
|
||||
g.drawImage(image, 0, 0, getWidth(), getWidth(), this); // see javadoc for more info on the parameters
|
||||
}
|
||||
|
||||
}
|
@ -1,358 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import com.boydti.fawe.FaweVersion;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
public class InstallerFrame extends JFrame {
|
||||
private final InvisiblePanel loggerPanel;
|
||||
private Color LIGHT_GRAY = new Color(0x66, 0x66, 0x66);
|
||||
private Color GRAY = new Color(0x44, 0x44, 0x46);
|
||||
private Color DARK_GRAY = new Color(0x33, 0x33, 0x36);
|
||||
private Color DARKER_GRAY = new Color(0x26, 0x26, 0x28);
|
||||
private Color INVISIBLE = new Color(0, 0, 0, 0);
|
||||
private Color OFF_WHITE = new Color(200, 200, 200);
|
||||
|
||||
private JTextArea loggerTextArea;
|
||||
private BrowseButton browse;
|
||||
|
||||
public InstallerFrame() throws Exception {
|
||||
final MovablePanel movable = new MovablePanel(this);
|
||||
|
||||
Container content = this.getContentPane();
|
||||
content.add(movable);
|
||||
this.setSize(480, 320);
|
||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setUndecorated(true);
|
||||
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (int) ((dimension.getWidth() - this.getWidth()) / 2);
|
||||
int y = (int) ((dimension.getHeight() - this.getHeight()) / 2);
|
||||
this.setLocation(x, y);
|
||||
this.setVisible(true);
|
||||
this.setOpacity(0);
|
||||
movable.setBackground(DARK_GRAY);
|
||||
movable.setLayout(new BorderLayout());
|
||||
|
||||
fadeIn();
|
||||
|
||||
JPanel topBar = new InvisiblePanel(new BorderLayout());
|
||||
{
|
||||
JPanel topBarLeft = new InvisiblePanel();
|
||||
JPanel topBarRight = new InvisiblePanel();
|
||||
|
||||
JLabel title = new JLabel("FastAsyncWorldEdit Installer");
|
||||
title.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
title.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||
title.setForeground(LIGHT_GRAY);
|
||||
|
||||
MinimizeButton minimize = new MinimizeButton(this);
|
||||
CloseButton exit = new CloseButton();
|
||||
|
||||
topBarLeft.add(title);
|
||||
topBarRight.add(minimize);
|
||||
topBarRight.add(exit);
|
||||
|
||||
topBar.add(topBarLeft, BorderLayout.CENTER);
|
||||
topBar.add(topBarRight, BorderLayout.EAST);
|
||||
}
|
||||
final JPanel mainContent = new InvisiblePanel(new BorderLayout());
|
||||
{
|
||||
final JPanel browseContent = new InvisiblePanel(new BorderLayout());
|
||||
File dir = MainUtil.getWorkingDirectory("minecraft");
|
||||
JLabel folder = new JLabel("Folder: ");
|
||||
folder.setForeground(OFF_WHITE);
|
||||
final InteractiveButton text = new InteractiveButton(dir.getPath(), DARKER_GRAY) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browse.actionPerformed(e);
|
||||
}
|
||||
};
|
||||
text.setForeground(OFF_WHITE);
|
||||
text.setBackground(DARKER_GRAY);
|
||||
text.setOpaque(true);
|
||||
text.setBorder(new EmptyBorder(4, 4, 4, 4));
|
||||
browse = new BrowseButton("") {
|
||||
@Override
|
||||
public void onSelect(File folder) {
|
||||
text.setText(folder.getPath());
|
||||
movable.repaint();
|
||||
}
|
||||
};
|
||||
InteractiveButton install = new InteractiveButton(">> Create Profile <<", DARKER_GRAY) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
install(text.getText());
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
browseContent.add(folder, BorderLayout.WEST);
|
||||
browseContent.add(text, BorderLayout.CENTER);
|
||||
browseContent.add(browse, BorderLayout.EAST);
|
||||
final JPanel installContent = new InvisiblePanel(new FlowLayout());
|
||||
install.setPreferredSize(new Dimension(416, 32));
|
||||
installContent.add(install);
|
||||
installContent.setBorder(new EmptyBorder(10, 0, 10, 0));
|
||||
this.loggerPanel = new InvisiblePanel(new BorderLayout());
|
||||
this.loggerPanel.setBackground(Color.GREEN);
|
||||
loggerPanel.setPreferredSize(new Dimension(416, 160));
|
||||
loggerTextArea = new JTextArea(12, 52);
|
||||
loggerTextArea.setBackground(GRAY);
|
||||
loggerTextArea.setForeground(DARKER_GRAY);
|
||||
loggerTextArea.setFont(new Font(loggerTextArea.getFont().getName(), Font.PLAIN, 9));
|
||||
JScrollPane scroll = new JScrollPane(loggerTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
scroll.setBackground(DARK_GRAY);
|
||||
scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
loggerPanel.add(scroll);
|
||||
loggerPanel.setVisible(false);
|
||||
|
||||
mainContent.setBorder(new EmptyBorder(6, 32, 6, 32));
|
||||
mainContent.add(browseContent, BorderLayout.NORTH);
|
||||
mainContent.add(installContent, BorderLayout.CENTER);
|
||||
mainContent.add(loggerPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
JPanel bottomBar = new InvisiblePanel();
|
||||
{
|
||||
try {
|
||||
InputStream stream = getClass().getResourceAsStream("/fawe.properties");
|
||||
java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
|
||||
String versionString = scanner.next().trim();
|
||||
scanner.close();
|
||||
FaweVersion version = new FaweVersion(versionString);
|
||||
String date = new Date(100 + version.year, version.month, version.day).toGMTString();
|
||||
String build = "https://ci.athion.net/job/FastAsyncWorldEdit/" + version.build;
|
||||
String commit = "https://github.com/boy0001/FastAsyncWorldedit/commit/" + Integer.toHexString(version.hash);
|
||||
String footerMessage = "FAWE v" + version.major + "." + version.minor + "." + version.patch + " by Empire92 (c) 2017 (GPL v3.0)";
|
||||
URL licenseUrl = new URL("https://github.com/boy0001/FastAsyncWorldedit/blob/master/LICENSE");
|
||||
URLButton licenseButton = new URLButton(licenseUrl, footerMessage);
|
||||
bottomBar.add(licenseButton);
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
URL chat = new URL("http://webchat.esper.net/?nick=&channels=IntellectualCrafters&fg_color=000&fg_sec_color=000&bg_color=FFF");
|
||||
URLButton chatButton = new URLButton(chat, "Chat");
|
||||
bottomBar.add(chatButton);
|
||||
URL wiki = new URL("https://github.com/boy0001/FastAsyncWorldedit/wiki");
|
||||
URLButton wikiButton = new URLButton(wiki, "Wiki");
|
||||
bottomBar.add(wikiButton);
|
||||
URL issue = new URL("https://github.com/boy0001/FastAsyncWorldedit/issues/new");
|
||||
URLButton issueButton = new URLButton(issue, "Report Issue");
|
||||
bottomBar.add(issueButton);
|
||||
}
|
||||
|
||||
// We want to add these a bit later
|
||||
movable.add(topBar, BorderLayout.NORTH);
|
||||
this.setVisible(true);
|
||||
this.repaint();
|
||||
movable.add(mainContent, BorderLayout.CENTER);
|
||||
this.setVisible(true);
|
||||
this.repaint();
|
||||
movable.add(bottomBar, BorderLayout.SOUTH);
|
||||
this.setVisible(true);
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
private boolean newLine = false;
|
||||
|
||||
public void prompt(String message) {
|
||||
JOptionPane.showMessageDialog(null, message);
|
||||
}
|
||||
|
||||
public void debug(String m) {
|
||||
System.out.println(m);
|
||||
}
|
||||
|
||||
public void install(String name) throws Exception {
|
||||
if (!loggerPanel.isVisible()) {
|
||||
loggerPanel.setVisible(true);
|
||||
this.repaint();
|
||||
System.setOut(new TextAreaOutputStream(loggerTextArea));
|
||||
}
|
||||
if (name == null || name.isEmpty()) {
|
||||
prompt("No folder selection");
|
||||
return;
|
||||
}
|
||||
final File dirMc = new File(name);
|
||||
if (!dirMc.exists()) {
|
||||
prompt("Folder does not exist");
|
||||
return;
|
||||
}
|
||||
if (!dirMc.isDirectory()) {
|
||||
prompt("You must select a folder, not a file");
|
||||
return;
|
||||
}
|
||||
Thread installThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<String> supported = Arrays.asList("v1710", "v189", "v194", "v110", "v111");
|
||||
String supportedString = null;
|
||||
for (String version : supported) {
|
||||
try {
|
||||
Class.forName("com.boydti.fawe.forge." + version + ".ForgeChunk_All");
|
||||
supportedString = version;
|
||||
break;
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
if (supportedString == null) {
|
||||
prompt("This version of FAWE cannot be installed this way.");
|
||||
return;
|
||||
}
|
||||
debug("Selected version " + supportedString);
|
||||
URL forgeUrl;
|
||||
URL worldEditUrl;
|
||||
URL worldEditCuiUrl;
|
||||
try {
|
||||
switch (supportedString) {
|
||||
case "v111":
|
||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.11.2-13.20.0.2201/forge-1.11.2-13.20.0.2201-installer.jar");
|
||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9593/download/worldedit-forge-mc1.11-6.1.6-SNAPSHOT-dist.jar");
|
||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/241/worldeditcuife-v1.0.6-mf-1.11.2-13.20.0.2201.jar");
|
||||
break;
|
||||
case "v110":
|
||||
forgeUrl = new URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.10.2-12.18.3.2185/forge-1.10.2-12.18.3.2185-installer.jar");
|
||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9395/download/worldedit-forge-mc1.10.2-6.1.4-SNAPSHOT-dist.jar");
|
||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/239/WorldEditCuiFe-v1.0.6-mf-1.10.2-12.18.2.2125.jar");
|
||||
break;
|
||||
case "v194":
|
||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.9.4-12.17.0.2051/forge-1.9.4-12.17.0.2051-installer.jar");
|
||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9171/download/worldedit-forge-mc1.9.4-6.1.3-SNAPSHOT-dist.jar");
|
||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/236/WorldEditCuiFe-v1.0.6-mf-1.9.4-12.17.0.1976.jar");
|
||||
break;
|
||||
case "v189":
|
||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.8.9-11.15.1.1902-1.8.9/forge-1.8.9-11.15.1.1902-1.8.9-installer.jar");
|
||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/8755/download/worldedit-forge-mc1.8.9-6.1.1-dist.jar");
|
||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/235/WorldEditCuiFe-v1.0.6-mf-1.8.9-11.15.1.1855.jar");
|
||||
break;
|
||||
case "v1710":
|
||||
forgeUrl = new URL("https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.4.1614-1.7.10/forge-1.7.10-10.13.4.1614-1.7.10-installer.jar");
|
||||
worldEditUrl = new URL("http://builds.enginehub.org/job/worldedit/9194/download/worldedit-forge-mc1.7.10-6.1.2-SNAPSHOT-dist.jar");
|
||||
worldEditCuiUrl = new URL("https://addons-origin.cursecdn.com/files/2361/234/WorldEditCuiFe-v1.0.6-mf-1.7.10-10.13.4.1566.jar");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
try { // install forge
|
||||
debug("Downloading forge installer from:\n - https://files.minecraftforge.net/");
|
||||
URLClassLoader loader = new URLClassLoader(new URL[]{forgeUrl});
|
||||
debug("Connected");
|
||||
Class<?> forgeInstallClass = loader.loadClass("net.minecraftforge.installer.ClientInstall");
|
||||
debug("Found ClientInstall class");
|
||||
Object forgeInstallInstance = forgeInstallClass.newInstance();
|
||||
debug(forgeInstallInstance + " | " + forgeInstallClass + " | " + StringMan.getString(forgeInstallClass.getMethods()));
|
||||
debug("Created instance " + forgeInstallInstance);
|
||||
Method methodRun = forgeInstallClass.getDeclaredMethods()[0];//("run", File.class, Predicate.class);
|
||||
Object alwaysTrue = loader.loadClass("com.google.common.base.Predicates").getDeclaredMethod("alwaysTrue").invoke(null);
|
||||
methodRun.invoke(forgeInstallInstance, dirMc, alwaysTrue);
|
||||
debug("Forge profile created, now installing WorldEdit");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
prompt("[ERROR] Forge install failed, download from:\nhttps://files.minecraftforge.net/");
|
||||
}
|
||||
File mods = new File(dirMc, "mods");
|
||||
if (!mods.exists()) {
|
||||
debug("Creating mods directory");
|
||||
mods.mkdirs();
|
||||
} else {
|
||||
for (File file : mods.listFiles()) {
|
||||
String name = file.getName().toLowerCase();
|
||||
if ((name.contains("worldedit") || name.contains("fawe"))) {
|
||||
debug("Delete existing: " + file.getName());
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
try { // install worldedit
|
||||
debug("Downloading WE-CUI from:\n - https://minecraft.curseforge.com/projects/worldeditcui-forge-edition");
|
||||
try (ReadableByteChannel rbc = Channels.newChannel(worldEditCuiUrl.openStream())) {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEditCUI.jar"))) {
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
debug("Successfully downloaded WorldEdit-CUI");
|
||||
} catch (Throwable e) {
|
||||
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
|
||||
}
|
||||
try { // install worldedit
|
||||
debug("Downloading WorldEdit from:\n - http://builds.enginehub.org/job/worldedit");
|
||||
try (ReadableByteChannel rbc = Channels.newChannel(worldEditUrl.openStream())) {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(mods, "WorldEdit.jar"))) {
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
|
||||
}
|
||||
}
|
||||
debug("Successfully downloaded WorldEdit");
|
||||
} catch (Throwable e) {
|
||||
prompt("[ERROR] WorldEdit install failed, download from:\nhttp://builds.enginehub.org/job/worldedit");
|
||||
}
|
||||
try { // install FAWE
|
||||
debug("Copying FastAsyncWorldEdit to mods directory");
|
||||
File file = new File(InstallerFrame.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
||||
debug(" - " + file.getPath());
|
||||
MainUtil.copyFile(file, new File(mods, "FastAsyncWorldEdit.jar"));
|
||||
debug("Installation complete!");
|
||||
} catch (Throwable e) {
|
||||
prompt("[ERROR] Copy installer failed, please copy this installer jar manually");
|
||||
}
|
||||
prompt("Installation complete!\nLaunch the game using the forge profile.");
|
||||
}
|
||||
});
|
||||
installThread.start();
|
||||
}
|
||||
|
||||
public void fadeIn() {
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (float i = 0; i <= 1; i += 0.001) {
|
||||
InstallerFrame.this.setOpacity(i);
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
InstallerFrame window = new InstallerFrame();
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import javax.swing.JButton;
|
||||
|
||||
public class InteractiveButton extends JButton implements ActionListener, MouseListener {
|
||||
private Color background;
|
||||
|
||||
public InteractiveButton(String text) {
|
||||
this(text, new Color(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
public InteractiveButton(String text, Color background) {
|
||||
setText(text);
|
||||
setBorderPainted(false);
|
||||
setVisible(true);
|
||||
setForeground(new Color(200, 200, 200));
|
||||
addActionListener(this);
|
||||
addMouseListener(this);
|
||||
setFocusable(false);
|
||||
if (background.getAlpha() != 0) {
|
||||
this.background = background;
|
||||
} else {
|
||||
this.background = new Color(0x38, 0x38, 0x39);
|
||||
}
|
||||
setBackground(this.background);
|
||||
}
|
||||
|
||||
public void setColor(Color background) {
|
||||
setBackground(background);
|
||||
this.background = background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
setBackground(new Color(0x44, 0x44, 0x44));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
setBackground(this.background);
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
setBackground(new Color(0x77, 0x77, 0x77));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
setBackground(new Color(0x33, 0x33, 0x36));
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.LayoutManager;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class InvisiblePanel extends JPanel {
|
||||
public InvisiblePanel(LayoutManager layout) {
|
||||
super(layout);
|
||||
setBackground(new Color(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
public InvisiblePanel() {
|
||||
this(new FlowLayout());
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import sun.swing.FilePane;
|
||||
|
||||
public class JSystemFileChooser extends JFileChooser {
|
||||
public void updateUI(){
|
||||
LookAndFeel old = UIManager.getLookAndFeel();
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
old = null;
|
||||
}
|
||||
|
||||
super.updateUI();
|
||||
|
||||
if(old != null){
|
||||
FilePane filePane = findFilePane(this);
|
||||
filePane.setViewType(FilePane.VIEWTYPE_DETAILS);
|
||||
filePane.setViewType(FilePane.VIEWTYPE_LIST);
|
||||
|
||||
Color background = UIManager.getColor("Label.background");
|
||||
setBackground(background);
|
||||
setOpaque(true);
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(old);
|
||||
}
|
||||
catch (UnsupportedLookAndFeelException ignored) {} // shouldn't get here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static FilePane findFilePane(Container parent){
|
||||
for(Component comp: parent.getComponents()){
|
||||
if(FilePane.class.isInstance(comp)){
|
||||
return (FilePane)comp;
|
||||
}
|
||||
if(comp instanceof Container){
|
||||
Container cont = (Container)comp;
|
||||
if(cont.getComponentCount() > 0){
|
||||
FilePane found = findFilePane(cont);
|
||||
if (found != null) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
public class MinimizeButton extends InteractiveButton {
|
||||
private final JFrame window;
|
||||
|
||||
public MinimizeButton(JFrame window) {
|
||||
super("-");
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
window.setState(Frame.ICONIFIED);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class MovablePanel extends JPanel {
|
||||
private Point initialClick;
|
||||
private JFrame parent;
|
||||
|
||||
public MovablePanel(final JFrame parent) {
|
||||
this.parent = parent;
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
public void mousePressed(MouseEvent e) {
|
||||
initialClick = e.getPoint();
|
||||
getComponentAt(initialClick);
|
||||
}
|
||||
});
|
||||
|
||||
addMouseMotionListener(new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
|
||||
// get location of Window
|
||||
int thisX = parent.getLocation().x;
|
||||
int thisY = parent.getLocation().y;
|
||||
|
||||
// Determine how much the mouse moved since the initial click
|
||||
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
|
||||
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
|
||||
|
||||
// Move window to this position
|
||||
int X = thisX + xMoved;
|
||||
int Y = thisY + yMoved;
|
||||
parent.setLocation(X, Y);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
public class TextAreaOutputStream extends PrintStream {
|
||||
|
||||
public TextAreaOutputStream(final JTextArea textArea) {
|
||||
super(new OutputStream() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
AtomicBoolean updated = new AtomicBoolean();
|
||||
AtomicBoolean waiting = new AtomicBoolean();
|
||||
boolean lineColor = false;
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
buffer.append((char) b);
|
||||
if (b == '\n') {
|
||||
updated.set(true);
|
||||
if (waiting.compareAndSet(false, true)) {
|
||||
executor.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
updated.set(false);
|
||||
int len = buffer.length();
|
||||
textArea.append(BBC.stripColor(buffer.substring(0, len)));
|
||||
buffer.delete(0, len);
|
||||
textArea.setVisible(true);
|
||||
textArea.repaint();
|
||||
} finally {
|
||||
waiting.set(false);
|
||||
if (updated.get() && waiting.compareAndSet(false, true)) {
|
||||
executor.submit(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
updated.lazySet(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.boydti.fawe.installer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Font;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
public class URLButton extends InteractiveButton {
|
||||
private final URL url;
|
||||
|
||||
public URLButton(URL url, String text) {
|
||||
super("<HTML>" + text + "</HTML>");
|
||||
this.url = url;
|
||||
setFont(new Font(getFont().getName(), Font.PLAIN, 9));
|
||||
setForeground(new Color(0x77, 0x77, 0x77));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(url.toURI());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
|
||||
Clipboard systemClipboard = defaultToolkit.getSystemClipboard();
|
||||
systemClipboard.setContents(new StringSelection(url.toString()), null);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.boydti.fawe.jnbt.anvil;
|
||||
|
||||
public class ChunkSimplifier {
|
||||
private final HeightMapMCAGenerator gen;
|
||||
|
||||
public ChunkSimplifier(HeightMapMCAGenerator gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
public void simplify(MCAChunk chunk) {
|
||||
// Copy biome
|
||||
// Calculate water level
|
||||
// Determine floor block
|
||||
// Determine overlay block
|
||||
// determine main block
|
||||
// Copy bedrock
|
||||
// copy anomalies to blocks
|
||||
}
|
||||
}
|
@ -3,41 +3,20 @@ package com.boydti.fawe.jnbt.anvil;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.SimpleCharFaweChunk;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweLocation;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.Metadatable;
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.*;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.change.StreamChange;
|
||||
import com.boydti.fawe.object.changeset.CFIChangeSet;
|
||||
import com.boydti.fawe.object.collection.DifferentialArray;
|
||||
import com.boydti.fawe.object.collection.DifferentialBlockBuffer;
|
||||
import com.boydti.fawe.object.collection.IterableThreadLocal;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVector2DSet;
|
||||
import com.boydti.fawe.object.collection.SummedAreaTable;
|
||||
import com.boydti.fawe.object.collection.*;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.object.queue.LazyFaweChunk;
|
||||
import com.boydti.fawe.object.schematic.Schematic;
|
||||
import com.boydti.fawe.util.CachedTextureUtil;
|
||||
import com.boydti.fawe.util.RandomTextureUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.boydti.fawe.util.image.Drawable;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
@ -51,24 +30,18 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.SimpleWorld;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, FaweQueue, StreamChange, Closeable, Drawable {
|
||||
public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Drawable, VirtualWorld {
|
||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
private final ThreadLocal<int[]> indexStore = new ThreadLocal<int[]>() {
|
||||
@ -91,6 +64,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
public final class CFIPrimtives implements Cloneable {
|
||||
protected int waterHeight = 0;
|
||||
protected int floorThickness = 0;
|
||||
protected int worldThickness = 0;
|
||||
protected boolean randomVariation = true;
|
||||
protected int biomePriority = 0;
|
||||
protected byte waterId = BlockID.STATIONARY_WATER;
|
||||
@ -250,6 +224,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
throw new UnsupportedOperationException("Not supported: Queue is not backed by a real world");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getOrigin() {
|
||||
return new BlockVector(chunkOffset.getBlockX() << 4, 0, chunkOffset.getBlockZ() << 4);
|
||||
}
|
||||
@ -262,7 +237,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
this.player = player;
|
||||
if (player != null) {
|
||||
FaweLocation pos = player.getLocation();
|
||||
this.chunkOffset = new Vector2D(pos.x >> 4, pos.z >> 4);
|
||||
this.chunkOffset = new Vector2D(1 + (pos.x >> 4), 1 + (pos.z >> 4));
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,6 +260,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
return viewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (viewer != null) {
|
||||
viewer.view(this);
|
||||
@ -306,10 +282,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
int pcx = (position.x >> 4) - OX;
|
||||
int pcz = (position.z >> 4) - OZ;
|
||||
|
||||
int scx = Math.max(0, pcx - 10);
|
||||
int scz = Math.max(0, pcz - 10);
|
||||
int ecx = Math.min(lenCX - 1, pcx + 10);
|
||||
int ecz = Math.min(lenCZ - 1, pcz + 10);
|
||||
int scx = Math.max(0, pcx - 15);
|
||||
int scz = Math.max(0, pcz - 15);
|
||||
int ecx = Math.min(lenCX - 1, pcx + 15);
|
||||
int ecz = Math.min(lenCZ - 1, pcz + 15);
|
||||
|
||||
MCAChunk chunk = new MCAChunk(this, 0, 0);
|
||||
for (int cz = scz; cz <= ecz; cz++) {
|
||||
@ -325,9 +301,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// FaweChunk toSend = getSnapshot(chunk, finalCX, finalCZ);
|
||||
// toSend.setLoc(HeightMapMCAGenerator.this, finalCX + OX, finalCZ + OZ);
|
||||
// packetQueue.sendChunkUpdate(toSend, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -366,6 +339,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
this.primtives.floorThickness = floorThickness;
|
||||
}
|
||||
|
||||
public void setWorldThickness(int height) {
|
||||
this.primtives.worldThickness = height;
|
||||
}
|
||||
|
||||
public void setWaterHeight(int waterHeight) {
|
||||
this.primtives.waterHeight = waterHeight;
|
||||
}
|
||||
@ -471,7 +448,27 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
} else {
|
||||
this.heights.setByte(index, (byte) (blockHeight));
|
||||
}
|
||||
}
|
||||
|
||||
private final void setLayerHeightRaw(int index, int height) {
|
||||
int blockHeight = (height) >> 3;
|
||||
int layerHeight = (height) & 0x7;
|
||||
setLayerHeightRaw(index, blockHeight, layerHeight);
|
||||
}
|
||||
|
||||
private final void setLayerHeightRaw(int index, int blockHeight, int layerHeight) {
|
||||
int floorId = floor.get()[index] >> 4;
|
||||
if (floorId == 78 || floorId == 80) {
|
||||
if (layerHeight != 0) {
|
||||
this.heights.getByteArray()[index] = (byte) (blockHeight + 1);
|
||||
this.floor.getCharArray()[index] = (char) (1248 + layerHeight);
|
||||
} else {
|
||||
this.heights.getByteArray()[index] = (byte) (blockHeight);
|
||||
this.floor.getCharArray()[index] = (char) (1280);
|
||||
}
|
||||
} else {
|
||||
this.heights.getByteArray()[index] = (byte) (blockHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,7 +504,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
int height = img.getRGB(x, z) & 0xFF;
|
||||
if (height == 255 || height > 0 && !white && PseudoRandom.random.nextInt(256) <= height) {
|
||||
int newHeight = table.average(x, z, index);
|
||||
setLayerHeight(index, newHeight);
|
||||
setLayerHeightRaw(index, newHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -520,7 +517,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
mutable.mutY(y);
|
||||
if (mask.test(mutable)) {
|
||||
int newHeight = table.average(x, z, index);
|
||||
setLayerHeight(index, newHeight);
|
||||
setLayerHeightRaw(index, newHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -528,7 +525,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
int newHeight = table.average(x, z, index);
|
||||
setLayerHeight(index, newHeight);
|
||||
setLayerHeightRaw(index, newHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -546,13 +543,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
|
||||
public void addCaves() throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1));
|
||||
addCaves(region);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void addSchems(Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1));
|
||||
addSchems(region, mask, worldData, clipboards, rarity, rotate);
|
||||
}
|
||||
|
||||
@ -657,12 +654,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
|
||||
public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1));
|
||||
addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
}
|
||||
|
||||
public void addDefaultOres(Mask mask) throws WorldEditException {
|
||||
addOres(new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength())), mask);
|
||||
addOres(new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth() -1, 255, getLength() -1)), mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -670,6 +667,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
return new Vector(0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FawePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getMaximumPoint() {
|
||||
return new Vector(getWidth() - 1, 255, getLength() - 1);
|
||||
@ -749,6 +751,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
return new SimpleCharFaweChunk(this, chunkX, chunkZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getSnapshot(int chunkX, int chunkZ) {
|
||||
return getSnapshot(null, chunkX, chunkZ);
|
||||
}
|
||||
@ -789,7 +792,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
|
||||
@Override
|
||||
public void setChunk(FaweChunk chunk) {
|
||||
System.out.println(((SimpleCharFaweChunk) chunk).getTotalCount());
|
||||
char[][] src = chunk.getCombinedIdArrays();
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
if (src[i] != null) {
|
||||
@ -875,9 +877,9 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
public void close(boolean update) {
|
||||
clear();
|
||||
if (chunkOffset != null && player != null) {
|
||||
if (chunkOffset != null && player != null && update) {
|
||||
FaweQueue packetQueue = SetQueue.IMP.getNewQueue(player.getWorld(), true, false);
|
||||
|
||||
int lenCX = (getWidth() + 15) >> 4;
|
||||
@ -901,6 +903,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
}
|
||||
}
|
||||
if (player != null) {
|
||||
player.deleteMeta("CFISettings");
|
||||
LocalSession session = player.getSession();
|
||||
session.clearHistory();
|
||||
}
|
||||
player = null;
|
||||
chunkOffset = null;
|
||||
}
|
||||
@ -921,7 +928,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
int index = z * getWidth() + x;
|
||||
if (y < 0) return 0;
|
||||
if (index < 0 || index >= getArea()) index = Math.floorMod(index, getArea());
|
||||
if (index < 0 || index >= getArea() || x < 0 || x >= getWidth()) return 0;
|
||||
int height = heights.getByte(index) & 0xFF;
|
||||
if (y > height) {
|
||||
if (y == height + 1) {
|
||||
@ -1053,6 +1060,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
return heights.getByte(index) & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= getArea()) index = Math.floorMod(index, getArea());
|
||||
return heights.getByte(index) & 0xFF;
|
||||
}
|
||||
|
||||
public void setBiome(BufferedImage img, byte biome, boolean white) {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
@ -1824,7 +1838,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
}
|
||||
|
||||
if (primtives.floorThickness != 0) {
|
||||
if (primtives.floorThickness != 0 || primtives.worldThickness != 0) {
|
||||
// Use biomes array as temporary buffer
|
||||
byte[] minArr = chunk.biomes;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
@ -1842,33 +1856,73 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
}
|
||||
|
||||
int minLayer = Math.max(0, (minY - primtives.floorThickness) >> 4);
|
||||
for (int layer = 0; layer < minLayer; layer++) {
|
||||
chunk.ids[layer] = null;
|
||||
chunk.data[layer] = null;
|
||||
|
||||
if (primtives.floorThickness != 0) {
|
||||
for (int layer = minLayer; layer <= maxLayer; layer++) {
|
||||
byte[] layerIds = chunk.ids[layer];
|
||||
byte[] layerDatas = chunk.data[layer];
|
||||
int startY = layer << 4;
|
||||
int endY = startY + 15;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
index = (z & 15) << 4;
|
||||
for (int x = csx; x <= cex; x++, index++) {
|
||||
globalIndex = indexes[index];
|
||||
int height = heightMap[index];
|
||||
|
||||
int min = (minArr[index] & 0xFF) - primtives.floorThickness;
|
||||
int localMin = min - startY;
|
||||
|
||||
int max = height + 1;
|
||||
if (min < startY) min = startY;
|
||||
if (max > endY) max = endY + 1;
|
||||
|
||||
|
||||
if (min < max) {
|
||||
char floorCombined = floor[globalIndex];
|
||||
final byte id = (byte) FaweCache.getId(floorCombined);
|
||||
final int data = FaweCache.getData(floorCombined);
|
||||
for (int y = min; y < max; y++) {
|
||||
int floorIndex = index + ((y & 15) << 8);
|
||||
layerIds[floorIndex] = id;
|
||||
if (data != 0) {
|
||||
chunk.setNibble(floorIndex, layerDatas, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int layer = minLayer; layer <= maxLayer; layer++) {
|
||||
byte[] layerIds = chunk.ids[layer];
|
||||
byte[] layerDatas = chunk.data[layer];
|
||||
int startY = layer << 4;
|
||||
int endY = startY + 15;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
index = (z & 15) << 4;
|
||||
for (int x = csx; x <= cex; x++, index++) {
|
||||
globalIndex = indexes[index];
|
||||
int height = heightMap[index];
|
||||
if (primtives.worldThickness != 0) {
|
||||
for (int layer = 0; layer < minLayer; layer++) {
|
||||
chunk.ids[layer] = null;
|
||||
chunk.data[layer] = null;
|
||||
}
|
||||
for (int layer = minLayer; layer <= maxLayer; layer++) {
|
||||
byte[] layerIds = chunk.ids[layer];
|
||||
byte[] layerDatas = chunk.data[layer];
|
||||
int startY = layer << 4;
|
||||
int endY = startY + 15;
|
||||
for (int z = csz; z <= cez; z++) {
|
||||
index = (z & 15) << 4;
|
||||
for (int x = csx; x <= cex; x++, index++) {
|
||||
globalIndex = indexes[index];
|
||||
int height = heightMap[index];
|
||||
|
||||
int min = (minArr[index] & 0xFF) - primtives.floorThickness;
|
||||
int localMin = min - startY;
|
||||
if (localMin > 0) {
|
||||
char floorCombined = floor[globalIndex];
|
||||
final byte id = (byte) FaweCache.getId(floorCombined);
|
||||
final int data = FaweCache.getData(floorCombined);
|
||||
int min = (minArr[index] & 0xFF) - primtives.worldThickness;
|
||||
int localMin = min - startY;
|
||||
if (localMin > 0) {
|
||||
char floorCombined = floor[globalIndex];
|
||||
final byte id = (byte) FaweCache.getId(floorCombined);
|
||||
final int data = FaweCache.getData(floorCombined);
|
||||
|
||||
for (int y = 0; y < localMin; y++) {
|
||||
int floorIndex = index + ((y & 15) << 8);
|
||||
layerIds[floorIndex] = 0;
|
||||
if (data != 0) {
|
||||
chunk.setNibble(floorIndex, layerDatas, 0);
|
||||
for (int y = 0; y < localMin; y++) {
|
||||
int floorIndex = index + ((y & 15) << 8);
|
||||
layerIds[floorIndex] = 0;
|
||||
if (data != 0) {
|
||||
chunk.setNibble(floorIndex, layerDatas, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2080,7 +2134,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return SimpleWorld.super.getMaxY();
|
||||
return 255;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2208,6 +2262,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements SimpleWorld, Faw
|
||||
|
||||
@Override
|
||||
public WorldData getWorldData() {
|
||||
if (player != null) return player.getWorld().getWorldData();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -11,24 +11,11 @@ import com.boydti.fawe.util.ArrayUtil;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.jnbt.*;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public class MCAChunk extends FaweChunk<Void> {
|
||||
|
||||
@ -102,13 +89,7 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toBytes(byte[] buffer) throws IOException {
|
||||
if (buffer == null) {
|
||||
buffer = new byte[8192];
|
||||
}
|
||||
FastByteArrayOutputStream buffered = new FastByteArrayOutputStream(buffer);
|
||||
DataOutputStream dataOut = new DataOutputStream(buffered);
|
||||
NBTOutputStream nbtOut = new NBTOutputStream((DataOutput) dataOut);
|
||||
public void write(NBTOutputStream nbtOut) throws IOException {
|
||||
nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND);
|
||||
nbtOut.writeLazyCompoundTag("Level", new NBTOutputStream.LazyWrite() {
|
||||
@Override
|
||||
@ -135,12 +116,12 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
}
|
||||
out.writeNamedTag("HeightMap", heightMap);
|
||||
out.writeNamedTagName("Sections", NBTConstants.TYPE_LIST);
|
||||
dataOut.writeByte(NBTConstants.TYPE_COMPOUND);
|
||||
nbtOut.getOutputStream().writeByte(NBTConstants.TYPE_COMPOUND);
|
||||
int len = 0;
|
||||
for (int layer = 0; layer < ids.length; layer++) {
|
||||
if (ids[layer] != null) len++;
|
||||
}
|
||||
dataOut.writeInt(len);
|
||||
nbtOut.getOutputStream().writeInt(len);
|
||||
for (int layer = 0; layer < ids.length; layer++) {
|
||||
byte[] idLayer = ids[layer];
|
||||
if (idLayer == null) {
|
||||
@ -156,7 +137,17 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
}
|
||||
});
|
||||
nbtOut.writeEndTag();
|
||||
nbtOut.close();
|
||||
}
|
||||
|
||||
public byte[] toBytes(byte[] buffer) throws IOException {
|
||||
if (buffer == null) {
|
||||
buffer = new byte[8192];
|
||||
}
|
||||
FastByteArrayOutputStream buffered = new FastByteArrayOutputStream(buffer);
|
||||
DataOutputStream dataOut = new DataOutputStream(buffered);
|
||||
try (NBTOutputStream nbtOut = new NBTOutputStream((DataOutput) dataOut)) {
|
||||
write(nbtOut);
|
||||
}
|
||||
return buffered.toByteArray();
|
||||
}
|
||||
|
||||
@ -287,9 +278,9 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
short pair = MathMan.tripleBlockCoord(x, y, z);
|
||||
CompoundTag tag = entry.getValue();
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
|
||||
map.put("x", new IntTag(x + (getX() << 4)));
|
||||
map.put("x", new IntTag((x & 15) + (getX() << 4)));
|
||||
map.put("y", new IntTag(y));
|
||||
map.put("z", new IntTag(z + (getZ() << 4)));
|
||||
map.put("z", new IntTag((z & 15) + (getZ() << 4)));
|
||||
tiles.put(pair, tag);
|
||||
}
|
||||
}
|
||||
@ -465,7 +456,7 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
return FaweCache.asTag(root);
|
||||
}
|
||||
|
||||
public MCAChunk(NBTInputStream nis, FaweQueue parent, int x, int z, int compressedSize) throws IOException {
|
||||
public MCAChunk(NBTInputStream nis, FaweQueue parent, int x, int z, boolean readPos) throws IOException {
|
||||
super(parent, x, z);
|
||||
ids = new byte[16][];
|
||||
data = new byte[16][];
|
||||
@ -510,7 +501,6 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
if (entities == null) {
|
||||
entities = new HashMap<UUID, CompoundTag>();
|
||||
}
|
||||
|
||||
long least = entityTag.getLong("UUIDLeast");
|
||||
long most = entityTag.getLong("UUIDMost");
|
||||
entities.put(new UUID(most, least), entityTag);
|
||||
@ -528,6 +518,20 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
heightMap = value;
|
||||
}
|
||||
});
|
||||
if (readPos) {
|
||||
streamer.addReader(".Level.xPos", new RunnableVal2<Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer index, Integer value) {
|
||||
MCAChunk.this.setLoc(getParent(), value, getZ());
|
||||
}
|
||||
});
|
||||
streamer.addReader(".Level.zPos", new RunnableVal2<Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer index, Integer value) {
|
||||
MCAChunk.this.setLoc(getParent(), getX(), value);
|
||||
}
|
||||
});
|
||||
}
|
||||
streamer.readFully();
|
||||
}
|
||||
|
||||
@ -733,16 +737,20 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
|
||||
public void removeLight() {
|
||||
for (int i = 0; i < skyLight.length; i++) {
|
||||
byte[] array1 = skyLight[i];
|
||||
if (array1 == null) {
|
||||
continue;
|
||||
}
|
||||
byte[] array2 = blockLight[i];
|
||||
Arrays.fill(array1, (byte) 0);
|
||||
Arrays.fill(array2, (byte) 0);
|
||||
removeLight(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLight(int i) {
|
||||
byte[] array1 = skyLight[i];
|
||||
if (array1 == null) {
|
||||
return;
|
||||
}
|
||||
byte[] array2 = blockLight[i];
|
||||
Arrays.fill(array1, (byte) 0);
|
||||
Arrays.fill(array2, (byte) 0);
|
||||
}
|
||||
|
||||
public int getNibble(int index, byte[] array) {
|
||||
int indexShift = index >> 1;
|
||||
if ((index & 1) == 0) {
|
||||
|
@ -86,6 +86,17 @@ public class MCAFile {
|
||||
Z = Integer.parseInt(split[2]);
|
||||
}
|
||||
|
||||
public MCAFile(FaweQueue parent, int mcrX, int mcrZ) throws Exception {
|
||||
this(parent, mcrX, mcrZ, new File(parent.getSaveFolder(), "r." + mcrX + "." + mcrZ + ".mca"));
|
||||
}
|
||||
|
||||
public MCAFile(FaweQueue parent, int mcrX, int mcrZ, File file) {
|
||||
this.queue = parent;
|
||||
this.file = file;
|
||||
X = mcrX;
|
||||
Z = mcrZ;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (raf != null) {
|
||||
try {
|
||||
@ -123,16 +134,21 @@ public class MCAFile {
|
||||
return queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the location header from disk
|
||||
*/
|
||||
public void init() {
|
||||
try {
|
||||
if (raf == null) {
|
||||
this.locations = new byte[4096];
|
||||
this.raf = new RandomAccessFile(file, "rw");
|
||||
if (raf.length() < 8192) {
|
||||
raf.setLength(8192);
|
||||
} else {
|
||||
raf.seek(0);
|
||||
raf.readFully(locations);
|
||||
if (file != null) {
|
||||
this.raf = new RandomAccessFile(file, "rw");
|
||||
if (raf.length() < 8192) {
|
||||
raf.setLength(8192);
|
||||
} else {
|
||||
raf.seek(0);
|
||||
raf.readFully(locations);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
@ -140,10 +156,6 @@ public class MCAFile {
|
||||
}
|
||||
}
|
||||
|
||||
public MCAFile(FaweQueue parent, int mcrX, int mcrZ) throws Exception {
|
||||
this(parent, new File(parent.getSaveFolder(), "r." + mcrX + "." + mcrZ + ".mca"));
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return X;
|
||||
}
|
||||
@ -193,7 +205,7 @@ public class MCAFile {
|
||||
return null;
|
||||
}
|
||||
NBTInputStream nis = getChunkIS(offset);
|
||||
MCAChunk chunk = new MCAChunk(nis, queue, cx, cz, size);
|
||||
MCAChunk chunk = new MCAChunk(nis, queue, cx, cz, false);
|
||||
nis.close();
|
||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||
synchronized (chunks) {
|
||||
@ -403,7 +415,9 @@ public class MCAFile {
|
||||
if (raf.length() - offset < len) {
|
||||
raf.setLength(((offset + len + 4095) / 4096) * 4096);
|
||||
}
|
||||
// Length of remaining data
|
||||
raf.writeInt(data.length + 1);
|
||||
// Compression type
|
||||
raf.write(2);
|
||||
raf.write(data);
|
||||
}
|
||||
@ -458,24 +472,38 @@ public class MCAFile {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the chunk to the file
|
||||
* @param pool
|
||||
*/
|
||||
public void flush(ForkJoinPool pool) {
|
||||
synchronized (raf) {
|
||||
// If the file is marked as deleted, nothing is written
|
||||
if (isDeleted()) {
|
||||
clear();
|
||||
file.delete();
|
||||
return;
|
||||
}
|
||||
boolean wait;
|
||||
|
||||
boolean wait; // If the flush method needs to wait for the pool
|
||||
if (pool == null) {
|
||||
wait = true;
|
||||
pool = new ForkJoinPool();
|
||||
} else wait = false;
|
||||
|
||||
// Chunks that need to be relocated
|
||||
Int2ObjectOpenHashMap<byte[]> relocate = new Int2ObjectOpenHashMap<>();
|
||||
// The position of each chunk
|
||||
final Int2ObjectOpenHashMap<Integer> offsetMap = new Int2ObjectOpenHashMap<>(); // Offset -> <byte cx, byte cz, short size>
|
||||
// The data of each modified chunk
|
||||
final Int2ObjectOpenHashMap<byte[]> compressedMap = new Int2ObjectOpenHashMap<>();
|
||||
// The data of each chunk that needs to be moved
|
||||
final Int2ObjectOpenHashMap<byte[]> append = new Int2ObjectOpenHashMap<>();
|
||||
boolean modified = false;
|
||||
// Get the current time for the chunk timestamp
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
// Load the chunks into the append or compressed map
|
||||
for (MCAChunk chunk : getCachedChunks()) {
|
||||
if (chunk.isModified() || chunk.isDeleted()) {
|
||||
modified = true;
|
||||
@ -504,8 +532,12 @@ public class MCAFile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If any changes were detected
|
||||
if (modified) {
|
||||
file.setLastModified(now);
|
||||
|
||||
// Load the offset data into the offset map
|
||||
forEachChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
|
||||
@Override
|
||||
public void run(Integer cx, Integer cz, Integer offset, Integer size) {
|
||||
@ -514,29 +546,41 @@ public class MCAFile {
|
||||
offsetMap.put((int) offset, (Integer) MathMan.pair(pair1, pair2));
|
||||
}
|
||||
});
|
||||
// Wait for previous tasks
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
int start = 8192;
|
||||
int written = start;
|
||||
int end = 8192;
|
||||
int nextOffset = 8192;
|
||||
try {
|
||||
for (int count = 0; count < offsetMap.size(); count++) {
|
||||
// Get the previous position of the next chunk
|
||||
Integer loc = offsetMap.get(nextOffset);
|
||||
while (loc == null) {
|
||||
nextOffset += 4096;
|
||||
loc = offsetMap.get(nextOffset);
|
||||
}
|
||||
int offset = nextOffset;
|
||||
|
||||
// Get the x/z from the paired location
|
||||
short cxz = MathMan.unpairX(loc);
|
||||
int cx = MathMan.unpairShortX(cxz);
|
||||
int cz = MathMan.unpairShortY(cxz);
|
||||
|
||||
// Get the size from the pair
|
||||
int size = MathMan.unpairY(loc) << 12;
|
||||
|
||||
nextOffset += size;
|
||||
end = Math.min(start + size, end);
|
||||
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
|
||||
byte[] newBytes = relocate.get(pair);
|
||||
|
||||
// newBytes is null if the chunk isn't modified or marked for moving
|
||||
if (newBytes == null) {
|
||||
MCAChunk cached = getCachedChunk(cx, cz);
|
||||
// If the previous offset marks the current write position (start) then we only write the header
|
||||
if (offset == start) {
|
||||
if (cached == null || !cached.isModified()) {
|
||||
writeHeader(raf, cx, cz, start >> 12, size >> 12, true);
|
||||
@ -547,6 +591,7 @@ public class MCAFile {
|
||||
newBytes = compressedMap.get(pair);
|
||||
}
|
||||
} else {
|
||||
// The chunk needs to be moved, fetch the data if necessary
|
||||
newBytes = compressedMap.get(pair);
|
||||
if (newBytes == null) {
|
||||
if (cached == null || !cached.isDeleted()) {
|
||||
@ -555,14 +600,19 @@ public class MCAFile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newBytes == null) {
|
||||
writeHeader(raf, cx, cz, 0, 0, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The length to be written (compressed data + 5 byte chunk header)
|
||||
int len = newBytes.length + 5;
|
||||
int oldSize = (size + 4095) >> 12;
|
||||
int newSize = (len + 4095) >> 12;
|
||||
int nextOffset2 = end;
|
||||
|
||||
// If the current write position (start) + length of data to write (len) are longer than the position of the next chunk, we need to move the next chunks
|
||||
while (start + len > end) {
|
||||
Integer nextLoc = offsetMap.get(nextOffset2);
|
||||
if (nextLoc != null) {
|
||||
@ -582,11 +632,16 @@ public class MCAFile {
|
||||
nextOffset2 += 4096;
|
||||
}
|
||||
}
|
||||
// Write the chunk + chunk header
|
||||
writeSafe(raf, start, newBytes);
|
||||
// Write the location data (beginning of file)
|
||||
writeHeader(raf, cx, cz, start >> 12, newSize, true);
|
||||
|
||||
written = start + newBytes.length + 5;
|
||||
start += newSize << 12;
|
||||
}
|
||||
|
||||
// Write all the chunks which need to be appended
|
||||
if (!append.isEmpty()) {
|
||||
for (Int2ObjectMap.Entry<byte[]> entry : append.int2ObjectEntrySet()) {
|
||||
int pair = entry.getIntKey();
|
||||
@ -601,6 +656,7 @@ public class MCAFile {
|
||||
start += newSize << 12;
|
||||
}
|
||||
}
|
||||
// Round the file length, since the vanilla server doesn't like it for some reason
|
||||
raf.setLength(4096 * ((written + 4095) / 4096));
|
||||
if (raf instanceof BufferedRandomAccessFile) {
|
||||
((BufferedRandomAccessFile) raf).flush();
|
||||
@ -614,6 +670,7 @@ public class MCAFile {
|
||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
chunks.clear();
|
||||
}
|
||||
IterableThreadLocal.clean(byteStore1);
|
||||
IterableThreadLocal.clean(byteStore2);
|
||||
|
@ -70,6 +70,10 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
this.hasSky = hasSky;
|
||||
}
|
||||
|
||||
public boolean hasParent() {
|
||||
return parent != null || parentNMS != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk loadChunk(FaweQueue faweQueue, int x, int z, boolean generate) {
|
||||
return getFaweChunk(x, z);
|
||||
@ -122,7 +126,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
int cbz = (cz << 4) - oZ;
|
||||
|
||||
boolean changed = false;
|
||||
for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) {
|
||||
for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) {
|
||||
for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) {
|
||||
FaweChunk chunk;
|
||||
synchronized (this) {
|
||||
@ -147,7 +151,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMCA(int mcaX, int mcaZ, RegionWrapper region, Runnable whileLocked, boolean save, boolean unload) {
|
||||
@ -530,7 +534,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
mutableBlock.setChunk(chunk);
|
||||
int bx = cx << 4;
|
||||
int bz = cz << 4;
|
||||
for (int layer = 0; layer < chunk.ids.length; layer++) {
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
if (chunk.doesSectionExist(layer)) {
|
||||
mutableBlock.setArrays(layer);
|
||||
int yStart = layer << 4;
|
||||
@ -687,6 +691,22 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSectionLighting(FaweChunk sections, int layer, boolean hasSky) {
|
||||
if (sections.getClass() == MCAChunk.class) {
|
||||
((MCAChunk) sections).removeLight(layer);
|
||||
} else if (parentNMS != null) {
|
||||
int cx = sections.getX();
|
||||
int cz = sections.getZ();
|
||||
parentNMS.ensureChunkLoaded(cx, cz);
|
||||
Object parentSections = parentNMS.getCachedSections(parentNMS.getWorld(), cx, cz);
|
||||
if (parentSections != null) {
|
||||
parentNMS.removeSectionLighting(sections, layer, hasSky);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(FaweChunk sections, RelightMode mode, boolean hasSky) {
|
||||
if (mode != RelightMode.NONE) {
|
||||
|
@ -53,13 +53,19 @@ public class MCAQueueMap implements IFaweQueueMap {
|
||||
if (lastFile == null) {
|
||||
try {
|
||||
queue.setMCA(lastFileX, lastFileZ, RegionWrapper.GLOBAL(), null, true, false);
|
||||
File file = new File(queue.getSaveFolder(), "r." + lastFileX + "." + lastFileZ + ".mca");
|
||||
if (create) {
|
||||
File parent = file.getParentFile();
|
||||
if (!parent.exists()) parent.mkdirs();
|
||||
if (!file.exists()) file.createNewFile();
|
||||
File save = queue.getSaveFolder();
|
||||
File file;
|
||||
if (save != null) {
|
||||
file = new File(queue.getSaveFolder(), "r." + lastFileX + "." + lastFileZ + ".mca");
|
||||
if (create) {
|
||||
File parent = file.getParentFile();
|
||||
if (!parent.exists()) parent.mkdirs();
|
||||
if (!file.exists()) file.createNewFile();
|
||||
}
|
||||
} else {
|
||||
file = null;
|
||||
}
|
||||
lastFile = tmp = new MCAFile(queue, file);
|
||||
lastFile = tmp = new MCAFile(queue, mcaX, mcaZ, file);
|
||||
} catch (FaweException.FaweChunkLoadException ignore) {
|
||||
lastFile = null;
|
||||
return null;
|
||||
@ -187,6 +193,8 @@ public class MCAQueueMap implements IFaweQueueMap {
|
||||
lastZ = Integer.MIN_VALUE;
|
||||
lastFileX = Integer.MIN_VALUE;
|
||||
lastFileZ = Integer.MIN_VALUE;
|
||||
lastChunk = null;
|
||||
lastFile = null;
|
||||
if (!mcaFileMap.isEmpty()) {
|
||||
Iterator<Map.Entry<Long, MCAFile>> iter = mcaFileMap.entrySet().iterator();
|
||||
boolean result;
|
||||
|
@ -0,0 +1,86 @@
|
||||
package com.boydti.fawe.jnbt.anvil.filters;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.number.MutableLong;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DebugFixAir extends MCAFilterCounter {
|
||||
@Override
|
||||
public MCAChunk applyChunk(MCAChunk chunk, MutableLong cache) {
|
||||
none:
|
||||
{
|
||||
some:
|
||||
{
|
||||
for (int layer = 0; layer < chunk.ids.length; layer++) {
|
||||
byte[] idLayer = chunk.ids[layer];
|
||||
if (idLayer == null) continue;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (idLayer[i] != 0) {
|
||||
if (layer != 0) break some;
|
||||
break none;
|
||||
}
|
||||
}
|
||||
{ // Possibly dead code depending on the generator
|
||||
chunk.ids[layer] = null;
|
||||
chunk.data[layer] = null;
|
||||
chunk.setModified();
|
||||
}
|
||||
}
|
||||
cache.add(Character.MAX_VALUE);
|
||||
chunk.setDeleted(true);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (chunk.ids[i] == null) return null;
|
||||
}
|
||||
// layer 0
|
||||
boolean modified = false;
|
||||
byte[] ids0 = chunk.ids[0];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (ids0[i] == 0) {
|
||||
if (!modified) {
|
||||
modified = true;
|
||||
}
|
||||
for (int layer = 0; layer < 4; layer++) {
|
||||
byte[] arr = chunk.ids[layer];
|
||||
for (int y = i; y < 4096; y += 256) {
|
||||
arr[y] = BlockID.DIRT;
|
||||
}
|
||||
}
|
||||
ids0[i] = BlockID.BEDROCK;
|
||||
if (chunk.ids[4][i] == 0) chunk.ids[4][i] = BlockID.GRASS;
|
||||
cache.add(256);
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
Arrays.fill(chunk.skyLight[4], (byte) 255);
|
||||
chunk.setModified();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishFile(MCAFile file, MutableLong cache) {
|
||||
Fawe.debug(" - apply " + file.getFile());
|
||||
boolean[] deleteFile = { true };
|
||||
file.forEachCachedChunk(new RunnableVal<MCAChunk>() {
|
||||
@Override
|
||||
public void run(MCAChunk value) {
|
||||
if (!value.isDeleted()) {
|
||||
deleteFile[0] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (deleteFile[0]) {
|
||||
file.setDeleted(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.boydti.fawe.jnbt.anvil.filters;
|
||||
|
||||
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
|
||||
import com.boydti.fawe.object.number.MutableLong;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
public class DeleteBiomeFilterSimple extends MCAFilterCounter {
|
||||
private final int id;
|
||||
|
||||
public DeleteBiomeFilterSimple(BaseBiome biome) {
|
||||
this.id = biome.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk applyChunk(MCAChunk chunk, MutableLong cache) {
|
||||
if ((chunk.biomes[0] & 0xFF) == id) {
|
||||
chunk.setDeleted(true);
|
||||
cache.add(Character.MAX_VALUE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -41,6 +41,8 @@ public class PlotTrimFilter extends DeleteUninhabitedFilter {
|
||||
|
||||
public PlotTrimFilter(World world, long fileDuration, long inhabitedTicks, long chunkInactivity) {
|
||||
super(fileDuration, inhabitedTicks, chunkInactivity);
|
||||
Fawe.debug("Initializing Plot trim...");
|
||||
|
||||
String worldName = Fawe.imp().getWorldName(world);
|
||||
PlotArea area = PS.get().getPlotAreaByString(worldName);
|
||||
IndependentPlotGenerator gen = area.getGenerator();
|
||||
@ -57,6 +59,7 @@ public class PlotTrimFilter extends DeleteUninhabitedFilter {
|
||||
|
||||
this.reference = calculateReference();
|
||||
|
||||
Fawe.debug(" - calculating claims");
|
||||
this.calculateClaimedArea();
|
||||
}
|
||||
|
||||
@ -114,6 +117,7 @@ public class PlotTrimFilter extends DeleteUninhabitedFilter {
|
||||
|
||||
@Override
|
||||
public boolean shouldDelete(File file, BasicFileAttributes attr, int mcaX, int mcaZ) throws IOException {
|
||||
Fawe.debug("Apply file: " + file);
|
||||
return !occupiedRegions.containsKey(mcaX, mcaZ) || super.shouldDelete(file, attr, mcaX, mcaZ);
|
||||
}
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
package com.boydti.fawe.jnbt.anvil.filters;
|
||||
|
||||
public class RegionFilter {
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.boydti.fawe.jnbt.anvil.filters;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
|
||||
import com.boydti.fawe.object.number.MutableLong;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class SetPatternFilter extends MCAFilterCounter {
|
||||
private final Pattern to;
|
||||
|
||||
public SetPatternFilter(Pattern to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyBlock(int x, int y, int z, BaseBlock block, MutableLong count) {
|
||||
BaseBlock newBlock = to.apply(x, y, z);
|
||||
int currentId = block.getId();
|
||||
if (FaweCache.hasNBT(currentId)) {
|
||||
block.setNbtData(null);
|
||||
}
|
||||
block.setId(newBlock.getId());
|
||||
block.setData(newBlock.getData());
|
||||
count.increment();
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ public class TrimAirFilter extends MCAFilterCounter {
|
||||
chunk.setModified();
|
||||
}
|
||||
}
|
||||
cache.add(Character.MAX_VALUE);
|
||||
chunk.setDeleted(true);
|
||||
return null;
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
package com.boydti.fawe.jnbt.anvil.filters;
|
||||
|
||||
import com.boydti.fawe.jnbt.anvil.MCAChunk;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFile;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.number.MutableLong;
|
||||
|
||||
public class TrimFlatFilter extends MCAFilterCounter {
|
||||
@Override
|
||||
public MCAChunk applyChunk(MCAChunk chunk, MutableLong cache) {
|
||||
// Check other layers
|
||||
for (int layer = 1; layer < chunk.ids.length; layer++) {
|
||||
byte[] idLayer = chunk.ids[layer];
|
||||
if (idLayer == null) continue;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (idLayer[i] != 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
{ // Possibly dead code depending on the generator
|
||||
chunk.ids[layer] = null;
|
||||
chunk.data[layer] = null;
|
||||
chunk.setModified();
|
||||
}
|
||||
}
|
||||
byte[] layer0 = chunk.ids[0];
|
||||
if (layer0 == null) return null;
|
||||
int index = 0;
|
||||
for (int y = 0; y <= 3; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++, index++) {
|
||||
int id = layer0[index] & 0xFF;
|
||||
switch (id) {
|
||||
case 2: // grass
|
||||
case 3: // dirt
|
||||
case 7: // bedrock
|
||||
continue;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int y = 4; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++, index++) {
|
||||
if (layer0[index] != 0) return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check floor layers
|
||||
cache.add(Character.MAX_VALUE);
|
||||
chunk.setDeleted(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishFile(MCAFile file, MutableLong cache) {
|
||||
boolean[] deleteFile = { true };
|
||||
file.forEachCachedChunk(new RunnableVal<MCAChunk>() {
|
||||
@Override
|
||||
public void run(MCAChunk value) {
|
||||
if (!value.isDeleted()) {
|
||||
deleteFile[0] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (deleteFile[0]) {
|
||||
file.setDeleted(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -46,8 +46,8 @@ public class OreGen extends Resource {
|
||||
}
|
||||
double f = rand.nextDouble() * Math.PI;
|
||||
|
||||
int x8 = x + 8;
|
||||
int z8 = z + 8;
|
||||
int x8 = x;
|
||||
int z8 = z;
|
||||
double so8 = maxSizeO8;
|
||||
double so16 = maxSizeO16;
|
||||
double sf = MathMan.sinInexact(f) * so8;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user