Compare commits

...

405 Commits
Dev ... master

Author SHA1 Message Date
dordsor21 a693d23489
Make it build and add safety to tab completion times 2021-03-07 19:34:14 +00:00
N0tMyFaultOG 98e85733b9 Let's not open issues here anymore 2020-05-30 00:22:30 +02:00
N0tMyFaultOG e6da2a5810 * 2020-05-29 20:00:23 +02:00
NotMyFault 259fcc2f29 Add metrics to Favs and add missing dependencies 2020-02-01 14:35:11 +01:00
NotMyFault 93548e4fe9
Update ISSUE_TEMPLATE.md 2019-12-31 00:04:00 +01:00
NotMyFault 29c9feea44
Update ISSUE_TEMPLATE.md 2019-12-31 00:00:39 +01:00
Jesse Boyd 55059437be
Delete RegionFilter.java 2019-11-13 14:54:25 -08:00
Jesse Boyd 42bd4583fa
Merge pull request #1332 from nmaster/master
Enable FAWE for Command Blocks in Nukkit.
2019-10-31 06:00:06 -07:00
NotMyFault 9ff3f45e52
Update README.md 2019-10-31 11:50:49 +01:00
NotMyFault c5d6466eed
Fixes #1304
A bit late but I'm going thru my old issues ;p
2019-10-30 17:27:41 +01:00
Dominik Renzel 7bc2e0181b enable FAWE for command blocks to work in nukkit. 2019-09-23 00:16:04 +02:00
Dominik Renzel 756b9d00af added bin folders to gitignore 2019-09-22 23:21:38 +02:00
Dominik Renzel a3cb8af95d Revert "Added support for command blocks in Nukkit."
This reverts commit ba9aff2a8a.
2019-09-22 23:19:42 +02:00
Dominik Renzel d3cc84c026 Revert "removed unnecessary code"
This reverts commit 553c89beeb.
2019-09-22 23:19:20 +02:00
Dominik Renzel 553c89beeb removed unnecessary code 2019-09-22 16:51:22 +02:00
Dominik Renzel ba9aff2a8a Added support for command blocks in Nukkit. 2019-09-22 16:14:35 +02:00
NotMyFault 58243b6757 Backport debugpaste order
Also add dependency check for NukkitX.
2019-07-25 22:32:38 +02:00
Jesse Boyd 5cc5ce5537
FIx for AsyncChunk 2019-07-12 17:38:03 +10:00
NotMyFault e994c765fa Add permission for //help 2019-07-07 01:26:05 +02:00
NotMyFault f71043bea6 Moving fawe adapter to console 2019-06-13 01:52:41 +02:00
NotMyFault d89cb44db7
Update ISSUE_TEMPLATE.md 2019-05-02 22:06:36 +02:00
NotMyFault 4879e0b62a Add javadoc 2019-05-02 19:49:10 +02:00
NotMyFault e1a62156c2 Add paste service 2019-05-01 23:50:07 +02:00
dordsor21 57c85d0aac Fix build I guess 2019-04-22 14:04:38 +01:00
NotMyFault 3132b8f1f2 Revert "Just build bukkit artifacts"
Dw dords, the last build will stay online on codemc so people can get it there incase our ci tends to die again and they can't build it locally :)
2019-04-22 00:54:26 +02:00
NotMyFault 2eee25e44e
Just build bukkit artifacts 2019-04-22 00:44:35 +02:00
Jesse Boyd 56499b7752
Fix invalid schematic message 2019-04-13 07:15:35 +10:00
Jesse Boyd 361a4e3dce
Potential NBT fix 2019-04-13 00:56:10 +10:00
Jesse Boyd a31dd987a5
drop endswith check 2019-04-11 13:18:26 +10:00
Jesse Boyd c5640e5038
optimize FawePlayer wrap @aikar 2019-04-11 11:11:09 +10:00
Jesse Boyd e901a0eba6
Remove getSimpleName FawePlayer 2019-04-11 02:12:38 +10:00
Jesse Boyd 4c87fea95c
fix NPE with void chunk 2019-04-06 15:34:45 +11:00
Jesse Boyd c6db4e10fd
Add return value 2019-04-06 14:48:04 +11:00
Jesse Boyd d1f6ef14ef
*rename method 2019-04-06 14:47:23 +11:00
Jesse Boyd dd28c78a36
trimflatfilter 2019-04-06 14:45:39 +11:00
Jesse Boyd 92e50d5897
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2019-04-06 05:05:50 +11:00
Jesse Boyd 4c9f9606d9
re-add bukkit mvn artifact 2019-04-06 05:03:37 +11:00
dordsor21 8c3e6b7e08
Update offset to match ci 2019-04-03 14:42:54 +01:00
Jesse Boyd b514efecfc
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2019-04-03 01:37:49 +11:00
Jesse Boyd 049dbe2dc2
Fix farmland data 2019-04-03 01:34:29 +11:00
NotMyFault d13b946b02
Update README.md 2019-03-29 21:36:10 +01:00
NotMyFault a1ffd3d5ff Fix PlotSquared maven repo link 2019-03-21 19:41:41 +01:00
NotMyFault 4bd026239d Adding link for 1.13.x issues
There you have your description and links ;p

Co-Authored-By: Hannes Greule <sirywell@users.noreply.github.com>
2019-03-21 19:35:57 +01:00
NotMyFault 14f3b914d3
Update offset to match build version 2019-03-02 13:43:53 +01:00
NotMyFault b39b388645 Reorder debugpaste information 2019-03-01 00:39:36 +01:00
NotMyFault 28e2537aaa
Merge pull request #1275 from N0tMyFaultOG/master
Fix building Forge versions
2019-02-27 07:07:18 +01:00
NotMyFault ab71b938e5 Fix building Forge versions 2019-02-27 07:05:41 +01:00
Josh Knight 70e24e432c
Merge pull request #1274 from N0tMyFaultOG/master
Switching from hastebin to Incendo
2019-02-26 19:37:55 -05:00
NotMyFault ee9950bca7 Switching from hastebin to Incendo 2019-02-26 15:50:01 +01:00
NotMyFault dc2d277517
Update ISSUE_TEMPLATE.md 2019-01-12 18:03:39 +01:00
NotMyFault 56a71fae5e
Typo fix, smh 2019-01-01 23:42:16 +01:00
NotMyFault e5c6a79f65
Update README.md 2018-12-29 13:59:53 +01:00
NotMyFault e5c7042e25
Fixing error when radius was smaller then 1 2018-12-29 13:35:35 +01:00
NotMyFault d131fa657e
Merge pull request #1220 from GreenChennai/patch-2
Update chinese message.yml
2018-12-19 15:58:03 +01:00
GreenChennai 6afe1b0ca6
Merge branch 'master' into patch-2 2018-12-19 19:33:13 +08:00
NotMyFault e64debbc2a Switching from IRC to Discord
To offer us a better possibility to help you, visit us on discord https://discord.gg/ngZCzbU
2018-12-18 21:15:53 +01:00
dordsor21 772de99706 * 2018-12-17 13:44:59 +00:00
dordsor21 f0fbd34d3c See if we can't force the actual P2 maven 2018-12-17 13:44:03 +00:00
dordsor21 5d0d461baf Remove mavenLocal from bukkit build.gradle 2018-12-17 13:33:06 +00:00
dordsor21 2d77214aa9 Add local repo even further up 2018-12-17 12:41:40 +00:00
dordsor21 dbf28a41d4 Never specified the local repository should be used. 2018-12-17 11:52:59 +00:00
dordsor21 783fda82bf Should fix build 2018-12-17 11:47:06 +00:00
NotMyFault 846495ee66
Minors 2018-12-12 16:29:34 +01:00
GreenChennai bcab75fe53
Update message.yml 2018-12-11 10:33:12 +08:00
NotMyFault c704f34e9b
Merge pull request #1218 from f0rb1d/master
Significantly improved the quality of Simplified Chinese translation.
2018-12-10 16:41:55 +01:00
NotMyFault 6bd4e990db
Fixed markdown 2018-12-10 16:23:22 +01:00
F0rb1d 40906b40f4 Significantly improved the quality of Simplified Chinese translation. 2018-12-10 21:25:08 +08:00
NotMyFault 1c17b1001d Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-11-21 14:28:21 +01:00
NotMyFault 8448b39414 Fixes #1201 2018-11-21 14:28:15 +01:00
IronApollo ba066847c4
Merge pull request #1189 from T3hBrian/master
Fix "null" and "#clipboard" argument failure for some brushes
2018-11-08 01:21:17 -05:00
TehBrian 0baddf7034
Fixed height brush 2018-11-07 23:16:19 -05:00
NotMyFault beb5cd61a4 Updating languages 2018-11-05 16:49:40 +01:00
NotMyFault 5e85cee058
Adding Italian translation 2018-11-04 20:41:41 +01:00
NotMyFault 626169ad1f
Merge pull request #1174 from evernife/master
Fix a bad world cast on forge 1.7.10
2018-10-25 12:07:51 +02:00
Petrus 0d10c1b690 Fix a bad world cast on forge 1.7.10 2018-10-25 06:04:12 -03:00
Jesse Boyd e26cdc6112
schem list validation 2018-10-17 23:57:13 +11:00
Jesse Boyd be9f606027
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-10-17 23:42:37 +11:00
Jesse Boyd 3c9b0fa3ea
Pull boy0001/WorldEdit#9 2018-10-17 23:42:30 +11:00
NotMyFault ae4083c9be Masking typo fixes 2018-10-16 22:27:08 +02:00
Jesse Boyd ac3005be36
Fixes #1152 2018-10-16 20:13:04 +11:00
Jesse Boyd 7962a15c47
Revert "try https"
This reverts commit e9c5d54ce5.
2018-10-16 02:19:34 +11:00
Jesse Boyd ce69326bb5
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-10-16 02:05:26 +11:00
Jesse Boyd e9c5d54ce5
try https 2018-10-16 02:05:21 +11:00
NotMyFault abe8b3f99a
Merge pull request #1158 from IronApollo/master
Added -f flag to bypass findFreePosition in jumpto
2018-10-15 11:36:46 +02:00
IronApollo 7f659a8b4f Added -f flag to bypass findFreePosition in jumpto 2018-10-15 05:11:48 -04:00
Jesse Boyd 2fef5e2e40
Merge pull request #1156 from GreenChennai/patch-1
Modify the error Chinese translation
2018-10-14 16:10:46 +11:00
GreenChennai 0cf2a92d4c
Modify the error Chinese translation
Some minor modifications
2018-10-14 08:49:09 +08:00
NotMyFault 9ce9885fb5 Added Chinese translation 2018-10-13 14:56:49 +02:00
NotMyFault bcd60813b6
Delete message.yml 2018-10-13 14:45:22 +02:00
NotMyFault 2713a68343
Merge pull request #1155 from GreenChennai/patch-1
Added Chinese message.yml
2018-10-13 14:36:58 +02:00
NotMyFault 26f4eaeb06
Update message.yml 2018-10-13 14:35:10 +02:00
GreenChennai c075b53784
Create message.yml 2018-10-13 20:29:22 +08:00
Jesse Boyd d2302d4088
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-10-13 15:21:30 +11:00
Jesse Boyd 47ce67c325
Various
freebuild region restrictions (bukkit)
+ tweak undo/redo messages
2018-10-13 15:20:21 +11:00
Jesse Boyd e447ef10a0
Merge pull request #1153 from Sprungente/patch-1
Little improve (Ger Translation)
2018-10-13 15:11:29 +11:00
Sprungente dfa66ea86b
Little improve
@N0tMyFaultOG pleas check the changes before you using it. Hope you like it :) 
Thanks for your update
2018-10-13 02:15:09 +02:00
NotMyFault 2bd8b6b6a0
Warn before updating
Fixes #1050
2018-10-10 13:57:26 +02:00
NotMyFault e1569b85e2
Merge pull request #1148 from N0tMyFaultOG/master
Typo fixes and missing prefixes added
2018-10-10 13:43:43 +02:00
NotMyFault 50bef3fb0c
Update BBC.java 2018-10-06 22:56:30 +02:00
NotMyFault 7d35200727
Update message.yml 2018-10-06 22:54:08 +02:00
NotMyFault 193519bbb8
Update message.yml 2018-10-06 22:53:54 +02:00
Jesse Boyd f3fdef6a46
Merge pull request #1146 from N0tMyFaultOG/master
Heightmapinterface permission
2018-10-05 15:09:54 +10:00
NotMyFault 05f8b758d8 heightmapinterface permission
Heightmapinterface permission added as you can download it on any server
2018-10-04 20:38:08 +02:00
Jesse Boyd 934897ff1c
Fix inventory mode 2 undo 2018-09-25 15:37:00 +10:00
Jesse Boyd 28ee68f0a6
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-09-23 17:29:45 +10:00
Jesse Boyd b8a0dea4bd
Fix inventory mode + nbt 2018-09-23 17:29:40 +10:00
Jesse Boyd b7f1ee30c6
Merge pull request #1131 from xSamagon/master
Fix of issue #1123
2018-09-16 11:57:45 +10:00
xSamagon 71dedf61d8 Fix of issue 1123
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)
2018-09-15 23:46:19 +02:00
Jesse Boyd 671c781a7c
re-add lazyCopy to EditSession 2018-09-15 02:42:57 +10:00
Jesse Boyd 9023723a0e
Fix oregen 2018-09-14 07:38:57 +10:00
Jesse Boyd 406bc9c017
Merge pull request #1109 from N0tMyFaultOG/patch-1
Added missing language values
2018-09-14 00:58:48 +10:00
Jesse Boyd f7decab132
Merge pull request #1110 from N0tMyFaultOG/master
Dutch and german message update
2018-09-14 00:58:28 +10:00
Jesse Boyd 936bd6fa91
Re-add isAlphaNumericUnd method to StringMan 2018-09-10 06:39:20 +10:00
Jesse Boyd 0640b19733
Fix command confirmation sessions 2018-09-08 09:09:51 +10:00
Jesse Boyd 8da1224e08
Fix undo 2018-09-08 08:23:01 +10:00
Jesse Boyd ca5ffe081b
Fix cliff brush NPE 2018-09-08 02:25:38 +10:00
Jesse Boyd d3ddd9ea6a
Fix compile 2018-09-08 02:07:47 +10:00
Jesse Boyd 9002a9a78f
Fix optional height NPE 2018-09-08 02:06:51 +10:00
Jesse Boyd 629f90cdaa
Fixes #1011 2018-09-08 01:34:45 +10:00
Jesse Boyd 9a67e7deb0
Fixes #1099 2018-09-08 01:30:50 +10:00
Jesse Boyd e57ac75a50
fix typo 2018-09-07 06:58:09 +10:00
Jesse Boyd 7108d62567
add min/max args 2018-09-07 06:45:03 +10:00
Jesse Boyd 0af4a02687
Add heightmapinterface cm 2018-09-07 06:41:16 +10:00
Jesse Boyd aa33250d42
Fix parser 2018-09-05 03:02:16 +10:00
Jesse Boyd db7110dac8
Fix schem load url 2018-09-05 02:03:19 +10:00
Jesse Boyd beb2e0e1b0
Various minor
JavaScript-API
Allow command replacing
Tweak primary thread checks
Tab completion
Schematic resolving
help tweaks
optimize change set
fix color brush
2018-09-04 05:40:06 +10:00
NotMyFault 3893aab67e
Update message.yml 2018-09-03 09:18:47 +02:00
Jesse Boyd 0021ab0d61
Allow local images for brusehs 2018-09-03 07:45:57 +10:00
NotMyFault 4095181346
Update message.yml 2018-09-02 23:21:00 +02:00
NotMyFault fc74879a84
Update message.yml 2018-09-02 22:52:38 +02:00
NotMyFault c4b24e501b
Update message.yml 2018-09-02 22:52:10 +02:00
NotMyFault 175bafdffb
Added missing language values 2018-09-02 21:52:19 +02:00
Jesse Boyd 57a977e148
Prompt for download link 2018-08-28 03:36:51 +10:00
Jesse Boyd 3e15d63448
Check towny ranks 2018-08-28 03:31:40 +10:00
Jesse Boyd 765be78aff
Add `fawe.towny.member` perm 2018-08-28 03:17:21 +10:00
Jesse Boyd 839a3151d5
Fix forge relog 2018-08-22 20:39:44 +10:00
Jesse Boyd 9e6b3fabe4
Use expression for brush radius 2018-08-22 03:10:20 +10:00
Jesse Boyd de52cfc656
Fix nukkit setbiome 2018-08-22 01:23:22 +10:00
Jesse Boyd 57f61f4f74
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-08-22 00:43:44 +10:00
Jesse Boyd 83e818d1c9
Potentially fix biome parsing 2018-08-22 00:43:30 +10:00
Jesse Boyd 0866842257
Update message.yml 2018-08-21 04:23:11 +10:00
Jesse Boyd fc1a8da8e2
Merge pull request #1062 from LeoDog896/patch-1
Update CONTRIBUTING.md
2018-08-21 04:17:26 +10:00
Jesse Boyd 16e7a90802
Update translations 2018-08-21 04:12:12 +10:00
Jesse Boyd f777211b90
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-08-21 04:02:52 +10:00
Jesse Boyd 46e36d90a4
Fixes #1083 2018-08-21 04:02:37 +10:00
Jesse Boyd 39ef1d7d62
Merge pull request #1081 from N0tMyFaultOG/patch-1
Dutch translation
2018-08-18 13:32:47 +10:00
NotMyFault ea8d93c64b
Dutch translation 2018-08-17 22:56:09 +02:00
Jesse Boyd a703bba082
Potential fix for anvil issues 2018-08-16 03:07:36 +10:00
Jesse Boyd c836e0ef68
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-08-13 16:09:50 +10:00
Jesse Boyd 213207ab7b
Add schemvis create method 2018-08-13 16:09:33 +10:00
Jesse Boyd d0a55ba4a4
Merge pull request #1074 from Byteflux/master
Remove custom event registration and improve 1.8+ detection
2018-08-13 05:16:51 +10:00
Byteflux 7e2b2e45b4 Remove custom event registration and improve 1.8+ detection 2018-08-12 12:07:09 -07:00
Jesse Boyd c1e13b14a7
Merge pull request #1044 from Erumeldor/patch-1
Update german message.yml
2018-08-13 04:52:39 +10:00
Jesse Boyd a3a28fe3de
Register each method + debug bad getMethods() 2018-08-13 04:28:14 +10:00
Jesse Boyd e75ff89429
Also remove the individual listeners 2018-08-13 04:21:43 +10:00
Jesse Boyd c472e85a27
Remove BlockExplodeEvent 2018-08-13 03:52:53 +10:00
Jesse Boyd 4394b45743
Register BlockExplodeEvent in another class 2018-08-13 03:47:21 +10:00
Jesse Boyd 1fabc98aff
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-08-13 00:34:01 +10:00
Jesse Boyd d0a2cabd5c
Register individual events for ChunkListener 2018-08-13 00:33:14 +10:00
Jesse Boyd 8dfde39cae
Update README.md 2018-08-12 23:27:16 +10:00
Jesse Boyd 1acc77a0c6
Update README.md 2018-08-12 23:26:22 +10:00
Jesse Boyd 1b55aa0b0c
Fixes #1070 2018-08-12 22:50:56 +10:00
Jesse Boyd 055a08b741
Propogate error 2018-08-12 21:18:46 +10:00
Jesse Boyd fa7fc22398
Record source 2018-08-11 15:06:02 +10:00
Jesse Boyd c683b414ba
Add PlayerSaveClipboardEvent 2018-08-11 15:03:43 +10:00
Jesse Boyd c12f685f0f
Add support for url:key in fullcopy 2018-08-09 23:58:26 +10:00
Jesse Boyd 60d07b5c2f
Use CommandException for `//gui` 2018-08-07 00:13:23 +10:00
Jesse Boyd e6128ecf63
Also strip for entities 2018-08-03 13:20:07 +10:00
Jesse Boyd 1c6097454f
Make tag mutable 2018-08-03 12:51:07 +10:00
Jesse Boyd 12265521c8
Allow rollbacks of all users 2018-08-03 11:55:44 +10:00
Jesse Boyd c1ef78b30f
use switch 2018-08-03 11:40:05 +10:00
Jesse Boyd 55a8978869
Add history restore command 2018-08-03 11:29:34 +10:00
Jesse Boyd f2412bca13
Add nbt stripping 2018-08-03 11:12:03 +10:00
LeoDog896 a78411dfdc
Update CONTRIBUTING.md 2018-07-27 20:44:42 -04:00
Jesse Boyd 3ed2e57f3a
Comment out unfinished code 2018-07-27 13:37:25 +10:00
Jesse Boyd 371e1bb27e
Ignore transitive dependencies for MapManager 2018-07-27 13:35:31 +10:00
Jesse Boyd 4d08c1229b
Fix setBiome with invalid biome 2018-07-27 13:26:32 +10:00
Jesse Boyd f5f13ddbe3
Add anvil command to delete all chunks matching a specified biome 2018-07-25 18:26:05 +10:00
Jesse Boyd a00345fd94
Tweak reset message 2018-07-21 22:53:37 +10:00
Jesse Boyd dc593a4667
Added argument for catenary direction 2018-07-21 22:42:15 +10:00
Jesse Boyd 074cf281c9
Check session exists before saving 2018-07-21 15:25:27 +10:00
Jesse Boyd 7501eabd2e
Potentiall fix NPE on server shutdown 2018-07-21 15:06:04 +10:00
Jesse Boyd efef7bcc00
Fixes ascend/descend bug 2018-07-21 12:47:46 +10:00
Jesse Boyd 7cbb117215
Check permission when using BrushTool 2018-07-15 15:57:43 +10:00
Jesse Boyd 9a8ec501b7
Dont override commands 2018-07-10 08:22:37 +10:00
Jesse Boyd c8eea3c976
* 2018-07-10 01:06:32 +10:00
Jesse Boyd bc9ccbd898
Fix brush commands 2018-07-10 00:51:52 +10:00
Jesse Boyd 6138a20105
Allow merging of dispatchers during command registration 2018-07-09 18:36:40 +10:00
Jesse Boyd 3ee4ab1e73
Add config option for mask type 2018-07-07 10:07:31 +10:00
Jesse Boyd 8796252c95
Add getter for WorldEdit 2018-07-07 07:14:30 +10:00
Jesse Boyd db3c83fdef
Wrap if command class is instance of processor 2018-07-07 07:12:54 +10:00
Jesse Boyd bcfc7275ad
Synchronize on chunk manager swap/move to avoid OOM 2018-07-05 19:34:24 +10:00
Erumeldor 7f26c57ed9
Update message.yml
The text said, that biomes have been changed in #num chunks. But it's blocks, not chunks
2018-06-26 12:58:24 +02:00
Jesse Boyd cc97c8d21e
Tweak task scheduling for less tps impact 2018-06-24 21:53:28 +10:00
Jesse Boyd 29794d4ccd
Fixes #795 2018-06-24 21:50:24 +10:00
Jesse Boyd c4d373549a
Fix WorldCopyClipboard 2018-06-19 07:34:22 +10:00
Jesse Boyd 9144d37c25
Fixes #1024 2018-06-10 15:54:59 +10:00
Jesse Boyd b8f37feef1
Fix TE CME on sponge 2018-06-09 06:14:53 +10:00
Jesse Boyd eaedd5442a
Fix horizontal firework detection 2018-06-08 04:36:27 +10:00
Jesse Boyd 3dbe0e9c30
Fix potential stack overflow 2018-06-07 03:49:14 +10:00
Jesse Boyd 4049014cb8
Allow multiple queued brush actions 2018-05-25 22:29:54 +10:00
Jesse Boyd 11dcafbcb8
Fix VS queuing 2018-05-25 22:28:39 +10:00
Jesse Boyd 099f733989
Fixes #1012 2018-05-24 15:24:41 +10:00
Jesse Boyd 58bf6f3172
* 2018-05-23 17:12:27 +10:00
Jesse Boyd 7eb83c000b
Fix command queuing from console 2018-05-23 16:34:38 +10:00
Jesse Boyd cf27decdb4
Fix P2 maxY 2018-05-23 16:32:08 +10:00
Jesse Boyd 01554bf1fb
fix image alpha scaling with summed color table 2018-05-23 16:19:38 +10:00
Jesse Boyd 6c05ec3b2a
Fix //schem save -g 2018-05-23 16:18:18 +10:00
Jesse Boyd 999e97a2de
* 2018-05-23 16:18:01 +10:00
Jesse Boyd ca1a62ac79
Add targetoffset scroll action 2018-05-23 16:17:37 +10:00
Jesse Boyd c6605ce587
Fixes #1010 2018-05-23 16:16:09 +10:00
Jesse Boyd d58a8549cb
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-05-23 16:15:41 +10:00
Jesse Boyd c93c4aee65
nbt ids 2018-05-23 16:15:27 +10:00
Jesse Boyd 435ffe934e
Merge pull request #1009 from N0tMyFaultOG/patch-1
Update german.yml
2018-05-21 08:28:40 +10:00
NotMyFault d219f5d02d
Update message.yml 2018-05-20 23:10:35 +02:00
NotMyFault 24f907395d
Update german.yml 2018-05-20 23:03:13 +02:00
Jesse Boyd b281370f3b
* 2018-05-17 19:17:28 +10:00
Jesse Boyd 3cae6e08c8
Delete files in the background 2018-05-17 19:00:03 +10:00
Jesse Boyd d66c14b06d
Fixes https://github.com/IntellectualSites/PlotSquared/issues/1945 2018-05-17 18:35:56 +10:00
Jesse Boyd d541115a3b
Use 0,255 for min/max build height 2018-05-16 12:07:30 +10:00
Jesse Boyd 5d076ef4b2
Fix issue with task queueing 2018-05-15 16:21:08 +10:00
Jesse Boyd fb744cdb21
Fix snipe event locking thread when used synchronously 2018-05-15 15:36:59 +10:00
Jesse Boyd 7aebc60983
remove debug 2018-05-15 15:24:43 +10:00
Jesse Boyd f95b659860
Fixes #1004 2018-05-15 11:11:00 +10:00
Jesse Boyd 9a54719d13
FIx MCAChunk move 2018-05-15 10:22:57 +10:00
Jesse Boyd fc599f2f86
Fix updater 2018-05-13 10:54:26 +10:00
Jesse Boyd 0bf6595ddd
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-05-13 10:50:56 +10:00
Jesse Boyd 3b5c1d1c8b
Don't give default limit if they have another 2018-05-13 10:50:42 +10:00
Jesse Boyd 63a40653cc Fixes #999 2018-05-12 16:54:20 +10:00
Jesse Boyd 2a7e111f46
Various minor
Fix NullExtent for heightmaps
auto dequeue the database and visualization tasks
2018-05-12 10:55:06 +10:00
Jesse Boyd fe17434d00
Add image brush 2018-05-11 17:59:32 +10:00
Jesse Boyd 8218e831ac
Add command `//gtexture` for texture control
Used in various patterns
2018-05-08 20:53:17 +10:00
Jesse Boyd 345b344000
Fix some region issues 2018-05-08 15:24:50 +10:00
Jesse Boyd ba5f37cd32
tweak update option comment 2018-05-08 15:21:13 +10:00
Jesse Boyd 0d9e79f4ae
Fixes #994 2018-05-06 16:32:50 +10:00
Jesse Boyd 0d1b46189b
CFI yscaling 2018-05-06 13:14:26 +10:00
Jesse Boyd 90713991a9
Fix //image arguments 2018-05-03 08:39:33 +10:00
Jesse Boyd 89bd2c0025
Suggest `//schem show all <args>` if no schems are found 2018-05-02 10:51:58 +10:00
Jesse Boyd e1df0ac8d1
Resolve paths where ../ fails 2018-05-02 10:34:15 +10:00
Jesse Boyd 63cb4784e7
debug file not found 2018-05-02 09:57:05 +10:00
Jesse Boyd 199eea5d9f
Fixes #860 2018-05-02 09:21:54 +10:00
Jesse Boyd 7a9ed0f512
Use file separator 2018-05-02 09:16:04 +10:00
Jesse Boyd af43e19018
Fixes #991 2018-05-02 09:07:01 +10:00
Jesse Boyd c71d872517
Ignore failed fallback listener registration 2018-05-02 09:06:21 +10:00
Jesse Boyd 6839d5531f
Prevent incompatibility with BetterShutdown 2018-05-02 09:03:00 +10:00
Jesse Boyd 03318369ae
Catch Exception (legacy sk89q command utils) 2018-05-02 02:15:03 +10:00
Jesse Boyd d32bcaac4b
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-04-30 06:20:51 +10:00
Jesse Boyd e244235350
Fixes #765 2018-04-30 06:20:41 +10:00
Jesse Boyd 1bebe14b67
Merge pull request #988 from Joeywp/master
Added a "Keep entities in non-air blocks" setting
2018-04-30 06:03:52 +10:00
Joey 19a9db3abf Added a "Keep entities in non-air blocks" setting 2018-04-29 17:40:48 +02:00
Jesse Boyd 7519f735bc
Add #extrema mask 2018-04-29 23:38:05 +10:00
Jesse Boyd 0f2125cc83
ADD #roc mask 2018-04-29 16:32:45 +10:00
Jesse Boyd 81a76dfd30
Don't consume optional arguments 2018-04-29 12:59:08 +10:00
Jesse Boyd 916bca59ba
* 2018-04-29 12:22:17 +10:00
Jesse Boyd 4d62867cb6
Optional distance for angle patterns/masks 2018-04-28 06:59:23 +10:00
Jesse Boyd 2ec9a92268
Updated updater 2018-04-28 06:38:53 +10:00
Jesse Boyd e8feaa9204
Fix angle mask
Fixes #923
Fixes #884
Fixes #804
2018-04-27 14:19:04 +10:00
Jesse Boyd eaa8fbfc9d
Fixes #985 2018-04-27 09:00:19 +10:00
Jesse Boyd 8e3e5b0d14
* 2018-04-26 05:24:41 +10:00
Jesse Boyd 29337e17d1
Fix extending region typo 2018-04-26 05:14:41 +10:00
Jesse Boyd 6cec36af99
CFI masking 2018-04-25 09:34:12 +10:00
Jesse Boyd 13b5ded4e9
Fix TextureUtil mushroom coloring 2018-04-22 07:35:34 +10:00
Jesse Boyd 668f6c6e34
Improved edit confirmation 2018-04-22 00:19:48 +10:00
Jesse Boyd 7065492740
Use temporary clipboard 2018-04-22 00:09:23 +10:00
Jesse Boyd cfe47d25d2
Fixes #910 2018-04-20 23:19:07 +10:00
Jesse Boyd 32cf8e47cc
Fixes #966 2018-04-20 23:16:02 +10:00
Jesse Boyd a89bdae93b
Fixes #977 2018-04-20 02:17:03 +10:00
Jesse Boyd 02f2572cf5
*clearclipboard 2018-04-20 00:32:44 +10:00
Jesse Boyd 40a569e14e
Fixes #976 2018-04-19 23:55:03 +10:00
Jesse Boyd 11ac395ff6
Update #surfacespread desc 2018-04-19 05:14:09 +10:00
Jesse Boyd b4bb0ddc15
* 2018-04-18 18:06:36 +10:00
Jesse Boyd 3182441e66
Fix chunk listener detection 2018-04-18 18:00:21 +10:00
Jesse Boyd 124cc02350
Fixes #975 2018-04-18 17:51:40 +10:00
Jesse Boyd bd346bc4c5
Fix schem file filters 2018-04-18 09:00:40 +10:00
Jesse Boyd 5298c5401f
Fixes #973 2018-04-17 17:28:07 +10:00
Jesse Boyd 72d85e0754
* 2018-04-17 06:39:58 +10:00
Jesse Boyd 5fdad79469
More schem show stuff 2018-04-17 06:39:40 +10:00
Jesse Boyd a7aef5bfd2
Fixes #972 2018-04-17 06:08:10 +10:00
Jesse Boyd 7997c60db4
* 2018-04-16 15:41:42 +10:00
Jesse Boyd 8830f9269c
Add PasteEvent 2018-04-16 15:40:48 +10:00
Jesse Boyd d1231fb56d
Fix setExtent 2018-04-16 01:59:10 +10:00
Jesse Boyd 049aff4d74
check file format 2018-04-14 02:52:41 +10:00
Jesse Boyd 5bdc2d6519
Fixes #970 2018-04-14 02:23:31 +10:00
Jesse Boyd 39216dee42
Display usage 2018-04-13 19:59:08 +10:00
Jesse Boyd 6c67192fe2
VirtualWorld cache/optimizations 2018-04-13 19:49:03 +10:00
Jesse Boyd d8d273a163
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-04-13 18:41:32 +10:00
Jesse Boyd 6968e66ad8
Various major
Implement virtual worlds
New schematic commands:
//schem show <directory>
//schem delete * - Deletes the files associated with your currently
loaded schematic
//schem move <directory> - Moves your currently loaded schematics to
this directory
//download -> supports downloading multiple schematics at once
2018-04-13 18:40:42 +10:00
Jesse Boyd c938a61896
Merge pull request #957 from roro1506/patch-1
Update BBC.java
2018-04-12 21:33:20 +10:00
Jesse Boyd b1f8bbddfa
* 2018-04-12 20:00:41 +10:00
Jesse Boyd 7968cdc232
support downloading multiple clipboards at once 2018-04-12 20:00:04 +10:00
Jesse Boyd 79fe27ab3e
Fix nether packet updates 2018-04-12 18:57:02 +10:00
Jesse Boyd 48992d2a4a
Fixes #943 2018-03-26 20:35:56 +11:00
roro1506 1f185e52b9
Update message.yml 2018-03-21 13:37:53 +01:00
roro1506 fa7a5f1423
Update message.yml 2018-03-21 13:36:28 +01:00
roro1506 5bb585db37
Update message.yml 2018-03-21 13:36:14 +01:00
roro1506 12ac22a9f7
Update message.yml 2018-03-21 13:35:50 +01:00
roro1506 51a541eee1
Update BBC.java
Updated a wrong TIP which had old pattern type.
2018-03-21 13:24:43 +01:00
Jesse Boyd 18c71453ce
Fix item drop issue on older spigot versions 2018-03-19 16:06:34 +11:00
Jesse Boyd ae3981cebf
Check VS snipe material against WE blacklist 2018-03-18 22:22:02 +11:00
Jesse Boyd 7c3ac8e362
Fix VS logging 2018-03-17 01:11:12 +11:00
Jesse Boyd aace4a37cb
debug fix skylight 2018-03-16 23:43:57 +11:00
Jesse Boyd 789c923106
debug fix air 2018-03-16 23:37:36 +11:00
Jesse Boyd 65939fa878
Fix cut 2018-03-16 17:20:27 +11:00
Jesse Boyd a5d70a65aa
Fixes #904 2018-03-16 17:17:07 +11:00
Jesse Boyd bc5241274c
Fix CFI smooth creating incorrect `//undo` 2018-03-15 18:44:36 +11:00
Jesse Boyd 485427c667
Fix CFI worldData 2018-03-15 17:07:36 +11:00
Jesse Boyd 83d6d0d1e0
Fix CFI visualization offset 2018-03-15 17:03:51 +11:00
Jesse Boyd c696b0260a
Fix anvil set counter 2018-03-15 16:51:52 +11:00
Jesse Boyd a2daa3a6a5
Check no-worldedit flag 2018-03-15 16:35:44 +11:00
Jesse Boyd fac3772eed
Fixes #947 2018-03-15 15:57:45 +11:00
Jesse Boyd 5cc4f6a37f
* 2018-03-15 15:02:49 +11:00
Jesse Boyd f991f4ad88
Use http 2018-03-15 03:14:30 +11:00
Jesse Boyd 353f93951c
Fixes #950 2018-03-15 03:13:41 +11:00
Jesse Boyd 8c29292bad
Fix `//move -a` with overlapping regions 2018-03-15 00:54:47 +11:00
Jesse Boyd e54df5a403
Add anvil set 2018-03-14 23:45:26 +11:00
Jesse Boyd 1967dd0769
tweak build 2018-03-14 21:49:07 +11:00
Jesse Boyd a07ad2c470
Use https 2018-03-14 16:07:24 +11:00
Jesse Boyd 3d8fdb021a
Spanish translations
Closes #948
2018-03-14 14:09:32 +11:00
Jesse Boyd 5045e3e6cd
Merge pull request #949 from MineMaximo/patch-3
message.yml
2018-03-14 14:04:11 +11:00
MineMaximo e6f417de55
message.yml
Translation of messages into Spanish
2018-03-10 11:05:45 -04:00
Jesse Boyd 25ef3a0c81
Recover from invalid bstats configuration 2018-03-10 23:59:31 +11:00
Jesse Boyd 4a9721edd3
Confirm for large `\\undo <times>` 2018-03-10 14:36:53 +11:00
Jesse Boyd a19e9a45e9
add clean task to individual projects 2018-03-10 01:59:19 +11:00
Jesse Boyd cf54fdc8c5
Add debug 2018-03-10 01:42:29 +11:00
Jesse Boyd 871074ec8e
Don't force trim to overwrite in-use sections.
- Just skip them
2018-03-10 01:28:10 +11:00
Jesse Boyd c9ca0791ea
url shortening + mcpe download form
Closes #284
2018-03-08 23:12:52 +11:00
Jesse Boyd 9cc588d5c9
loadbefore WorldGuard 2018-03-08 17:50:47 +11:00
Jesse Boyd ddcc297ec5
Fix #910 (tile remove) 2018-03-08 17:36:43 +11:00
Jesse Boyd 9128a17533
Fixes #936 2018-03-07 15:12:37 +11:00
Jesse Boyd 044fc0a44c
Debug #938 2018-03-07 15:07:50 +11:00
Jesse Boyd 3644ad9d70
Ignore CUI connections with more than 3 failed attempts. 2018-03-07 15:00:11 +11:00
Jesse Boyd b430f4748a
Fix FAVS compile 2018-03-01 15:49:42 +11:00
Jesse Boyd 7df831cc58
Temporarily use local nukkit dependency 2018-02-27 12:00:01 +11:00
Jesse Boyd dc8a18af9d
fix compilation 2018-02-27 11:19:57 +11:00
Jesse Boyd c4165a76a4
Fix distr above id:256 2018-02-27 11:15:43 +11:00
Jesse Boyd 80672f74e7
* 2018-02-27 02:05:47 +11:00
Jesse Boyd d450b8f0bc
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-02-27 01:58:29 +11:00
Jesse Boyd 77cf4ec34c
Support for non cuboid regions + add #liquid mask 2018-02-27 01:58:12 +11:00
Jesse Boyd 61f3dcaacc
Merge pull request #921 from SirYwell/master
fixed //overlay command
2018-02-27 00:24:45 +11:00
Jesse Boyd 09addf9073
Fixes #927 2018-02-26 11:48:09 +11:00
SirYwell ca7579e0a7 fixec //overlay command where the bottom layer was set to the given
block even if the block below is air
2018-02-17 03:56:07 +01:00
Jesse Boyd 7141cc4a9c
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-02-16 00:54:30 +11:00
Jesse Boyd dd29dd518d
* 2018-02-16 00:16:17 +11:00
Jesse Boyd 9c1fe2571b
Merge pull request #919 from SirYwell/master
Fixed translation
2018-02-14 21:01:29 +11:00
Jesse Boyd ce394bceae
Update vault depend 2018-02-14 20:45:20 +11:00
Jesse Boyd df12aa421e
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-02-12 00:58:11 +11:00
Jesse Boyd 4c2754d6df
Use name based UUID for the time being 2018-02-12 00:57:59 +11:00
Jesse Boyd 504f790b61
Merge pull request #917 from redbluescreen/master
Put wand to player's hotbar for Sponge
2018-02-11 22:02:50 +11:00
redbluescreen f38796656c
Put wand to player's hotbar 2018-02-11 12:54:46 +02:00
Jesse Boyd e1c3404b16
Update VS depend 2018-02-11 12:29:12 +11:00
Jesse Boyd e09c0c2224
* forgot MaskingExtent 2018-02-10 00:20:34 +11:00
Jesse Boyd 519a95b4b9
* 2018-02-10 00:13:13 +11:00
Jesse Boyd fa8d9d322e
Mask tweaks
Biome pattern can be properly masked now
Added `false` and `true` mask
2018-02-10 00:12:57 +11:00
Jesse Boyd fb8f76f833
Debug bad persistent brush values 2018-02-09 15:58:48 +11:00
Jesse Boyd 147c1c87fe
tweak sweep brush y coordinate 2018-02-09 12:58:37 +11:00
Jesse Boyd 598fcb8fcd
whoops 2018-02-08 20:11:26 +11:00
Jesse Boyd 9ef163af52
Strip color from plain console messages 2018-02-08 17:09:32 +11:00
Jesse Boyd 1b504e949c
Remove javax.xml.bind usage 2018-02-08 17:03:31 +11:00
Jesse Boyd b902a57c2c
Various minor
Closes #482
Optimized sqrt for small ranges
Close clipboard on finalize
2018-02-08 16:52:42 +11:00
Jesse Boyd 6f664c19bb
Fixes #912 2018-02-07 13:16:58 +11:00
Jesse Boyd 46634b1b26
Fix CylinderRegion minY/maxY excedding world 2018-02-06 18:02:01 +11:00
Hannes Greule bad4705f7a
fixed translation 2018-02-02 22:20:04 +01:00
Jesse Boyd ec5e45fdd2
Various minor
update to latest nukkit
Add tr lang file
Add support for legacy pattern as command argument
2018-02-02 14:18:26 +11:00
Jesse Boyd 371b4f5ee5
Fixes #905 2018-01-30 13:12:35 +11:00
Jesse Boyd 21e976ce4d
Fix forge 1.7.10 CME 2018-01-29 13:03:49 +11:00
Jesse Boyd 7136fb422e
Fixes #898 2018-01-25 14:58:47 +11:00
Jesse Boyd ad60b90987
Various minor
Functioning nukkit gui for most commands
Fixes #876
2018-01-24 19:57:08 +11:00
Jesse Boyd ea63c77d7e
Fix butcher/copy entities etc. 2018-01-23 17:07:46 +11:00
Jesse Boyd 724bf55f13
Fixes #892 2018-01-22 14:35:30 +11:00
Jesse Boyd 68bda0d775
*Fix warp for arrows as well 2018-01-21 21:29:09 +11:00
Jesse Boyd e1ab82d07b
Fix WarpBrush 2018-01-21 16:48:33 +11:00
Jesse Boyd ca906cc8c3
Fix thermos getWorldName 2018-01-20 20:41:23 +11:00
Jesse Boyd 5125a18540
Fix P2 hook not checking done flag 2018-01-20 00:24:29 +11:00
Jesse Boyd 6ee7f47129
Add duplicate patterns rather than replacing them 2018-01-19 14:36:01 +11:00
Jesse Boyd 17d3e574fb
Fix AsyncSign empty lines 2018-01-17 12:41:08 +11:00
Jesse Boyd 613f6bd5c0
Use local settings for FaweQueue 2018-01-17 12:19:37 +11:00
Jesse Boyd 1186a00b47
Fixes #885 2018-01-17 11:57:01 +11:00
Jesse Boyd bcbf307e8d
Don't unlight border chunks 2018-01-16 13:49:29 +11:00
Jesse Boyd 8d5e329eea
Fix remove lighting end 2018-01-16 13:33:43 +11:00
Jesse Boyd 083d4e7d08
Fix `//removelight` 2018-01-16 12:35:13 +11:00
Jesse Boyd ff42446f19
Fix lighting remove 2018-01-16 12:19:43 +11:00
Jesse Boyd 8cd6c1512b
Fix typo 2018-01-16 12:10:04 +11:00
Jesse Boyd 78e795d21a
reordering the dependency fixed it...? whatever 2018-01-16 12:05:09 +11:00
Jesse Boyd 134daefa24
Various unfinished
Start work on command GUI
Code cleanup
Add new lighting mode (see config)
Rename sponge -> sponge112
Fix sponge compile issues
Fix fuzzy region min/max not being set on first use
Fix clipboard on disk not closing on java 9
Start work on CFI chunk simplifier (for loading existing worlds)
Minor tile fixes for bukkit 1.12
2018-01-16 11:30:55 +11:00
Jesse Boyd d78d533acd
Check more frames 2018-01-16 10:38:17 +11:00
Jesse Boyd e2e31b364d
Nukkit permpack 2018-01-16 00:19:18 +11:00
Jesse Boyd bcb9320a45
Discard unused EditSession when using /u 2018-01-15 23:21:11 +11:00
Jesse Boyd 2448b2fe22
* 2018-01-15 17:32:20 +11:00
Jesse Boyd 446dc9c568
Use supplier instead of RunnableVal for sync 2018-01-15 15:39:55 +11:00
Jesse Boyd 0a246fc90f
Add ASkyBlock support 2018-01-12 16:13:54 +11:00
Jesse Boyd 0a127dfb40
Default tick-limiter to false if whitelisted
#847
2018-01-11 20:37:29 +11:00
Jesse Boyd 5be72dd5d7
Quicker tick-limiter detection and lower timings 2018-01-11 20:16:10 +11:00
Jesse Boyd 780a1ec16f
* 2018-01-11 19:55:54 +11:00
Jesse Boyd 4b7c1e987b
Fixes #870 Fixes #872 2018-01-11 18:08:15 +11:00
Jesse Boyd 9366acd6dc
Fixes #870 2018-01-11 14:26:33 +11:00
Jesse Boyd 274bc6d9a7
Nukkit regen/clear fixes
Closes #869
Fixes #868
2018-01-10 20:42:24 +11:00
Jesse Boyd b36c3dfc90
* 2018-01-10 19:53:02 +11:00
Jesse Boyd a1ccdf0543
Use combined color for texturing 2018-01-10 19:40:44 +11:00
Jesse Boyd 0a776078ea
Fixes #852 2018-01-10 16:22:04 +11:00
Jesse Boyd 4609b472fe
Various minor
Fix transforms and mask help pages
Closes #852
Add world and floor thickness to CFI
Fix snow layers not affecting leaves
2018-01-10 14:51:58 +11:00
Jesse Boyd e6ea640d21
Fixes #855 2018-01-10 11:26:11 +11:00
Jesse Boyd bb7b1cb736
Fixes #863 2018-01-07 23:47:47 +11:00
Jesse Boyd e1e31beff0
Fixes #847 2018-01-07 21:25:49 +11:00
Jesse Boyd 189e8189fb
Merge branch 'master' of https://github.com/boy0001/FastAsyncWorldedit 2018-01-07 17:14:46 +11:00
Jesse Boyd 9126c083ab
Fixes #862 2018-01-07 17:11:40 +11:00
362 changed files with 20025 additions and 5994 deletions

2
.github/CONTRIBUTING.md vendored Normal file
View 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
View 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
View 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
View File

@ -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/

View File

@ -1,2 +0,0 @@
### Bugs
Please provide a console log and your fawe configuration.

View File

@ -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

View File

@ -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)

View File

@ -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
}
}
}

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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) {
/*

View File

@ -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) {

View File

@ -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();
}
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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;
}
}

View File

@ -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();
}
};
}
};
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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"));

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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) {
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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);
}
}
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
}
});
}

View File

@ -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)));
}
}
}

View File

@ -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();
}

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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) {

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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>",

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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}.
*

View File

@ -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;
}
}

View File

@ -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"),;

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;
}
}
/**

View File

@ -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;
}

View File

@ -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;

View File

@ -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))

View File

@ -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];

View File

@ -22,6 +22,16 @@ public class NullRelighter implements Relighter {
}
@Override
public void clear() {
}
@Override
public void removeLighting() {
}
@Override
public void fixBlockLighting() {

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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);
}
});
}
}

View 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);
}
}

View File

@ -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
}
}

View File

@ -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();
}
}

View File

@ -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));
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
});
}
}

View File

@ -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();
}
});
}
}

View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -1,4 +0,0 @@
package com.boydti.fawe.jnbt.anvil.filters;
public class RegionFilter {
}

View File

@ -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();
}
}

View File

@ -23,6 +23,7 @@ public class TrimAirFilter extends MCAFilterCounter {
chunk.setModified();
}
}
cache.add(Character.MAX_VALUE);
chunk.setDeleted(true);
return null;
}

View File

@ -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);
}
}
}

View File

@ -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